Imported from tomacox74/js2il (
.github/skills/test262-porting/SKILL.md). Install upstream withnpx skills add tomacox74/js2il --skill test262-porting. Copyright stays with the author.
Test262 Porting
Use this skill when you need to port one or more upstream test262 tests into tests\Jroc.Test262.Tests.
Goal
Keep the upstream test262 case as the source of truth by copying the JavaScript fixture exactly as-is whenever it is brought into this repo.
Catalog-First Candidate Selection
Before discovering candidates, consult the Test262 artifact catalog.
The SQLite database and generated lists are published by
.github/workflows/test262-catalog.yml as the test262-catalog Actions artifact.
See docs/ECMA262/Test262Catalog.md for the schema, provenance rules, and
workflow inputs. Keep downloads and generated lists under ignored
artifacts/test262/ or session storage, not in Git.
-
Look for an existing local catalog or a completed catalog workflow run. Select a trusted run from the intended branch that actually published the aggregate artifact; do not assume the latest run has one:
gh run list --workflow test262-catalog.yml --branch master --limit 10 # Replace RUN_ID with the selected run ID; use a fresh download directory. gh run download RUN_ID --name test262-catalog --dir artifacts/test262/catalog-downloadUse the feature branch instead of
masterwhen evaluating a catalog not yet published on the default branch. Do not overwrite a database being written by an active scan. -
Read
summary.jsonbefore using any list. Verify the upstream pin againsttests/test262/test262.pin.json, examine the fingerprint and runner identity, and report scan completeness.inventory_completedoes not mean execution is complete. A falsecomplete_passing_unported_listmeans the exported passes are only the known subset, not all passing unported tests. -
Refresh registration exclusions against the working tree:
python3 scripts/test262/catalog.py --db artifacts/test262/catalog-download/catalog.sqlite \ export --refresh-registrations --output artifacts/test262/catalog-downloadInspect
registration_warningsin the new summary. Resolve candidates against actual C# registrations and canonical/legacy fixture paths; never suppress a candidate by basename alone. -
Prefer
passing-unported.txt, thenhistorical-passing-unported.txtwhen selecting coverage-only ports. "Current" in a downloaded catalog refers to its recorded environment, not automatically this checkout or local build. Each accepted catalog pass must have every required variant passing under one provenance; missing variants, timeouts, metadata errors, and unsupported requirements are not passes.To establish local provenance or resume missing evidence, build the current compiler, initialize the database, and run only a bounded relevant area:
dotnet build src/Cli/Jroc.csproj -c Release python3 scripts/test262/catalog.py --db artifacts/test262/catalog-download/catalog.sqlite init --expand python3 scripts/test262/catalog.py --db artifacts/test262/catalog-download/catalog.sqlite \ scan --filter built-ins/Array/prototype/at --limit 100 --seconds 120 python3 scripts/test262/catalog.py --db artifacts/test262/catalog-download/catalog.sqlite \ export --refresh-registrations --output artifacts/test262/catalog-downloadChange the filter to the requested area.
--limitcounts variants, not fixtures. Initialization retains old evidence as historical when the fingerprint changes. Ordinary scans resume missing variants; use--retryonly for a deliberate recheck. If no artifact is available, use the defaultartifacts/test262/catalog.sqlitewithinit --expand, boundedscan, andexportrather than starting another whole-corpus local scan. -
Catalog evidence comes from the MVP composite-JavaScript runner, not the native C# harness. Historical or otherwise incompatible passes need fresh confirmation. Always run the focused native
Jroc.Test262.Testssuite after porting; catalog passes alone never count as published conformance. Do not rerun MVP preflight unnecessarily for candidates with compatible, complete evidence. Use targeted probes for missing evidence or diagnosis.
After an accepted port, refresh registrations and exports again so subsequent selection excludes it. Leave exhaustive discovery to the resumable catalog workflow; do not wait for a complete catalog before porting a known-good batch.
Porting Workflow
- Start from one concrete upstream
test262file and preserve its relative spec path and base filename. - Add the repo fixture under the matching folder in
tests\Jroc.Test262.Tests\...\JavaScript\, using the same filename so the port still clearly maps back to the original source. - Copy the upstream JavaScript fixture exactly as-is:
- do not rewrite
assert.sameValue(...),assert(...), or other upstream checks intoconsole.log(...), - preserve directive prologues such as
"use strict";, - keep any additional local fixture files when the case depends on sibling modules or scripts, and pass them through the C# test using the existing
additionalFilespattern, - preserve frontmatter such as
includes,flags, andnegative; the shared C# harness uses it to select helpers and validate expected failures, - do not add or inline JavaScript harness files. Extend the native C# harness when a required helper is missing.
- do not rewrite
- Add or update the folder's
ExecutionTests.csentry so:- the xUnit
DisplayNameis the originaltest262filename, - the C# method name is an identifier-safe version of that filename,
- the execution test points at the preserved JavaScript fixture path.
- the xUnit
- Successful test262 fixtures must produce no output. Assertions fail by throwing, so do not create an execution snapshot.
Native Harness Overview
All test262 harness support lives under tests/Jroc.Testing/Test262.
| File | Responsibility |
|---|---|
Test262SharedAssertHarness.cs |
Parses frontmatter, injects onlyStrict when needed, selects native helpers from includes, compiles and executes the fixture, checks runtime-negative exception types, and enforces no output. |
Test262HostRuntimeIntrinsics.cs |
Registers the core host globals and dispatches optional helper registration. |
Test262PropertyHelpers.cs |
Implements propertyHelper.js descriptor and attribute checks. |
Test262TypedArrayHelpers.cs |
Implements typed-array constructor lists, argument factories, and callback matrices. |
Test262AtomicsHelpers.cs |
Implements Atomics index and non-view value matrices. |
Test262EncodingHelpers.cs |
Implements hexadecimal encoding helpers. |
Test262PromiseHelpers.cs |
Implements promise sequence and settled-result checks. |
The harness does not read, concatenate, or compile helper JavaScript. The
tests/Jroc.Test262.Tests/Harness directory was removed.
Test262SharedAssertHarness reads the fixture's includes array and passes it
to Test262HostRuntimeIntrinsics.Create. Core globals are always available:
assert, backed by the productionJavaScriptRuntime.Node.AssertModule;Test262Error,$ERROR,$DONE, and$262;compareArray,isConstructor,getWellKnownIntrinsicObject,assertRelativeDateMs, andasyncTest;- property helpers, which remain unconditional because some older hand-ported fixtures use them without retaining upstream frontmatter.
Other helper groups are registered only when their upstream filename appears
in includes, for example testTypedArray.js, testAtomics.js,
decimalToHexString.js, promiseHelper.js, tcoHelper.js, or nans.js.
This keeps runtime setup small while preserving the upstream metadata contract.
Assertions do not print success markers. A normal test passes by completing
with empty output. assert failures throw AssertionError. Runtime-negative
tests that intentionally leave an exception unhandled are validated against
the frontmatter negative.type; tests that catch an expected exception with
assert.throws execute normally.
Adding a Missing Harness Helper
When a newly ported fixture names a helper that is not implemented:
- Read the pinned upstream helper and inventory every global it defines that the ported fixtures use. Preserve its observable JavaScript semantics, callback order, constructor matrix, coercions, and assertion behavior.
- Add a focused
Test262<Name>Helpers.csfile undertests/Jroc.Testing/Test262. Use aRegister(...)entry point when the helper exposes multiple globals. - Expose JavaScript-callable functions with
Test262HostRuntimeIntrinsics.CreateFunction, including the upstream functionnameandlength. UseObjectRuntime,TypeUtilities,Closure,JsNull, and public runtime objects so behavior follows JROC's JavaScript semantics rather than CLR shortcuts. - Add conditional registration in
Test262HostRuntimeIntrinsics.Createkeyed by the exact upstream include filename. Register unconditionally only when existing hand-ported fixtures demonstrably rely on the helper without frontmatter, and document that reason beside the registration. - For helper data such as constructor lists or value tables, return actual
JavaScript-visible arrays and objects. Preserve the distinction between CLR
null(JavaScriptundefined) andJsNull.Null(JavaScriptnull). - Extend
tests/Jroc.Test262.Tests/Integration/JavaScript/test262NativeHostHelpers.jswith the helper filename inincludesand assertions covering its native globals. Also run representative real fixtures that exercise its edge cases. - Do not recreate
tests/Jroc.Test262.Tests/Harness, prepend helper source to fixtures, or weaken copied assertions to make a port pass.
Typed-array constructors require particular care. Pass JavaScript-visible, constructible adapters rather than raw CLR delegates, and preserve the upstream constructor/argument-factory callback matrix so moving the helper to C# does not silently reduce test coverage.
Repo-Specific Rules
- Prefer execution coverage only. Do not automatically add a parallel
tests\Jroc.Tests\...regression unless we specifically need generator/IL assertions or other project-specific coverage beyond what thetest262port already proves. - Keep the original
test262layout recognizable. The path and filename are the main breadcrumb back to the upstream test. - Do not edit copied
tests\Jroc.Test262.Tests\...\JavaScript\*.jsfixtures to fit the local harness. Fix missing support in the native C# harness or product runtime. - PR #1011 is the reference example for this workflow: the arrow-function restricted
caller/argumentsscenario belongs undertests\Jroc.Test262.Tests\language\expressions\arrow-function\, and the paralleltests\Jroc.Tests\ArrowFunction\ArrowFunction_RestrictedCallerArgumentsPropertiesregression is redundant.
Validation
- Run the focused
Jroc.Test262.Testssuite for the affected area. - If the case fails, first classify whether it is:
- a porting problem (wrong file placement, missing additional file, malformed frontmatter, or missing native harness helper), or
- a real product bug.
- Keep the port, fix the correct layer, and avoid masking product defects with ad-hoc test rewrites.
- When changing shared native helpers, run the harness integration tests plus representative fixtures for every affected helper. Let PR CI run the full test262 and normal solution suites.
Documentation Follow-Through
Every accepted, passing test262 case changes JROC's published conformance
evidence. Update both customer-facing conformance documents in the same PR:
- Update
docs/ECMA262/Index.md:- refresh the Test262
Verified passingandNot yet verifiedcounts; - recalculate their percentages against the applicable pinned ECMA-262 corpus;
- keep the link to the detailed conformance report.
- refresh the Test262
- Update
docs/ECMA262/Test262Conformance.md:- refresh the overall totals;
- refresh every affected area and feature row;
- ensure each row's passing, known-unsupported, and no-published-result counts add up to its applicable total;
- recalculate each affected verified percentage.
- Keep these documents client-facing. Use conformance terms such as
Verified passing,Known unsupported, andNo published result; do not expose fixture-porting or repository-registration details. - Count unique standalone upstream tests at the pinned Test262 revision.
Do not count
_FIXTURE.jssupport files, strict/non-strict variants, test infrastructure, or duplicate local fixtures as additional conformance. - Keep the documented JROC version accurate. Do not attribute conformance added only on the development branch to an older released version.
When the cases also change the feature support story, update the relevant
docs/ECMA262/**/Section*.json entries, regenerate their Markdown, and update
CHANGELOG.md in the same PR.