
# Testovanie oracle

Každé rozhodnutie o implementácii v Phasis závisí od jednej otázky: **vytvára V8 rovnaký výstup?**

JavaScript má jemné sémantické nuansy — `NaN !== NaN`, `-0 === 0`, `[1] + 1 === "11"`, presné poradie výpočtu vlastností a načasovanie mikrotaskov `Promise`. Odvodzovať ich nanovo čítaním špecifikácie je pomalé a náchylné na chyby. Phasis to obchádza tak, že za oracle považuje Node.js (V8): napíšete scenár JS, spustíte ho cez V8 a zaznamenáte výstup ako referenčný; potom ho spustíte cez Phasis, znova zaznamenáte výstup a porovnáte ich.

```
1. SETUP    → a JavaScript source file or snippet
2. ORACLE   → Node.js executes it, output captured as truth
3. ACTUAL   → Phasis executes it, output captured
4. COMPARE  → oracle vs actual, diff measures the gap
```

## Dve úrovne testovania

### Úroveň 1 — vlastné scenáre

Každý scenár v `scenarios/` je malý program JS so známym výstupom. Spustenie jedného scenára:

```bash
./bin/test-scenario operators/arithmetic
```

Spustenie všetkých scenárov, iba jednej kategórie alebo paralelne:

```bash
./bin/test-regression
./bin/test-regression --jobs 4
./bin/test-regression --category expressions
```

Obnovenie oracle (e.g po aktualizácii verzie Node.js):

```bash
./bin/oracle --refresh operators/arithmetic
```

Scenáre sú usporiadané podľa kapitol ECMAScriptu: literály, operátory, premenné, riadenie toku, funkcie, objekty, polia, triedy, vstavané funkcie, chyby, interoperabilita a okrajové prípady.

### Úroveň 2 — test262

Oficiálna testovacia sada zhody TC39 je prevzatá ako podmodul git v `test262/`. Každý test sa overuje sám: prejde, ak nevyvolá výnimku, a zlyhá, ak ju vyvolá (pri testoch `negative` naopak). Pred každým testom načíta testovací rámec `assert.js` a `sta.js`.

```bash
./bin/test262                                    # full suite
./bin/test262 --category built-ins/Array         # subset
./bin/test262 --jobs 4                           # parallel
./bin/test262 --failures                         # one line per failing test
./bin/compat-report                              # full COMPAT.md + compat.json
```

Snímka celej testovacej sady sa nachádza v [`COMPAT.md`](https://github.com/inline0/phasis/blob/main/COMPAT.md) a obnovuje sa pomocou `bin/compat-report`. V CI ju workflow `compat-matrix.yml` spúšťa po častiach a ukladá výsledok; tento workflow sa spúšťa manuálne, nie pri každom odoslaní zmien.

## Lokálna kontrola pred odoslaním zmien

`./bin/verify-all` spúšťa kontrolu kvality, ktorú vyžaduje CI:

```
=== PHPStan ===                  level 6, zero errors
=== Code Standards ===           PHPCS, zero warnings
=== PHPUnit ===                  unit suite passes
=== Oracle Regression ===        scenarios under `scenarios/` pass
```

Samo osebe to **nestačí** — pri každej zmene parsera, interpreta alebo vstavaných funkcií treba otestovať aj test262. Pri každej požiadavke na zlúčenie CI spúšťa PHPStan, PHPCS, unit testy a regresné testy oracle; sady WPT a popular sa spúšťajú pri zmenách v `src/` alebo ich fixture. Úplná matica test262 nie je súčasťou CI pre požiadavky na zlúčenie, preto lokálne otestujte dotknuté kategórie.

## Prečo to funguje

Ak považujete V8 za zdroj pravdy, pri vývoji takmer vôbec nemusíte čítať špecifikáciu. Každá nezhoda s V8 znamená chybu Phasis — nikdy nejde o nejednoznačnosť špecifikácie, o ktorej by sa dalo polemizovať. Po zapracovaní opravy sa príslušné položky test262 stanú trvalými regresnými testami.

Miera úspešnosti 100 % je výsledkom tejto disciplíny: každá požiadavka na zlúčenie sa vyhodnocuje voči V8, CI odmieta regresie v testovacích sadách oracle, WPT a popular a matica test262 potvrdzuje výsledok celej sady, keď sa spustí.
