mirror of
https://github.com/bendtherules/completion-viz.git
synced 2026-08-18 21:52:36 +00:00
Clone engine262 in /engine262
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
# https://github.com/tc39/test262/blob/master/features.txt
|
||||
|
||||
# Start with `-` to skip feature
|
||||
# Map feature to engine262 feature using `feature = engine262featurename`
|
||||
|
||||
-Atomics
|
||||
-Atomics.waitAsync
|
||||
|
||||
-caller
|
||||
|
||||
-SharedArrayBuffer
|
||||
|
||||
-tail-call-optimization
|
||||
|
||||
-class-fields-public
|
||||
-class-fields-private
|
||||
-class-methods-private
|
||||
-class-static-fields-public
|
||||
-class-static-fields-private
|
||||
-class-static-methods-private
|
||||
|
||||
# https://github.com/tc39/proposal-top-level-await
|
||||
top-level-await = top-level-await
|
||||
|
||||
# https://github.com/tc39/proposal-hashbang
|
||||
hashbang = hashbang
|
||||
|
||||
# https://github.com/tc39/proposal-numeric-separator
|
||||
numeric-separator-literal = numeric-separators
|
||||
|
||||
# https://github.com/tc39/proposal-regexp-match-indices
|
||||
regexp-match-indices = regexp-match-indices
|
||||
|
||||
# https://github.com/tc39/proposal-cleanup-some
|
||||
cleanupSome = cleanup-some
|
||||
@@ -0,0 +1,59 @@
|
||||
#####################
|
||||
### Skipped Tests ###
|
||||
#####################
|
||||
|
||||
# Comments start with `#`.
|
||||
# Paths are relative to the `test262/test` directory.
|
||||
# Paths may contain globs.
|
||||
|
||||
# Spec bug
|
||||
built-ins/Date/prototype/setMonth/this-value-invalid-date.js
|
||||
|
||||
# Spec bug
|
||||
built-ins/Function/prototype/bind/instance-length-tointeger.js
|
||||
|
||||
# https://github.com/tc39/test262/issues/427
|
||||
language/expressions/prefix-increment/S11.4.4_A5_T4.js
|
||||
language/expressions/prefix-increment/S11.4.4_A5_T5.js
|
||||
language/expressions/postfix-increment/S11.3.1_A5_T4.js
|
||||
language/expressions/postfix-increment/S11.3.1_A5_T5.js
|
||||
language/expressions/prefix-decrement/S11.4.5_A5_T4.js
|
||||
language/expressions/prefix-decrement/S11.4.5_A5_T5.js
|
||||
language/expressions/postfix-decrement/S11.3.2_A5_T4.js
|
||||
language/expressions/postfix-decrement/S11.3.2_A5_T5.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.1_T4.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.4_T4.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.7_T4.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.10_T4.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.11_T4.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.2_T4.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.3_T4.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.5_T4.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.6_T4.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.9_T4.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.8_T4.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.1_T5.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.2_T5.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.3_T5.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.4_T5.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.5_T5.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.6_T5.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.7_T5.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.8_T5.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.9_T5.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.10_T5.js
|
||||
language/expressions/compound-assignment/S11.13.2_A5.11_T5.js
|
||||
language/expressions/assignment/S11.13.1_A5_T5.js
|
||||
language/expressions/assignment/S11.13.1_A5_T4.js
|
||||
|
||||
# https://github.com/tc39/ecma262/issues/1426
|
||||
built-ins/String/prototype/replace/S15.5.4.11_A3_T*.js
|
||||
|
||||
# We need our own date parser
|
||||
built-ins/Date/parse/without-utc-offset.js
|
||||
|
||||
# TODO: RegExp
|
||||
built-ins/RegExp/property-escapes/**/*.js
|
||||
built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier.js
|
||||
built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier.js
|
||||
built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier.js
|
||||
@@ -0,0 +1,26 @@
|
||||
##################
|
||||
### Slow Tests ###
|
||||
##################
|
||||
|
||||
# Comments start with `#`.
|
||||
# Paths are relative to the `test262/test` directory.
|
||||
# Paths may contain globs.
|
||||
|
||||
built-ins/RegExp/character-class-escape-non-whitespace.js
|
||||
built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js
|
||||
built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js
|
||||
built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-flags-u.js
|
||||
built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier-flags-u.js
|
||||
built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-flags-u.js
|
||||
built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier-flags-u.js
|
||||
language/literals/regexp/S7.8.5_A1.1_T2.js
|
||||
language/literals/regexp/S7.8.5_A1.4_T2.js
|
||||
language/literals/regexp/S7.8.5_A2.1_T2.js
|
||||
language/literals/regexp/S7.8.5_A2.4_T2.js
|
||||
|
||||
language/comments/S7.4_A5.js
|
||||
language/comments/S7.4_A6.js
|
||||
|
||||
built-ins/{encode,decode}URI?(Component)/**/*.js
|
||||
|
||||
built-ins/Function/prototype/toString/built-in-function-object.js
|
||||
@@ -0,0 +1,324 @@
|
||||
'use strict';
|
||||
|
||||
try {
|
||||
require('@snek/source-map-support/register');
|
||||
} catch {}
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const util = require('util');
|
||||
const glob = require('glob');
|
||||
|
||||
const readList = (name) => {
|
||||
const source = fs.readFileSync(path.resolve(__dirname, name), 'utf8');
|
||||
return source.split('\n').filter((l) => l && !l.startsWith('#'));
|
||||
};
|
||||
const readListPaths = (name) => readList(name)
|
||||
.flatMap((t) => glob.sync(path.resolve(__dirname, 'test262', 'test', t)))
|
||||
.map((f) => path.relative(path.resolve(__dirname, 'test262'), f));
|
||||
|
||||
const disabledFeatures = [];
|
||||
const featureMap = {};
|
||||
readList('features')
|
||||
.forEach((f) => {
|
||||
if (f.startsWith('-')) {
|
||||
disabledFeatures.push(f.slice(1));
|
||||
}
|
||||
if (f.includes('=')) {
|
||||
const [k, v] = f.split('=');
|
||||
featureMap[k.trim()] = v.trim();
|
||||
}
|
||||
});
|
||||
|
||||
if (!process.send) {
|
||||
// supervisor
|
||||
|
||||
const childProcess = require('child_process');
|
||||
const TestStream = require('test262-stream');
|
||||
|
||||
const {
|
||||
pass,
|
||||
fail,
|
||||
skip,
|
||||
total,
|
||||
CPU_COUNT,
|
||||
} = require('../base');
|
||||
|
||||
const override = process.argv.find((e, i) => i > 1 && !e.startsWith('-'));
|
||||
const NUM_WORKERS = process.env.NUM_WORKERS
|
||||
? Number.parseInt(process.env.NUM_WORKERS, 10)
|
||||
: Math.round(CPU_COUNT * 0.75);
|
||||
const RUN_SLOW_TESTS = process.argv.includes('--run-slow-tests');
|
||||
|
||||
const createWorker = () => {
|
||||
const c = childProcess.fork(__filename);
|
||||
c.on('message', (message) => {
|
||||
const { description, status, error } = message;
|
||||
switch (status) {
|
||||
case 'PASS':
|
||||
pass();
|
||||
break;
|
||||
case 'FAIL':
|
||||
fail(description, error);
|
||||
break;
|
||||
case 'SKIP':
|
||||
skip();
|
||||
break;
|
||||
default:
|
||||
throw new RangeError(JSON.stringify(message));
|
||||
}
|
||||
});
|
||||
c.on('exit', (code) => {
|
||||
if (code !== 0) {
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
return c;
|
||||
};
|
||||
|
||||
const workers = Array.from({ length: NUM_WORKERS }, () => createWorker());
|
||||
let longRunningWorker;
|
||||
if (RUN_SLOW_TESTS) {
|
||||
longRunningWorker = createWorker();
|
||||
}
|
||||
|
||||
const slowlist = readListPaths('slowlist');
|
||||
const skiplist = readListPaths('skiplist');
|
||||
|
||||
const stream = new TestStream(path.resolve(__dirname, 'test262'), {
|
||||
paths: [override || 'test'],
|
||||
omitRuntime: true,
|
||||
});
|
||||
|
||||
let workerIndex = 0;
|
||||
stream.on('data', (test) => {
|
||||
if (test.attrs.flags.module && test.scenario !== 'default') {
|
||||
// test262-stream duplicates module tests, deduplicate here
|
||||
return;
|
||||
}
|
||||
|
||||
if (/annexB|intl402/.test(test.file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
total();
|
||||
|
||||
if ((test.attrs.features && test.attrs.features.some((feature) => disabledFeatures.includes(feature)))
|
||||
|| skiplist.includes(test.file)) {
|
||||
skip();
|
||||
return;
|
||||
}
|
||||
|
||||
if (slowlist.includes(test.file)) {
|
||||
if (RUN_SLOW_TESTS) {
|
||||
longRunningWorker.send(test);
|
||||
} else {
|
||||
skip();
|
||||
}
|
||||
} else {
|
||||
workers[workerIndex].send(test);
|
||||
workerIndex += 1;
|
||||
if (workerIndex >= workers.length) {
|
||||
workerIndex = 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
stream.on('end', () => {
|
||||
workers.forEach((w) => {
|
||||
w.send('DONE');
|
||||
});
|
||||
if (RUN_SLOW_TESTS) {
|
||||
longRunningWorker.send('DONE');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// worker
|
||||
|
||||
const {
|
||||
Agent,
|
||||
setSurroundingAgent,
|
||||
inspect,
|
||||
|
||||
Value,
|
||||
|
||||
IsCallable,
|
||||
IsDataDescriptor,
|
||||
Type,
|
||||
|
||||
AbruptCompletion,
|
||||
Throw,
|
||||
} = require('../..');
|
||||
const { createRealm } = require('../../bin/test262_realm');
|
||||
|
||||
const isError = (type, value) => {
|
||||
if (Type(value) !== 'Object') {
|
||||
return false;
|
||||
}
|
||||
const proto = value.Prototype;
|
||||
if (!proto || Type(proto) !== 'Object') {
|
||||
return false;
|
||||
}
|
||||
const ctorDesc = proto.properties.get(new Value('constructor'));
|
||||
if (!ctorDesc || !IsDataDescriptor(ctorDesc)) {
|
||||
return false;
|
||||
}
|
||||
const ctor = ctorDesc.Value;
|
||||
if (Type(ctor) !== 'Object' || IsCallable(ctor) !== Value.true) {
|
||||
return false;
|
||||
}
|
||||
const namePropDesc = ctor.properties.get(new Value('name'));
|
||||
if (!namePropDesc || !IsDataDescriptor(namePropDesc)) {
|
||||
return false;
|
||||
}
|
||||
const nameProp = namePropDesc.Value;
|
||||
return Type(nameProp) === 'String' && nameProp.stringValue() === type;
|
||||
};
|
||||
|
||||
const includeCache = {};
|
||||
|
||||
const run = (test) => {
|
||||
const features = [];
|
||||
if (test.attrs.features) {
|
||||
test.attrs.features.forEach((f) => {
|
||||
if (featureMap[f]) {
|
||||
features.push(featureMap[f]);
|
||||
}
|
||||
});
|
||||
}
|
||||
const agent = new Agent({
|
||||
features,
|
||||
});
|
||||
setSurroundingAgent(agent);
|
||||
|
||||
const {
|
||||
realm, trackedPromises,
|
||||
resolverCache, setPrintHandle,
|
||||
} = createRealm({ file: test.file });
|
||||
const r = realm.scope(() => {
|
||||
test.attrs.includes.unshift('assert.js', 'sta.js');
|
||||
if (test.attrs.flags.async) {
|
||||
test.attrs.includes.unshift('doneprintHandle.js');
|
||||
}
|
||||
|
||||
for (const include of test.attrs.includes) {
|
||||
if (includeCache[include] === undefined) {
|
||||
const p = path.resolve(__dirname, `./test262/harness/${include}`);
|
||||
includeCache[include] = {
|
||||
source: fs.readFileSync(p, 'utf8'),
|
||||
specifier: p,
|
||||
};
|
||||
}
|
||||
const entry = includeCache[include];
|
||||
const completion = realm.evaluateScript(entry.source, { specifier: entry.specifier });
|
||||
if (completion instanceof AbruptCompletion) {
|
||||
return { status: 'FAIL', error: inspect(completion) };
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const completion = realm.evaluateScript(`\
|
||||
var Test262Error = class Test262Error extends Error {};
|
||||
|
||||
function $DONE(error) {
|
||||
if (error) {
|
||||
if (typeof error === 'object' && error !== null && 'stack' in error) {
|
||||
__consolePrintHandle__('Test262:AsyncTestFailure:' + error.stack);
|
||||
} else {
|
||||
__consolePrintHandle__('Test262:AsyncTestFailure:Test262Error: ' + error);
|
||||
}
|
||||
} else {
|
||||
__consolePrintHandle__('Test262:AsyncTestComplete');
|
||||
}
|
||||
}`);
|
||||
if (completion instanceof AbruptCompletion) {
|
||||
return { status: 'FAIL', error: inspect(completion) };
|
||||
}
|
||||
}
|
||||
|
||||
let asyncResult;
|
||||
if (test.attrs.flags.async) {
|
||||
setPrintHandle((m) => {
|
||||
if (m.stringValue && m.stringValue() === 'Test262:AsyncTestComplete') {
|
||||
asyncResult = { status: 'PASS' };
|
||||
} else {
|
||||
asyncResult = { status: 'FAIL', error: m.stringValue ? m.stringValue() : inspect(m) };
|
||||
}
|
||||
setPrintHandle(undefined);
|
||||
});
|
||||
}
|
||||
|
||||
const specifier = path.resolve(__dirname, 'test262', test.file);
|
||||
|
||||
let completion;
|
||||
if (test.attrs.flags.module) {
|
||||
completion = realm.createSourceTextModule(specifier, test.contents);
|
||||
if (!(completion instanceof AbruptCompletion)) {
|
||||
const module = completion;
|
||||
resolverCache.set(specifier, module);
|
||||
completion = module.Link();
|
||||
if (!(completion instanceof AbruptCompletion)) {
|
||||
completion = module.Evaluate();
|
||||
}
|
||||
if (!(completion instanceof AbruptCompletion)) {
|
||||
if (completion.PromiseState === 'rejected') {
|
||||
completion = Throw(completion.PromiseResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
completion = realm.evaluateScript(test.contents, { specifier });
|
||||
}
|
||||
|
||||
if (completion instanceof AbruptCompletion) {
|
||||
if (test.attrs.negative && isError(test.attrs.negative.type, completion.Value)) {
|
||||
return { status: 'PASS' };
|
||||
} else {
|
||||
return { status: 'FAIL', error: inspect(completion) };
|
||||
}
|
||||
}
|
||||
|
||||
if (test.attrs.flags.async) {
|
||||
if (!asyncResult) {
|
||||
throw new Error('missing async result');
|
||||
}
|
||||
return asyncResult;
|
||||
}
|
||||
|
||||
if (trackedPromises.length > 0) {
|
||||
return { status: 'FAIL', error: inspect(trackedPromises[0]) };
|
||||
}
|
||||
|
||||
if (test.attrs.negative) {
|
||||
return { status: 'FAIL', error: `Expected ${test.attrs.negative.type} during ${test.attrs.negative.phase}` };
|
||||
} else {
|
||||
return { status: 'PASS' };
|
||||
}
|
||||
});
|
||||
|
||||
return r;
|
||||
};
|
||||
|
||||
let p = Promise.resolve();
|
||||
const handleSendError = (e) => {
|
||||
if (e) {
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
process.on('message', (test) => {
|
||||
if (test === 'DONE') {
|
||||
p.then(() => process.exit(0));
|
||||
p = undefined;
|
||||
} else {
|
||||
const description = `${test.file}\n${test.attrs.description}`;
|
||||
p = p
|
||||
.then(() => run(test))
|
||||
.then((r) => {
|
||||
process.send({ description, ...r }, handleSendError);
|
||||
})
|
||||
.catch((e) => {
|
||||
process.send({ description, status: 'FAIL', error: util.inspect(e) }, handleSendError);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user