This document describes how to run the Test262 ECMAScript conformance test suite against the tsrun interpreter.
The test262 suite is included as a git submodule. Initialize it with:
git submodule update --init --depth 1Or clone directly:
git clone --depth 1 https://github.com/tc39/test262 test262Build the test runner:
cargo build --release --bin test262-runner# Run all tests in a directory
./target/release/test262-runner language/types
# Run with verbose output (shows each test)
./target/release/test262-runner --verbose language/literals/numeric
# Stop on first failure (good for debugging)
./target/release/test262-runner --verbose --stop-on-fail language/statements
# List tests without running
./target/release/test262-runner --list language/expressions/addition
# Filter by pattern within directory
./target/release/test262-runner --filter "array" built-ins/Array| Option | Description |
|---|---|
--test262-dir <PATH> |
Path to test262 directory (default: ./test262) |
--filter <PATTERN> |
Filter tests by path pattern |
--features <LIST> |
Only run tests requiring these features (comma-separated) |
--skip-features <LIST> |
Skip tests requiring these features (comma-separated) |
--verbose / -v |
Show detailed output for each test |
--stop-on-fail |
Stop on first failure |
--list |
List matching tests without running |
--strict-only |
Only run strict mode variants |
--non-strict-only |
Only run non-strict mode variants |
Important: The tsrun interpreter runs all code in strict mode. This means:
- Tests marked
noStrictwill fail (they rely on sloppy mode behavior) - Tests marked
onlyStrictare the most relevant for this interpreter - The
--strict-onlyflag is recommended for accurate pass rates
For meaningful results, run with strict mode only:
./target/release/test262-runner --strict-only language/typesResults as of the current implementation (run with --strict-only flag):
| Category | Pass | Fail | Skip | Pass Rate |
|---|---|---|---|---|
language/function-code |
88 | 20 | 0 | 81.5% |
language/identifiers |
182 | 86 | 0 | 67.9% |
language/types |
68 | 36 | 0 | 65.4% |
language/literals/string |
32 | 29 | 0 | 52.5% |
language/literals/numeric |
80 | 75 | 0 | 51.6% |
language/arguments-object |
72 | 74 | 60 | 49.3% |
language/comments |
12 | 17 | 1 | 41.4% |
language/expressions |
2729 | 5351 | 2477 | 33.8% |
language/statements |
1991 | 4308 | 2539 | 31.6% |
language/block-scope |
34 | 111 | 0 | 23.4% |
| Category | Pass | Fail | Skip | Pass Rate |
|---|---|---|---|---|
built-ins/Math |
135 | 192 | 0 | 41.3% |
built-ins/Number |
110 | 224 | 1 | 32.9% |
built-ins/Object |
1093 | 2285 | 22 | 32.4% |
built-ins/RegExp |
340 | 799 | 739 | 29.9% |
built-ins/String |
348 | 858 | 3 | 28.9% |
built-ins/Set |
46 | 141 | 195 | 24.6% |
built-ins/Function |
101 | 319 | 1 | 24.0% |
built-ins/Map |
33 | 155 | 15 | 17.6% |
built-ins/Promise |
39 | 235 | 364 | 14.2% |
built-ins/Symbol |
10 | 82 | 0 | 10.9% |
The test runner automatically skips tests requiring features we don't support:
BigInt- Arbitrary precision integersWeakRef,WeakMap,WeakSet- Weak referencesFinalizationRegistry- Cleanup callbacksAtomics,SharedArrayBuffer- Shared memoryTypedArray,ArrayBuffer,DataView- Binary dataTemporal- Date/time proposalShadowRealm- Isolated realmsdecorators- Class decorators proposal
eval- Dynamic code executionwithstatement - Deprecated featuretail-call-optimization- Requires special runtime supportIntl- Internationalization API
import-assertions,import-attributes- Import attributesjson-modules- JSON importsregexp-lookbehind- RegExp lookbehind assertionsregexp-named-groups- RegExp named capture groupsregexp-unicode-property-escapes- Unicode property escapestop-level-await- Module-level await
Many tests use eval() to test whitespace/unicode handling:
// Test expects eval to be available
if (eval("1\u0009+\u00091") !== 2) { ... }Some numeric literal formats like .1 (leading dot) may not be fully supported:
// Test for leading dot notation
.1 === 0.1Tests for extended unicode identifier characters:
// Unicode escape in identifier
var \u0078 = 1;Some strict mode behaviors differ slightly from spec:
// Strict mode this binding
"use strict";
function f() { return this; } // Should return undefinedObject property descriptor behaviors (enumerable, configurable, writable):
Object.defineProperty(obj, 'x', { value: 1, writable: false });To skip additional features:
./target/release/test262-runner --skip-features "Promise,async-functions" language/To run only tests requiring specific features:
./target/release/test262-runner --features "arrow-function" language/expressions/arrow-functionTest262 tests use YAML frontmatter for metadata:
/*---
description: Test description
features: [arrow-function, const]
flags: [onlyStrict]
negative:
phase: parse
type: SyntaxError
includes: [propertyHelper.js]
---*/
// Test code here| Flag | Description |
|---|---|
onlyStrict |
Run only in strict mode |
noStrict |
Run only in non-strict mode |
module |
Interpret as ES module |
raw |
Don't add harness files |
async |
Async test (requires print() callback) |
Tests expected to throw errors specify:
phase:parse,resolution, orruntimetype: Expected error constructor name
To investigate a specific failure:
# Run single test with verbose output
./target/release/test262-runner --verbose --stop-on-fail \
test262/test/language/expressions/addition/S11.6.1_A1.js
# View the test file
cat test262/test/language/expressions/addition/S11.6.1_A1.jsThe test runner automatically loads these harness files before each test:
harness/sta.js- Test262Error class and $DONOTEVALUATEharness/assert.js- Assertion functions (assert, assert.sameValue, etc.)
Additional harness files are loaded based on the includes metadata.
Release build is recommended for running large test suites:
# Debug build: ~1.19s for 485 tests
./target/debug/test262-runner language/expressions/assignment
# Release build: ~0.28s for 485 tests
./target/release/test262-runner language/expressions/assignmentWhen adding new features:
- Run relevant test262 tests to check compliance
- Document any intentional deviations from spec
- Update this file with new pass rates