
# Δοκιμές oracle

Κάθε απόφαση υλοποίησης στο Phasis εξαρτάται από ένα ερώτημα: **παράγει το V8 την ίδια έξοδο;**

Το JavaScript έχει λεπτές σημασιολογικές διαφορές — `NaN !== NaN`, `-0 === 0`, `[1] + 1 === "11"`, την ακριβή σειρά απαρίθμησης ιδιοτήτων και τον χρονισμό των microtask `Promise`. Η αναπαραγωγή αυτών διαβάζοντας την προδιαγραφή είναι αργή και επιρρεπής σε σφάλματα. Το Phasis το παρακάμπτει, αντιμετωπίζοντας το Node.js (V8) ως oracle: γράψτε ένα σενάριο JS, εκτελέστε το μέσω του V8 και καταγράψτε την έξοδο ως αληθή· εκτελέστε το μέσω του Phasis, καταγράψτε ξανά την έξοδο και συγκρίνετέ τες.

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

## Δύο επίπεδα δοκιμών

### Επίπεδο 1 — Προσαρμοσμένα σενάρια

Κάθε σενάριο στο `scenarios/` είναι ένα μικρό πρόγραμμα JS με γνωστή έξοδο. Εκτελέστε ένα σενάριο:

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

Εκτελέστε όλα τα σενάρια, μόνο μία κατηγορία ή παράλληλα:

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

Ανανεώστε το oracle (e.g. μετά από ενημέρωση έκδοσης του Node.js):

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

Τα σενάρια οργανώνονται ανά κεφάλαιο ECMAScript: κυριολεκτικές τιμές, τελεστές, μεταβλητές, ροή ελέγχου, συναρτήσεις, αντικείμενα, πίνακες, κλάσεις, ενσωματωμένα στοιχεία, σφάλματα, διαλειτουργικότητα και οριακές περιπτώσεις.

### Επίπεδο 2 — test262

Η επίσημη σουίτα συμμόρφωσης TC39 έχει ληφθεί ως υπομονάδα git στο `test262/`. Κάθε δοκιμή επαληθεύει μόνη της το αποτέλεσμα: περνά αν δεν προκληθεί εξαίρεση και αποτυγχάνει αν προκληθεί (ή το αντίστροφο για δοκιμές `negative`). Ο μηχανισμός δοκιμών φορτώνει τα `assert.js` και `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
```

Το πλήρες στιγμιότυπο της σουίτας βρίσκεται στο [`COMPAT.md`](https://github.com/inline0/phasis/blob/main/COMPAT.md) και αναδημιουργείται από το `bin/compat-report`. Στο CI, η ροή εργασίας `compat-matrix.yml` το εκτελεί σε τμήματα και υποβάλλει το αποτέλεσμα· η ροή εργασίας ξεκινά χειροκίνητα, όχι σε κάθε push.

## Τοπικός έλεγχος πριν από το push

Το `./bin/verify-all` εκτελεί την πύλη ποιότητας που επιβάλλει το CI:

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

Από μόνο του **δεν** αρκεί — πρέπει επίσης να δειγματοληπτείται το test262 για κάθε αλλαγή που αγγίζει τον parser, τον interpreter ή τα ενσωματωμένα στοιχεία. Σε κάθε pull request, το CI εκτελεί τα PHPStan, PHPCS, τη σουίτα μονάδων και την παλινδρόμηση oracle· οι σουίτες WPT και δημοφιλών πακέτων εκτελούνται όταν ένα pull request αλλάζει το `src/` ή τα fixtures τους. Η πλήρης μήτρα test262 δεν αποτελεί μέρος του CI των pull request, επομένως δοκιμάστε τοπικά τις κατηγορίες που επηρεάζονται.

## Γιατί λειτουργεί

Αν θεωρείτε το V8 ως την έγκυρη πηγή, σχεδόν όλη η ανάγνωση προδιαγραφών αφαιρείται από τον κύκλο ανάπτυξης. Η διαφωνία με το V8 υποδεικνύει πάντα σφάλμα Phasis — ποτέ ασάφεια στις προδιαγραφές που επιδέχεται συζήτηση. Μόλις ενσωματωθεί μια διόρθωση, οι αντίστοιχες εγγραφές test262 γίνονται μόνιμες δοκιμές παλινδρόμησης.

Το ποσοστό επιτυχίας 100% είναι αποτέλεσμα αυτής της πειθαρχίας: κάθε PR αξιολογείται με βάση το V8, το CI απορρίπτει παλινδρομήσεις στις σουίτες oracle, WPT και δημοφιλών πακέτων, ενώ η μήτρα test262 επιβεβαιώνει το αποτέλεσμα της πλήρους σουίτας όταν εκτελείται.
