コンテンツへスキップ

オラクルテスト

Phasisにおける実装上のあらゆる判断は、1つの問いを基準にします。V8は同じ出力を生成するか?

JavaScriptには、NaN !== NaN、-0 === 0、[1] + 1 === "11"、プロパティ列挙の厳密な順序、Promiseマイクロタスクの実行タイミングなど、微妙な意味論があります。仕様を読んでこれらを再導出するのは時間がかかり、間違いも起きやすくなります。Phasisは、Node.js(V8)をオラクルとして扱うことで、この手間を省きます。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

2段階のテスト

レベル1 — カスタムシナリオ

scenarios/の各シナリオは、出力が既知の小さなJSプログラムです。シナリオを1つ実行するには:

シェル
./bin/test-scenario operators/arithmetic

すべてのシナリオ、特定のカテゴリだけ、または並列で実行できます:

シェル
./bin/test-regression
./bin/test-regression --jobs 4
./bin/test-regression --category expressions

オラクルを更新するには(e.g。Node.jsのバージョン更新後):

シェル
./bin/oracle --refresh operators/arithmetic

シナリオはECMAScriptの章に沿って整理されています。リテラル、演算子、変数、制御フロー、関数、オブジェクト、配列、クラス、組み込み機能、エラー、相互運用、エッジケースです。

レベル2 — test262

TC39の公式適合性テストスイートは、test262/のgitサブモジュールとしてチェックアウトされます。各テストは自己検証型です。例外が発生しなければ合格し、発生すれば失敗します(negativeテストでは逆になります)。各テストの前に、ハーネスがassert.jsとsta.jsを読み込みます。

シェル
./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にあり、bin/compat-reportで再生成されます。CIではcompat-matrix.ymlワークフローがこれを複数のシャードに分けて実行し、結果をコミットします。このワークフローは手動で開始し、プッシュごとには実行しません。

プッシュ前のローカルチェック

./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もサンプル実行する必要があります。すべてのプルリクエストで、CIはPHPStan、PHPCS、ユニットスイート、オラクルのリグレッション検証を実行します。プルリクエストでsrc/またはそれらのフィクスチャが変更された場合は、WPTとpopular-packageスイートも実行されます。test262の全マトリクスはプルリクエストのCIに含まれないため、影響するカテゴリをローカルで選んで実行してください。

この方法が有効な理由

V8を正解の基準にすることで、開発中に仕様を読む必要がほぼなくなります。V8との不一致は必ずPhasisのバグを示し、仕様が曖昧だと主張できる余地はありません。修正が取り込まれると、対応するtest262テストが恒久的なリグレッションテストになります。

この手順が100 %の合格率を支えています。すべてのプルリクエストをV8と照合し、CIはオラクル、WPT、popular-packageの各スイートでリグレッションを拒否します。test262のマトリクスは、実行時に全テストスイートの結果を確認します。