
# Pengujian oracle

Setiap keputusan implementasi di Phasis bergantung pada satu pertanyaan: **apakah V8 menghasilkan keluaran yang sama?**

JavaScript memiliki semantik yang rumit — `NaN !== NaN`, `-0 === 0`, `[1] + 1 === "11"`, urutan enumerasi properti yang tepat, dan waktu eksekusi microtask `Promise`. Menurunkannya kembali dengan membaca spesifikasi lambat dan rawan kesalahan. Phasis mengatasi hal ini dengan memperlakukan Node.js (V8) sebagai oracle: tulis skenario JS, jalankan melalui V8, simpan keluarannya sebagai kebenaran; jalankan melalui Phasis, simpan keluarannya lagi; bandingkan.

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

## Dua tingkat pengujian

### Tingkat 1 — Skenario khusus

Setiap skenario di `scenarios/` adalah program JS kecil dengan keluaran yang diketahui. Jalankan satu skenario:

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

Jalankan semuanya, hanya satu kategori, atau secara paralel:

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

Perbarui oracle (e.g, misalnya setelah pembaruan versi Node.js):

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

Skenario diatur berdasarkan bab ECMAScript: literal, operator, variabel, alur kontrol, fungsi, objek, array, kelas, built-in, error, interop, kasus tepi.

### Tingkat 2 — test262

Rangkaian pengujian kesesuaian resmi TC39 di-checkout sebagai submodul git di bawah `test262/`. Setiap pengujian memverifikasi dirinya sendiri: berhasil jika tidak melempar error, gagal jika sebaliknya (atau kebalikannya untuk pengujian `negative`). Harness memuat `assert.js` dan `sta.js` sebelum setiap pengujian.

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

Snapshot rangkaian lengkap berada di [`COMPAT.md`](https://github.com/inline0/phasis/blob/main/COMPAT.md), dibuat ulang oleh `bin/compat-report`. Di CI, workflow `compat-matrix.yml` menjalankannya dalam beberapa shard dan melakukan commit atas hasilnya; workflow itu dijalankan secara manual, bukan pada setiap push.

## Pemeriksaan lokal sebelum push

`./bin/verify-all` menjalankan gerbang kualitas yang diterapkan CI:

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

Itu saja **tidak** cukup — test262 juga harus dijalankan pada sampel untuk setiap perubahan yang menyentuh parser, interpreter, atau built-in. Pada setiap pull request, CI menjalankan PHPStan, PHPCS, rangkaian unit, dan regresi oracle; rangkaian WPT dan paket populer dijalankan jika pull request mengubah `src/` atau fixture-nya. Matriks test262 lengkap tidak termasuk dalam CI pull request, jadi lakukan sampling kategori terdampak secara lokal.

## Mengapa cara ini berhasil

Memperlakukan V8 sebagai sumber kebenaran menghilangkan hampir semua kegiatan membaca spesifikasi dari siklus pengembangan. Ketidaksesuaian dengan V8 selalu menunjukkan bug Phasis — tidak pernah ambiguitas spesifikasi yang dapat diperdebatkan. Setelah perbaikan diterapkan, entri test262 yang sesuai menjadi pengujian regresi permanen.

Tingkat kelulusan 100 sebesar % merupakan hasil dari disiplin ini: setiap PR dinilai berdasarkan V8, CI menolak regresi pada rangkaian oracle, WPT, dan paket populer, serta matriks test262 mengonfirmasi hasil rangkaian lengkap saat dijalankan.
