
# Testavimas pagal etalonus

Kiekvienas Phasis įgyvendinimo sprendimas priklauso nuo vieno klausimo: **ar V8 pateikia tą patį rezultatą?**

JavaScript semantika subtili — `NaN !== NaN`, `-0 === 0`, `[1] + 1 === "11"`, tiksli savybių išvardijimo tvarka, `Promise` mikro užduočių vykdymo laikas. Iš naujo išvesti tai skaitant specifikaciją lėta ir nepatikima. Phasis šią problemą apeina laikydama Node.js (V8) etalonu: parašykite JS scenarijų, paleiskite jį per V8 ir užfiksuokite rezultatą kaip teisingą; tada paleiskite per Phasis, vėl užfiksuokite rezultatą ir palyginkite.

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

## Du testavimo lygiai

### 1 lygis — individualūs scenarijai

Kiekvienas `scenarios/` scenarijus yra nedidelė JS programa su žinomu rezultatu. Paleiskite vieną scenarijų:

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

Paleiskite juos visus, vieną kategoriją arba lygiagrečiai:

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

Atnaujinkite etaloną (e.g. po Node.js versijos atnaujinimo):

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

Scenarijai suskirstyti pagal ECMAScript skyrius: literalai, operatoriai, kintamieji, valdymo srautas, funkcijos, objektai, masyvai, klasės, integruotos funkcijos, klaidos, sąveika ir kraštiniai atvejai.

### 2 lygis — test262

Oficialus TC39 atitikties testų rinkinys prijungtas kaip git submodulis kataloge `test262/`. Kiekvienas testas tikrina save: jis sėkmingas, jei nesukelia išimties, o jei sukelia — nepavyksta (arba atvirkščiai, jei tai `negative` testas). Prieš kiekvieną testą testų karkasas įkelia `assert.js` ir `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
```

Viso rinkinio momentinė kopija saugoma [`COMPAT.md`](https://github.com/inline0/phasis/blob/main/COMPAT.md), ją iš naujo sukuria `bin/compat-report`. CI aplinkoje `compat-matrix.yml` darbo eiga paleidžia testus dalimis ir išsaugo rezultatą; ši darbo eiga paleidžiama rankiniu būdu, o ne po kiekvieno pakeitimo.

## Vietinis patikrinimas prieš siunčiant pakeitimus

`./bin/verify-all` paleidžia CI taikomą kokybės patikrą:

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

Vien šio patikrinimo **nepakanka** — test262 taip pat reikia išbandyti su pavyzdžiais, jei keičiamas analizatorius, interpretatorius ar integruotos funkcijos. Kiekvienam pull request CI paleidžia PHPStan, PHPCS, vienetų testų rinkinį ir etalonų regresijos testą; WPT bei populiarių paketų rinkiniai paleidžiami, kai pull request pakeičia `src/` arba jų fikstūras. Visa test262 matrica į pull request CI neįtraukta, todėl lokaliai išbandykite paveiktas kategorijas.

## Kodėl tai veikia

Laikant V8 tiesos šaltiniu, kuriant programą beveik nebereikia skaityti specifikacijos. Nesutapimas su V8 visada reiškia Phasis klaidą — tai niekada nėra ginčytinas specifikacijos neaiškumas. Pritaikius pataisą, atitinkami test262 įrašai tampa nuolatiniais regresijos testais.

100 % sėkmingų testų dalis pasiekiama laikantis šios tvarkos: kiekvienas PR vertinamas pagal V8, CI atmeta regresijas etalonų, WPT ir populiarių paketų rinkiniuose, o test262 matrica patvirtina viso rinkinio rezultatą, kai ją paleidžiame.
