
# Vertailutestaus

Kaikki kohteen Phasis toteutuspäätökset ratkaistaan yhden kysymyksen perusteella: **tuottaako V8 saman tuloksen?**

JavaScript-kielellä on hienovaraisia semantiikkoja — `NaN !== NaN`, `-0 === 0`, `[1] + 1 === "11"`, ominaisuuksien luetteloinnin tarkka järjestys ja `Promise`-mikrotehtävien suoritusajankohta. Niiden johtaminen uudelleen määritystä lukemalla on hidasta ja altista virheille. Phasis ohittaa tämän käsittelemällä kohdetta Node.js (V8) vertailukohtana: kirjoita JS-skenaario, suorita se kohteessa V8 ja tallenna tulos oikeana; suorita se kohteessa Phasis, tallenna tulos uudelleen ja vertaa tuloksia.

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

## Kaksi testaustasoa

### Taso 1 — mukautetut skenaariot

Jokainen kohteen `scenarios/` skenaario on pieni JS-ohjelma, jonka tulos tunnetaan. Suorita yksi skenaario:

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

Suorita kaikki skenaariot, yksi luokka tai useita rinnakkain:

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

Päivitä vertailukohta (e.g esimerkiksi kohteen Node.js version päivityksen jälkeen):

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

Skenaariot on järjestetty ECMAScript-lukujen mukaan: literaalit, operaattorit, muuttujat, ohjausvirta, funktiot, objektit, taulukot, luokat, sisäänrakennetut toiminnot, virheet, yhteentoimivuus ja reunatapaukset.

### Taso 2 — test262

Virallinen TC39-vaatimustenmukaisuustestisarja on lisätty git-alimoduulina kohteeseen `test262/`. Jokainen testi tarkistaa itse itsensä: se menee läpi, jos poikkeusta ei synny, ja epäonnistuu, jos poikkeus syntyy (tai päinvastoin kohteen `negative` testien kohdalla). Testiajoympäristö lataa kohteet `assert.js` ja `sta.js` ennen jokaista testiä.

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

Koko testisarjan vedos on kohteessa [`COMPAT.md`](https://github.com/inline0/phasis/blob/main/COMPAT.md), ja se luodaan uudelleen kohteella `bin/compat-report`. CI:n `compat-matrix.yml`-työnkulku suorittaa testit rinnakkain lohkoissa ja tallentaa tuloksen. Työnkulku käynnistetään käsin, ei jokaisella työntökerralla.

## Paikallinen tarkistus ennen työntämistä

`./bin/verify-all` suorittaa CI:n edellyttämän laatutarkistuksen:

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

Tämä ei **yksin** riitä — test262-testejä on ajettava otoksena kaikille muutoksille, jotka koskevat jäsennintä, tulkkia tai sisäänrakennettuja toimintoja. Jokaisen pull-pyynnön yhteydessä CI suorittaa kohteet PHPStan ja PHPCS, yksikkötestisarjan sekä vertailuregression. WPT- ja suosittujen pakettien testisarjat suoritetaan, kun pull-pyynnössä muutetaan kohdetta `src/` tai niiden testitiedostoja. Koko test262-matriisi ei kuulu pull-pyyntöjen CI:hin, joten aja paikallisesti muutokseen liittyvät testiluokat.

## Miksi tämä toimii

Kun kohdetta V8 käsitellään totuudenlähteenä, määrityksen lukeminen jää lähes kokonaan pois kehityssyklistä. Ero kohteeseen V8 verrattuna osoittaa aina Phasis-virheen — ei koskaan määrityksen monitulkintaisuutta, josta voisi väitellä. Kun korjaus on lisätty, vastaavista test262-testeistä tulee pysyviä regressiotestejä.

100 %:n läpäisyaste perustuu tähän käytäntöön: jokainen PR arvioidaan V8:n mukaan, CI hylkää regressiot oracle-, WPT- ja suosittujen pakettien testisarjoissa, ja test262-matriisi vahvistaa koko testisarjan tuloksen, kun se suoritetaan.
