
# Oracle-testning

Varje implementeringsbeslut i Phasis avgörs av en fråga: **ger V8 samma resultat?**

JavaScript har subtil semantik — `NaN !== NaN`, `-0 === 0`, `[1] + 1 === "11"`, den exakta ordningen för uppräkning av egenskaper och tidpunkten för `Promise`-mikrotasks. Att härleda detta på nytt genom att läsa specifikationen är långsamt och felbenäget. Phasis undviker det genom att behandla Node.js (V8) som ett oracle: skriv ett JS-scenario, kör det genom V8 och spara resultatet som facit; kör det genom Phasis, spara resultatet igen och jämför.

```
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
```

## Två testnivåer

### Nivå 1 — Anpassade scenarier

Varje scenario i `scenarios/` är ett litet JS-program med känt resultat. Kör ett enskilt scenario:

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

Kör alla, en enda kategori eller parallellt:

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

Uppdatera oracle (e.g. efter en versionsuppdatering av Node.js):

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

Scenarierna är organiserade efter ECMAScript-kapitel: literaler, operatorer, variabler, kontrollflöde, funktioner, objekt, arrayer, klasser, inbyggda funktioner, fel, interoperabilitet och specialfall.

### Nivå 2 — test262

Den officiella TC39-konformitetssviten är utcheckad som en git-submodul under `test262/`. Varje test verifierar sig självt: det godkänns om det inte kastar ett undantag och misslyckas om det gör det (eller tvärtom för `negative`-tester). Testriggen laddar `assert.js` och `sta.js` före varje test.

```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
```

Ögonblicksbilden av hela sviten finns i [`COMPAT.md`](https://github.com/inline0/phasis/blob/main/COMPAT.md) och återskapas av `bin/compat-report`. I CI kör `compat-matrix.yml`-arbetsflödet den i delar och checkar in resultatet. Arbetsflödet startas manuellt, inte vid varje push.

## Lokal kontroll före push

`./bin/verify-all` kör kvalitetskontrollen som CI tillämpar:

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

Det räcker **inte** på egen hand — test262 måste också testas för alla ändringar som berör parsern, tolken eller inbyggda funktioner. Vid varje pull request kör CI PHPStan, PHPCS, unit-sviten och oracle-regressionstestet. WPT- och popular-paketsviterna körs när en pull request ändrar `src/` eller deras fixtures. Den fullständiga test262-matrisen ingår inte i CI för pull requests, så testa berörda kategorier lokalt.

## Varför det här fungerar

När V8 behandlas som facit behöver utvecklingsflödet nästan inte alls läsa specifikationen. Om resultatet skiljer sig från V8 finns alltid ett Phasis-fel — det är aldrig en tvetydighet i specifikationen att diskutera. När en korrigering har landat blir motsvarande test262-poster permanenta regressionstester.

100 % godkända tester är resultatet av den här disciplinen: varje PR bedöms mot V8, CI avvisar regressioner i oracle-, WPT- och popular-paketsviterna, och test262-matrisen bekräftar resultatet för hela sviten när den körs.
