test262の適合状況
test262はTC39が管理する公式適合性テストスイートで、JavaScriptエンジンを比較する標準的な方法です。
Phasisは、言語の意味論、標準ライブラリ、Intl、annexB、レガシーWeb機能、stagingの実験的テストディレクトリ、ハーネスのセルフテストなど、すべてのカテゴリでスイート全体に100 %合格します。機能フラグによる回避も、ホスト環境の不足を理由とする除外リストも、シャードごとの除外もありません。
このスイートは固定されています。test262のgitサブモジュールが、Phasisの測定対象リビジョンを固定し、新しい上流テストはサブモジュールを更新した後にのみ対象となります。COMPAT.mdにあるスイート全体のスナップショットはcompat-matrix.ymlワークフローで再生成されます。この処理はプッシュごとではなく手動で開始し、COMPAT.mdにスナップショットの取得時期と対象コミットが記録されます。
比較として、test262.fyiでは、同じスイートを各種の実運用JSエンジンで実行しています:
| エンジン | 適合率 |
|---|---|
| V8 (Chrome / Node) | 99.8 % |
| SpiderMonkey (Firefox) | 99.6 % |
| JavaScriptCore (Safari) | 99.4 % |
| QuickJS | ~97 % |
| Hermes (React Native) | ~95 % |
| Phasis | 100 % |
これらのエンジンにはそれぞれ、新たに取り込まれた提案や実装中のまれなエッジケースなど、小さな未対応部分が残っています。Phasisは適合性を第一に据えた単一目的の実装であるため、その差を埋めています。
ローカルで実行する
ランナーにはtest262サブモジュールとリポジトリのテストクラスが必要です。どちらもComposerパッケージには含まれないため、クローンから実行してください:
git clone https://github.com/inline0/phasis
cd phasis
git submodule update --init test262
composer install
./bin/test262 --jobs 4
最近のMacでは全テストの実行に約20分かかります。CIではマトリックスの各シャードが並列に動作し、数分で完了します。
デバッグ時に特定のカテゴリだけを実行するには:
./bin/test262 --category built-ins/Array
./bin/test262 --category language/expressions/yield --failures
すべてのフラグについてはCLIリファレンスを参照してください。
重要な理由
JavaScriptには細かな意味論があります。NaN !== NaN、-0 === 0、[1] + 1 === "11"、プロパティ列挙の厳密な順序、Promiseマイクロタスクの実行タイミングなどです。JSのユーザーコードを実行するライブラリは、そのすべてを常に正しく扱う必要があります。test262は「正しさ」の基準です。100 %合格するということは、V8で動作するJSプログラムがPhasisでも(ブラウザー専用APIを除き)バイト単位で同じ出力を生成することを意味します。