summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/test')
-rw-r--r--js/src/tests/test/expected/export/multi-header.js12
-rw-r--r--js/src/tests/test/expected/export/reftest-and-frontmatter-error.js9
-rw-r--r--js/src/tests/test/expected/export/reftest-error-syntaxerror.js11
-rw-r--r--js/src/tests/test/expected/export/regular.js2
-rw-r--r--js/src/tests/test/expected/import/files/local/smTempBranch/language/export/escaped-foobarbaz.js8
-rw-r--r--js/src/tests/test/expected/import/files/local/smTempBranch/shell.js384
-rw-r--r--js/src/tests/test/expected/import/files/local/smTempBranch/temp42/bar.js6
-rw-r--r--js/src/tests/test/expected/import/files/local/smTempBranch/temp42/baz.js6
-rw-r--r--js/src/tests/test/expected/import/files/local/smTempBranch/temp42/foo.js6
-rw-r--r--js/src/tests/test/fixtures/export/reftest-and-frontmatter-error.js2
-rw-r--r--js/src/tests/test/fixtures/export/reftest-error-syntaxerror.js2
-rw-r--r--js/src/tests/test/fixtures/export/reportCompare.js3
-rw-r--r--js/src/tests/test/fixtures/import/files/bar.js6
-rw-r--r--js/src/tests/test/fixtures/import/files/baz.js6
-rw-r--r--js/src/tests/test/fixtures/import/files/foo.js6
-rw-r--r--js/src/tests/test/python.toml4
-rwxr-xr-xjs/src/tests/test/run.py74
17 files changed, 386 insertions, 161 deletions
diff --git a/js/src/tests/test/expected/export/multi-header.js b/js/src/tests/test/expected/export/multi-header.js
index 477395713d..ea6c25ca88 100644
--- a/js/src/tests/test/expected/export/multi-header.js
+++ b/js/src/tests/test/expected/export/multi-header.js
@@ -2,21 +2,21 @@
// This code is governed by the BSD license found in the LICENSE file.
/*---
-info: |
- foo bar baz
+author: Jeff Walden <jwalden+code@mit.edu>
+esid: sec-let-and-const-declarations
description: |
Outside AsyncFunction, |await| is a perfectly cromulent LexicalDeclaration variable
name. Therefore ASI doesn't apply, and so the |0| where a |=| was expected is a
syntax error.
-author: Jeff Walden <jwalden+code@mit.edu>
negative:
phase: early
type: SyntaxError
-flags:
-- module
-esid: sec-let-and-const-declarations
features:
- foobar
+flags:
+- module
+info: |
+ foo bar baz
---*/
function f() {
diff --git a/js/src/tests/test/expected/export/reftest-and-frontmatter-error.js b/js/src/tests/test/expected/export/reftest-and-frontmatter-error.js
index 4966385662..8394ec7e51 100644
--- a/js/src/tests/test/expected/export/reftest-and-frontmatter-error.js
+++ b/js/src/tests/test/expected/export/reftest-and-frontmatter-error.js
@@ -1,17 +1,16 @@
// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
-
/*---
esid: sec-let-and-const-declarations
-features: []
-negative:
- phase: runtime
- type: SyntaxError
description: |
Outside AsyncFunction, |await| is a perfectly cromulent LexicalDeclaration variable
name. Therefore ASI doesn't apply, and so the |0| where a |=| was expected is a
syntax error.
+negative:
+ phase: runtime
+ type: SyntaxError
+features: []
---*/
eval(`
diff --git a/js/src/tests/test/expected/export/reftest-error-syntaxerror.js b/js/src/tests/test/expected/export/reftest-error-syntaxerror.js
index 5cd5759f66..163c5b8a4d 100644
--- a/js/src/tests/test/expected/export/reftest-error-syntaxerror.js
+++ b/js/src/tests/test/expected/export/reftest-error-syntaxerror.js
@@ -1,18 +1,17 @@
// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
-
/*---
-negative:
- phase: early
- type: SyntaxError
author: Jeff Walden <jwalden+code@mit.edu>
-features: []
+esid: sec-let-and-const-declarations
description: |
Outside AsyncFunction, |await| is a perfectly cromulent LexicalDeclaration variable
name. Therefore ASI doesn't apply, and so the |0| where a |=| was expected is a
syntax error.
-esid: sec-let-and-const-declarations
+features: []
+negative:
+ phase: early
+ type: SyntaxError
---*/
function f() {
diff --git a/js/src/tests/test/expected/export/regular.js b/js/src/tests/test/expected/export/regular.js
index b920a66a3c..4541ef37e5 100644
--- a/js/src/tests/test/expected/export/regular.js
+++ b/js/src/tests/test/expected/export/regular.js
@@ -3,11 +3,11 @@
/*---
author: Jeff Walden <jwalden+code@mit.edu>
+esid: sec-let-and-const-declarations
description: |
'|await| is excluded from LexicalDeclaration by grammar parameter, in AsyncFunction. Therefore
|let| followed by |await| inside AsyncFunction is an ASI opportunity, and this code
must parse without error.'
-esid: sec-let-and-const-declarations
---*/
async function f() {
diff --git a/js/src/tests/test/expected/import/files/local/smTempBranch/language/export/escaped-foobarbaz.js b/js/src/tests/test/expected/import/files/local/smTempBranch/language/export/escaped-foobarbaz.js
index 8f923637f3..f8a2afd775 100644
--- a/js/src/tests/test/expected/import/files/local/smTempBranch/language/export/escaped-foobarbaz.js
+++ b/js/src/tests/test/expected/import/files/local/smTempBranch/language/export/escaped-foobarbaz.js
@@ -6,8 +6,8 @@
esid: sec-grammar-notation
description: >
The `default` keyword must not contain Unicode escape sequences.
-info: >
- Terminal symbols of the lexical, RegExp, and numeric string grammars are shown
+info: |
+ Terminal symbols are shown
in fixed width font, both in the productions of the grammars and throughout this
specification whenever the text directly refers to such a terminal symbol. These
are to appear in a script exactly as written. All terminal symbol code points
@@ -15,11 +15,11 @@ info: >
from the Basic Latin range, as opposed to any similar-looking code points from
other Unicode ranges.
negative:
- phase: early
+ phase: parse
type: SyntaxError
flags: [module]
---*/
-throw "Test262: This statement should not be evaluated.";
+$DONOTEVALUATE();
export d\u0065fault 0;
diff --git a/js/src/tests/test/expected/import/files/local/smTempBranch/shell.js b/js/src/tests/test/expected/import/files/local/smTempBranch/shell.js
index ee1cf95742..9adb7aa914 100644
--- a/js/src/tests/test/expected/import/files/local/smTempBranch/shell.js
+++ b/js/src/tests/test/expected/import/files/local/smTempBranch/shell.js
@@ -1,20 +1,23 @@
+// GENERATED, DO NOT EDIT
// file: assert.js
// Copyright (C) 2017 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: |
Collection of assertion functions used throughout test262
+defines: [assert]
---*/
+
function assert(mustBeTrue, message) {
if (mustBeTrue === true) {
return;
}
if (message === undefined) {
- message = 'Expected true but got ' + String(mustBeTrue);
+ message = 'Expected true but got ' + assert._toString(mustBeTrue);
}
- $ERROR(message);
+ throw new Test262Error(message);
}
assert._isSameValue = function (a, b) {
@@ -28,7 +31,12 @@ assert._isSameValue = function (a, b) {
};
assert.sameValue = function (actual, expected, message) {
- if (assert._isSameValue(actual, expected)) {
+ try {
+ if (assert._isSameValue(actual, expected)) {
+ return;
+ }
+ } catch (error) {
+ throw new Test262Error(message + ' (_isSameValue operation threw) ' + error);
return;
}
@@ -38,9 +46,9 @@ assert.sameValue = function (actual, expected, message) {
message += ' ';
}
- message += 'Expected SameValue(«' + String(actual) + '», «' + String(expected) + '») to be true';
+ message += 'Expected SameValue(«' + assert._toString(actual) + '», «' + assert._toString(expected) + '») to be true';
- $ERROR(message);
+ throw new Test262Error(message);
};
assert.notSameValue = function (actual, unexpected, message) {
@@ -54,14 +62,15 @@ assert.notSameValue = function (actual, unexpected, message) {
message += ' ';
}
- message += 'Expected SameValue(«' + String(actual) + '», «' + String(unexpected) + '») to be false';
+ message += 'Expected SameValue(«' + assert._toString(actual) + '», «' + assert._toString(unexpected) + '») to be false';
- $ERROR(message);
+ throw new Test262Error(message);
};
assert.throws = function (expectedErrorConstructor, func, message) {
+ var expectedName, actualName;
if (typeof func !== "function") {
- $ERROR('assert.throws requires two arguments: the error constructor ' +
+ throw new Test262Error('assert.throws requires two arguments: the error constructor ' +
'and a function to run');
return;
}
@@ -76,23 +85,38 @@ assert.throws = function (expectedErrorConstructor, func, message) {
} catch (thrown) {
if (typeof thrown !== 'object' || thrown === null) {
message += 'Thrown value was not an object!';
- $ERROR(message);
+ throw new Test262Error(message);
} else if (thrown.constructor !== expectedErrorConstructor) {
- message += 'Expected a ' + expectedErrorConstructor.name + ' but got a ' + thrown.constructor.name;
- $ERROR(message);
+ expectedName = expectedErrorConstructor.name;
+ actualName = thrown.constructor.name;
+ if (expectedName === actualName) {
+ message += 'Expected a ' + expectedName + ' but got a different error constructor with the same name';
+ } else {
+ message += 'Expected a ' + expectedName + ' but got a ' + actualName;
+ }
+ throw new Test262Error(message);
}
return;
}
message += 'Expected a ' + expectedErrorConstructor.name + ' to be thrown but no exception was thrown at all';
- $ERROR(message);
+ throw new Test262Error(message);
};
-assert.throws.early = function(err, code) {
- let wrappedCode = `function wrapperFn() { ${code} }`;
- let ieval = eval;
+assert._toString = function (value) {
+ try {
+ if (value === 0 && 1 / value === -Infinity) {
+ return '-0';
+ }
+
+ return String(value);
+ } catch (err) {
+ if (err.name === 'TypeError') {
+ return Object.prototype.toString.call(value);
+ }
- assert.throws(err, () => { Function(wrappedCode); }, `Function: ${code}`);
+ throw err;
+ }
};
// file: compareArray.js
@@ -101,6 +125,7 @@ assert.throws.early = function(err, code) {
/*---
description: |
Compare the contents of two arrays
+defines: [compareArray]
---*/
function compareArray(a, b) {
@@ -109,16 +134,41 @@ function compareArray(a, b) {
}
for (var i = 0; i < a.length; i++) {
- if (b[i] !== a[i]) {
+ if (!compareArray.isSameValue(b[i], a[i])) {
return false;
}
}
return true;
}
+compareArray.isSameValue = function(a, b) {
+ if (a === 0 && b === 0) return 1 / a === 1 / b;
+ if (a !== a && b !== b) return true;
+
+ return a === b;
+};
+
+compareArray.format = function(arrayLike) {
+ return `[${[].map.call(arrayLike, String).join(', ')}]`;
+};
+
assert.compareArray = function(actual, expected, message) {
- assert(compareArray(actual, expected),
- `Expected [${actual.join(", ")}] and [${expected.join(", ")}] to have the same contents. ${message}`);
+ message = message === undefined ? '' : message;
+
+ if (typeof message === 'symbol') {
+ message = message.toString();
+ }
+
+ assert(actual != null, `First argument shouldn't be nullish. ${message}`);
+ assert(expected != null, `Second argument shouldn't be nullish. ${message}`);
+ var format = compareArray.format;
+ var result = compareArray(actual, expected);
+
+ // The following prevents actual and expected from being iterated and evaluated
+ // more than once unless absolutely necessary.
+ if (!result) {
+ assert(false, `Expected ${format(actual)} and ${format(expected)} to have the same contents. ${message}`);
+ }
};
// file: propertyHelper.js
@@ -128,8 +178,26 @@ assert.compareArray = function(actual, expected, message) {
description: |
Collection of functions used to safely verify the correctness of
property descriptors.
+defines:
+ - verifyProperty
+ - verifyEqualTo # deprecated
+ - verifyWritable # deprecated
+ - verifyNotWritable # deprecated
+ - verifyEnumerable # deprecated
+ - verifyNotEnumerable # deprecated
+ - verifyConfigurable # deprecated
+ - verifyNotConfigurable # deprecated
---*/
+// @ts-check
+
+/**
+ * @param {object} obj
+ * @param {string|symbol} name
+ * @param {PropertyDescriptor|undefined} desc
+ * @param {object} [options]
+ * @param {boolean} [options.restore]
+ */
function verifyProperty(obj, name, desc, options) {
assert(
arguments.length > 2,
@@ -144,7 +212,7 @@ function verifyProperty(obj, name, desc, options) {
assert.sameValue(
originalDesc,
undefined,
- `obj['${nameStr}'] descriptor should be undefined`
+ "obj['" + nameStr + "'] descriptor should be undefined"
);
// desc and originalDesc are both undefined, problem solved;
@@ -153,51 +221,67 @@ function verifyProperty(obj, name, desc, options) {
assert(
Object.prototype.hasOwnProperty.call(obj, name),
- `obj should have an own property ${nameStr}`
+ "obj should have an own property " + nameStr
);
assert.notSameValue(
desc,
null,
- `The desc argument should be an object or undefined, null`
+ "The desc argument should be an object or undefined, null"
);
assert.sameValue(
typeof desc,
"object",
- `The desc argument should be an object or undefined, ${String(desc)}`
+ "The desc argument should be an object or undefined, " + String(desc)
);
+ var names = Object.getOwnPropertyNames(desc);
+ for (var i = 0; i < names.length; i++) {
+ assert(
+ names[i] === "value" ||
+ names[i] === "writable" ||
+ names[i] === "enumerable" ||
+ names[i] === "configurable" ||
+ names[i] === "get" ||
+ names[i] === "set",
+ "Invalid descriptor field: " + names[i],
+ );
+ }
+
var failures = [];
if (Object.prototype.hasOwnProperty.call(desc, 'value')) {
- if (desc.value !== originalDesc.value) {
- failures.push(`descriptor value should be ${desc.value}`);
+ if (!isSameValue(desc.value, originalDesc.value)) {
+ failures.push("descriptor value should be " + desc.value);
+ }
+ if (!isSameValue(desc.value, obj[name])) {
+ failures.push("object value should be " + desc.value);
}
}
if (Object.prototype.hasOwnProperty.call(desc, 'enumerable')) {
if (desc.enumerable !== originalDesc.enumerable ||
desc.enumerable !== isEnumerable(obj, name)) {
- failures.push(`descriptor should ${desc.enumerable ? '' : 'not '}be enumerable`);
+ failures.push('descriptor should ' + (desc.enumerable ? '' : 'not ') + 'be enumerable');
}
}
if (Object.prototype.hasOwnProperty.call(desc, 'writable')) {
if (desc.writable !== originalDesc.writable ||
desc.writable !== isWritable(obj, name)) {
- failures.push(`descriptor should ${desc.writable ? '' : 'not '}be writable`);
+ failures.push('descriptor should ' + (desc.writable ? '' : 'not ') + 'be writable');
}
}
if (Object.prototype.hasOwnProperty.call(desc, 'configurable')) {
if (desc.configurable !== originalDesc.configurable ||
desc.configurable !== isConfigurable(obj, name)) {
- failures.push(`descriptor should ${desc.configurable ? '' : 'not '}be configurable`);
+ failures.push('descriptor should ' + (desc.configurable ? '' : 'not ') + 'be configurable');
}
}
- assert.sameValue(failures.length, 0, failures.join('; '));
+ assert(!failures.length, failures.join('; '));
if (options && options.restore) {
Object.defineProperty(obj, name, originalDesc);
@@ -207,14 +291,15 @@ function verifyProperty(obj, name, desc, options) {
}
function isConfigurable(obj, name) {
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
try {
delete obj[name];
} catch (e) {
if (!(e instanceof TypeError)) {
- $ERROR("Expected TypeError, got " + e);
+ throw new Test262Error("Expected TypeError, got " + e);
}
}
- return !Object.prototype.hasOwnProperty.call(obj, name);
+ return !hasOwnProperty.call(obj, name);
}
function isEnumerable(obj, name) {
@@ -237,14 +322,19 @@ function isEnumerable(obj, name) {
Object.prototype.propertyIsEnumerable.call(obj, name);
}
-function isEqualTo(obj, name, expectedValue) {
- var actualValue = obj[name];
+function isSameValue(a, b) {
+ if (a === 0 && b === 0) return 1 / a === 1 / b;
+ if (a !== a && b !== b) return true;
- return assert._isSameValue(actualValue, expectedValue);
+ return a === b;
}
+var __isArray = Array.isArray;
function isWritable(obj, name, verifyProp, value) {
- var newValue = value || "unlikelyValue";
+ var unlikelyValue = __isArray(obj) && name === "length" ?
+ Math.pow(2, 32) - 1 :
+ "unlikelyValue";
+ var newValue = value || unlikelyValue;
var hadValue = Object.prototype.hasOwnProperty.call(obj, name);
var oldValue = obj[name];
var writeSucceeded;
@@ -253,82 +343,103 @@ function isWritable(obj, name, verifyProp, value) {
obj[name] = newValue;
} catch (e) {
if (!(e instanceof TypeError)) {
- $ERROR("Expected TypeError, got " + e);
+ throw new Test262Error("Expected TypeError, got " + e);
}
}
- writeSucceeded = isEqualTo(obj, verifyProp || name, newValue);
+ writeSucceeded = isSameValue(obj[verifyProp || name], newValue);
// Revert the change only if it was successful (in other cases, reverting
// is unnecessary and may trigger exceptions for certain property
// configurations)
if (writeSucceeded) {
if (hadValue) {
- obj[name] = oldValue;
+ obj[name] = oldValue;
} else {
- delete obj[name];
+ delete obj[name];
}
}
return writeSucceeded;
}
+/**
+ * Deprecated; please use `verifyProperty` in new tests.
+ */
function verifyEqualTo(obj, name, value) {
- if (!isEqualTo(obj, name, value)) {
- $ERROR("Expected obj[" + String(name) + "] to equal " + value +
+ if (!isSameValue(obj[name], value)) {
+ throw new Test262Error("Expected obj[" + String(name) + "] to equal " + value +
", actually " + obj[name]);
}
}
+/**
+ * Deprecated; please use `verifyProperty` in new tests.
+ */
function verifyWritable(obj, name, verifyProp, value) {
if (!verifyProp) {
assert(Object.getOwnPropertyDescriptor(obj, name).writable,
"Expected obj[" + String(name) + "] to have writable:true.");
}
if (!isWritable(obj, name, verifyProp, value)) {
- $ERROR("Expected obj[" + String(name) + "] to be writable, but was not.");
+ throw new Test262Error("Expected obj[" + String(name) + "] to be writable, but was not.");
}
}
+/**
+ * Deprecated; please use `verifyProperty` in new tests.
+ */
function verifyNotWritable(obj, name, verifyProp, value) {
if (!verifyProp) {
assert(!Object.getOwnPropertyDescriptor(obj, name).writable,
"Expected obj[" + String(name) + "] to have writable:false.");
}
if (isWritable(obj, name, verifyProp)) {
- $ERROR("Expected obj[" + String(name) + "] NOT to be writable, but was.");
+ throw new Test262Error("Expected obj[" + String(name) + "] NOT to be writable, but was.");
}
}
+/**
+ * Deprecated; please use `verifyProperty` in new tests.
+ */
function verifyEnumerable(obj, name) {
assert(Object.getOwnPropertyDescriptor(obj, name).enumerable,
"Expected obj[" + String(name) + "] to have enumerable:true.");
if (!isEnumerable(obj, name)) {
- $ERROR("Expected obj[" + String(name) + "] to be enumerable, but was not.");
+ throw new Test262Error("Expected obj[" + String(name) + "] to be enumerable, but was not.");
}
}
+/**
+ * Deprecated; please use `verifyProperty` in new tests.
+ */
function verifyNotEnumerable(obj, name) {
assert(!Object.getOwnPropertyDescriptor(obj, name).enumerable,
"Expected obj[" + String(name) + "] to have enumerable:false.");
if (isEnumerable(obj, name)) {
- $ERROR("Expected obj[" + String(name) + "] NOT to be enumerable, but was.");
+ throw new Test262Error("Expected obj[" + String(name) + "] NOT to be enumerable, but was.");
}
}
+/**
+ * Deprecated; please use `verifyProperty` in new tests.
+ */
function verifyConfigurable(obj, name) {
assert(Object.getOwnPropertyDescriptor(obj, name).configurable,
"Expected obj[" + String(name) + "] to have configurable:true.");
if (!isConfigurable(obj, name)) {
- $ERROR("Expected obj[" + String(name) + "] to be configurable, but was not.");
+ throw new Test262Error("Expected obj[" + String(name) + "] to be configurable, but was not.");
}
}
+/**
+ * Deprecated; please use `verifyProperty` in new tests.
+ */
function verifyNotConfigurable(obj, name) {
assert(!Object.getOwnPropertyDescriptor(obj, name).configurable,
"Expected obj[" + String(name) + "] to have configurable:false.");
if (isConfigurable(obj, name)) {
- $ERROR("Expected obj[" + String(name) + "] NOT to be configurable, but was.");
+ throw new Test262Error("Expected obj[" + String(name) + "] NOT to be configurable, but was.");
}
}
@@ -341,6 +452,7 @@ description: |
- An error class to avoid false positives when testing for thrown exceptions
- A function to explicitly throw an exception using the Test262Error class
+defines: [Test262Error, $DONOTEVALUATE]
---*/
@@ -352,11 +464,14 @@ Test262Error.prototype.toString = function () {
return "Test262Error: " + this.message;
};
-var $ERROR;
-$ERROR = function $ERROR(message) {
+Test262Error.thrower = function (message) {
throw new Test262Error(message);
};
+function $DONOTEVALUATE() {
+ throw "Test262: This statement should not be evaluated.";
+}
+
// file: test262-host.js
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -364,18 +479,36 @@ $ERROR = function $ERROR(message) {
// https://github.com/tc39/test262/blob/main/INTERPRETING.md#host-defined-functions
;(function createHostObject(global) {
+ "use strict";
+
+ // Save built-in functions and constructors.
var FunctionToString = global.Function.prototype.toString;
var ReflectApply = global.Reflect.apply;
- var NewGlobal = global.newGlobal;
var Atomics = global.Atomics;
+ var Error = global.Error;
var SharedArrayBuffer = global.SharedArrayBuffer;
var Int32Array = global.Int32Array;
+
+ // Save built-in shell functions.
+ var NewGlobal = global.newGlobal;
var setSharedArrayBuffer = global.setSharedArrayBuffer;
var getSharedArrayBuffer = global.getSharedArrayBuffer;
var evalInWorker = global.evalInWorker;
+ var monotonicNow = global.monotonicNow;
+ var gc = global.gc;
+ var clearKeptObjects = global.clearKeptObjects;
+
+ var hasCreateIsHTMLDDA = "createIsHTMLDDA" in global;
var hasThreads = ("helperThreadCount" in global ? global.helperThreadCount() > 0 : true);
- var hasMailbox = typeof setSharedArrayBuffer == "function" && typeof getSharedArrayBuffer == "function";
- var hasEvalInWorker = typeof evalInWorker == "function";
+ var hasMailbox = typeof setSharedArrayBuffer === "function" && typeof getSharedArrayBuffer === "function";
+ var hasEvalInWorker = typeof evalInWorker === "function";
+
+ if (!hasCreateIsHTMLDDA && !("document" in global && "all" in global.document))
+ throw new Error("no [[IsHTMLDDA]] object available for testing");
+
+ var IsHTMLDDA = hasCreateIsHTMLDDA
+ ? global.createIsHTMLDDA()
+ : global.document.all;
// The $262.agent framework is not appropriate for browsers yet, and some
// test cases can't work in browsers (they block the main thread).
@@ -394,6 +527,13 @@ $ERROR = function $ERROR(message) {
detachArrayBuffer: global.detachArrayBuffer,
evalScript: global.evaluateScript || global.evaluate,
global,
+ IsHTMLDDA,
+ gc() {
+ gc();
+ },
+ clearKeptObjects() {
+ clearKeptObjects();
+ },
agent: (function () {
// SpiderMonkey complication: With run-time argument --no-threads
@@ -407,19 +547,23 @@ $ERROR = function $ERROR(message) {
// being run at all.
if (!sabTestable) {
+ let {reportCompare, quit} = global;
+
+ function notAvailable() {
+ // See comment above.
+ if (!hasThreads && shellCode) {
+ reportCompare(0, 0);
+ quit(0);
+ }
+ throw new Error("Agents not available");
+ }
+
return {
- _notAvailable() {
- // See comment above.
- if (!hasThreads && shellCode) {
- global.reportCompare(0,0);
- global.quit(0);
- }
- throw new Error("Agents not available");
- },
- start(script) { this._notAvailable() },
- broadcast(sab, id) { this._notAvailable() },
- getReport() { this._notAvailable() },
- sleep(s) { this._notAvailable() }
+ start(script) { notAvailable() },
+ broadcast(sab, id) { notAvailable() },
+ getReport() { notAvailable() },
+ sleep(s) { notAvailable() },
+ monotonicNow,
}
}
@@ -442,102 +586,110 @@ $ERROR = function $ERROR(message) {
var _worker_prefix =
// BEGIN WORKER PREFIX
-`if (typeof $262 == 'undefined')
+`if (typeof $262 === 'undefined')
$262 = {};
-$262.agent = (function () {
+$262.agent = (function (global) {
+ var ReflectApply = global.Reflect.apply;
+ var StringCharCodeAt = global.String.prototype.charCodeAt;
+ var {
+ add: Atomics_add,
+ compareExchange: Atomics_compareExchange,
+ load: Atomics_load,
+ store: Atomics_store,
+ wait: Atomics_wait,
+ } = global.Atomics;
+
+ var {getSharedArrayBuffer} = global;
+
var _ia = new Int32Array(getSharedArrayBuffer());
var agent = {
receiveBroadcast(receiver) {
var k;
- while (((k = Atomics.load(_ia, ${_MSG_LOC})) & 1) == 0)
+ while (((k = Atomics_load(_ia, ${_MSG_LOC})) & 1) === 0)
;
var received_sab = getSharedArrayBuffer();
- var received_id = Atomics.load(_ia, ${_ID_LOC});
- Atomics.add(_ia, ${_ACK_LOC}, 1);
- while (Atomics.load(_ia, ${_MSG_LOC}) == k)
+ var received_id = Atomics_load(_ia, ${_ID_LOC});
+ Atomics_add(_ia, ${_ACK_LOC}, 1);
+ while (Atomics_load(_ia, ${_MSG_LOC}) === k)
;
receiver(received_sab, received_id);
},
report(msg) {
- while (Atomics.compareExchange(_ia, ${_LOCKTXT_LOC}, 0, 1) == 1)
+ while (Atomics_compareExchange(_ia, ${_LOCKTXT_LOC}, 0, 1) === 1)
;
msg = "" + msg;
var i = _ia[${_NEXT_LOC}];
_ia[i++] = msg.length;
for ( let j=0 ; j < msg.length ; j++ )
- _ia[i++] = msg.charCodeAt(j);
+ _ia[i++] = ReflectApply(StringCharCodeAt, msg, [j]);
_ia[${_NEXT_LOC}] = i;
- Atomics.add(_ia, ${_NUMTXT_LOC}, 1);
- Atomics.store(_ia, ${_LOCKTXT_LOC}, 0);
+ Atomics_add(_ia, ${_NUMTXT_LOC}, 1);
+ Atomics_store(_ia, ${_LOCKTXT_LOC}, 0);
},
sleep(s) {
- Atomics.wait(_ia, ${_SLEEP_LOC}, 0, s);
+ Atomics_wait(_ia, ${_SLEEP_LOC}, 0, s);
},
- leaving() {}
+ leaving() {},
+
+ monotonicNow: global.monotonicNow,
};
- Atomics.add(_ia, ${_RDY_LOC}, 1);
+ Atomics_add(_ia, ${_RDY_LOC}, 1);
return agent;
-})();`;
+})(this);`;
// END WORKER PREFIX
- return {
- _numWorkers: 0,
- _numReports: 0,
- _reportPtr: _FIRST,
-
- _bailIfNotAvailable() {
- if (!sabTestable) {
- // See comment above.
- if (!hasThreads && shellCode) {
- global.reportCompare(0,0);
- global.quit(0);
- }
- throw new Error("Agents not available");
- }
- },
+ var _numWorkers = 0;
+ var _numReports = 0;
+ var _reportPtr = _FIRST;
+ var {
+ add: Atomics_add,
+ load: Atomics_load,
+ store: Atomics_store,
+ wait: Atomics_wait,
+ } = Atomics;
+ var StringFromCharCode = global.String.fromCharCode;
+ return {
start(script) {
- this._bailIfNotAvailable();
setSharedArrayBuffer(_ia.buffer);
- var oldrdy = Atomics.load(_ia, _RDY_LOC);
+ var oldrdy = Atomics_load(_ia, _RDY_LOC);
evalInWorker(_worker_prefix + script);
- while (Atomics.load(_ia, _RDY_LOC) == oldrdy)
+ while (Atomics_load(_ia, _RDY_LOC) === oldrdy)
;
- this._numWorkers++;
+ _numWorkers++;
},
broadcast(sab, id) {
- this._bailIfNotAvailable();
setSharedArrayBuffer(sab);
- Atomics.store(_ia, _ID_LOC, id);
- Atomics.store(_ia, _ACK_LOC, 0);
- Atomics.add(_ia, _MSG_LOC, 1);
- while (Atomics.load(_ia, _ACK_LOC) < this._numWorkers)
+ Atomics_store(_ia, _ID_LOC, id);
+ Atomics_store(_ia, _ACK_LOC, 0);
+ Atomics_add(_ia, _MSG_LOC, 1);
+ while (Atomics_load(_ia, _ACK_LOC) < _numWorkers)
;
- Atomics.add(_ia, _MSG_LOC, 1);
+ Atomics_add(_ia, _MSG_LOC, 1);
},
getReport() {
- this._bailIfNotAvailable();
- if (this._numReports == Atomics.load(_ia, _NUMTXT_LOC))
+ if (_numReports === Atomics_load(_ia, _NUMTXT_LOC))
return null;
var s = "";
- var i = this._reportPtr;
+ var i = _reportPtr;
var len = _ia[i++];
for ( let j=0 ; j < len ; j++ )
- s += String.fromCharCode(_ia[i++]);
- this._reportPtr = i;
- this._numReports++;
+ s += StringFromCharCode(_ia[i++]);
+ _reportPtr = i;
+ _numReports++;
return s;
},
sleep(s) {
- this._bailIfNotAvailable();
- Atomics.wait(_ia, _SLEEP_LOC, 0, s);
+ Atomics_wait(_ia, _SLEEP_LOC, 0, s);
},
+
+ monotonicNow,
};
})()
};
@@ -558,4 +710,14 @@ function $DONE(failure) {
reportFailure(failure);
else
reportCompare(0, 0);
+
+ if (typeof jsTestDriverEnd === "function") {
+ gDelayTestDriverEnd = false;
+ jsTestDriverEnd();
+ }
+}
+
+// Some tests in test262 leave promise rejections unhandled.
+if ("ignoreUnhandledRejections" in this) {
+ ignoreUnhandledRejections();
}
diff --git a/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/bar.js b/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/bar.js
index c22331fd51..210c610046 100644
--- a/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/bar.js
+++ b/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/bar.js
@@ -1,2 +1,8 @@
+// Copyright (C) 2017 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-grammar-notation
+---*/
reportCompare(0, 0);
diff --git a/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/baz.js b/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/baz.js
index c22331fd51..210c610046 100644
--- a/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/baz.js
+++ b/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/baz.js
@@ -1,2 +1,8 @@
+// Copyright (C) 2017 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-grammar-notation
+---*/
reportCompare(0, 0);
diff --git a/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/foo.js b/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/foo.js
index c22331fd51..210c610046 100644
--- a/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/foo.js
+++ b/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/foo.js
@@ -1,2 +1,8 @@
+// Copyright (C) 2017 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-grammar-notation
+---*/
reportCompare(0, 0);
diff --git a/js/src/tests/test/fixtures/export/reftest-and-frontmatter-error.js b/js/src/tests/test/fixtures/export/reftest-and-frontmatter-error.js
index 38e98283d7..4355646c73 100644
--- a/js/src/tests/test/fixtures/export/reftest-and-frontmatter-error.js
+++ b/js/src/tests/test/fixtures/export/reftest-and-frontmatter-error.js
@@ -1,4 +1,6 @@
// |reftest| error:SyntaxError
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-let-and-const-declarations
diff --git a/js/src/tests/test/fixtures/export/reftest-error-syntaxerror.js b/js/src/tests/test/fixtures/export/reftest-error-syntaxerror.js
index 718778ddf7..974369a3b1 100644
--- a/js/src/tests/test/fixtures/export/reftest-error-syntaxerror.js
+++ b/js/src/tests/test/fixtures/export/reftest-error-syntaxerror.js
@@ -1,4 +1,6 @@
// |reftest| error:SyntaxError
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
/*---
author: Jeff Walden <jwalden+code@mit.edu>
diff --git a/js/src/tests/test/fixtures/export/reportCompare.js b/js/src/tests/test/fixtures/export/reportCompare.js
index 7b5af60053..3e22e016fb 100644
--- a/js/src/tests/test/fixtures/export/reportCompare.js
+++ b/js/src/tests/test/fixtures/export/reportCompare.js
@@ -36,3 +36,6 @@ reportCompare(
true,
true
);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/test/fixtures/import/files/bar.js b/js/src/tests/test/fixtures/import/files/bar.js
index e69de29bb2..30a528ee66 100644
--- a/js/src/tests/test/fixtures/import/files/bar.js
+++ b/js/src/tests/test/fixtures/import/files/bar.js
@@ -0,0 +1,6 @@
+// Copyright (C) 2017 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-grammar-notation
+---*/
diff --git a/js/src/tests/test/fixtures/import/files/baz.js b/js/src/tests/test/fixtures/import/files/baz.js
index e69de29bb2..30a528ee66 100644
--- a/js/src/tests/test/fixtures/import/files/baz.js
+++ b/js/src/tests/test/fixtures/import/files/baz.js
@@ -0,0 +1,6 @@
+// Copyright (C) 2017 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-grammar-notation
+---*/
diff --git a/js/src/tests/test/fixtures/import/files/foo.js b/js/src/tests/test/fixtures/import/files/foo.js
index e69de29bb2..30a528ee66 100644
--- a/js/src/tests/test/fixtures/import/files/foo.js
+++ b/js/src/tests/test/fixtures/import/files/foo.js
@@ -0,0 +1,6 @@
+// Copyright (C) 2017 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-grammar-notation
+---*/
diff --git a/js/src/tests/test/python.toml b/js/src/tests/test/python.toml
new file mode 100644
index 0000000000..0be72db2d7
--- /dev/null
+++ b/js/src/tests/test/python.toml
@@ -0,0 +1,4 @@
+[DEFAULT]
+subsuite = "mozbuild"
+
+["run.py"]
diff --git a/js/src/tests/test/run.py b/js/src/tests/test/run.py
index a6f7a94932..862045a083 100755
--- a/js/src/tests/test/run.py
+++ b/js/src/tests/test/run.py
@@ -1,19 +1,23 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Adapted from https://github.com/tc39/test262/blob/main/tools/generation/test/run.py
import contextlib
import os
import shutil
import subprocess
+import sys
import tempfile
import unittest
-testDir = os.path.dirname(os.path.relpath(__file__))
-OUT_DIR = os.path.join(testDir, "out")
+import pytest
+from mozunit import main
+
+testDir = os.path.dirname(os.path.abspath(__file__))
+OUT_DIR = os.path.abspath(os.path.join(testDir, "..", "out"))
EXPECTED_DIR = os.path.join(testDir, "expected")
ex = os.path.join(testDir, "..", "test262-export.py")
importExec = os.path.join(testDir, "..", "test262-update.py")
-test262Url = "git://github.com/tc39/test262.git"
+test262Url = "https://github.com/tc39/test262.git"
@contextlib.contextmanager
@@ -29,8 +33,12 @@ class TestExport(unittest.TestCase):
maxDiff = None
def exportScript(self):
- relpath = os.path.relpath(os.path.join(testDir, "fixtures", "export"))
- sp = subprocess.Popen([ex, relpath, "--out", OUT_DIR], stdout=subprocess.PIPE)
+ abspath = os.path.abspath(os.path.join(testDir, "fixtures", "export"))
+ sp = subprocess.Popen(
+ [sys.executable, os.path.abspath(ex), abspath, "--out", OUT_DIR],
+ stdout=subprocess.PIPE,
+ cwd=os.path.join(testDir, ".."),
+ )
stdout, stderr = sp.communicate()
return dict(stdout=stdout, stderr=stderr, returncode=sp.returncode)
@@ -67,56 +75,57 @@ class TestExport(unittest.TestCase):
)
# Run import script
- print("%s --local %s --out %s" % (importExec, cloneDir, OUT_DIR))
+ print(
+ "%s %s --local %s --out %s"
+ % (sys.executable, importExec, cloneDir, OUT_DIR)
+ )
sp = subprocess.Popen(
- [importExec, "--local", cloneDir, "--out", OUT_DIR],
+ [sys.executable, importExec, "--local", cloneDir, "--out", OUT_DIR],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
+ cwd=os.path.join(testDir, ".."),
)
- stdoutdata, _ = sp.communicate()
+ stdoutdata, stderrdata = sp.communicate()
- return stdoutdata, sp.returncode, cloneDir
+ return stdoutdata, stderrdata, sp.returncode, cloneDir
- def isTestFile(self, filename):
+ def isTestFile(self, filename: str):
return not (
filename.startswith(".")
or filename.startswith("#")
or filename.endswith("~")
)
- def getFiles(self, path):
- names = []
+ def getFiles(self, path: str):
+ names: list[str] = []
for root, _, fileNames in os.walk(path):
for fileName in filter(self.isTestFile, fileNames):
names.append(os.path.join(root, fileName))
names.sort()
return names
- def compareTrees(self, targetName):
- expectedPath = os.path.join(EXPECTED_DIR, targetName)
- actualPath = OUT_DIR
-
+ def compareTrees(self, expectedPath: str, actualPath: str):
expectedFiles = self.getFiles(expectedPath)
actualFiles = self.getFiles(actualPath)
self.assertListEqual(
- map(lambda x: os.path.relpath(x, expectedPath), expectedFiles),
- map(lambda x: os.path.relpath(x, actualPath), actualFiles),
+ [os.path.relpath(x, expectedPath) for x in expectedFiles],
+ [os.path.relpath(x, actualPath) for x in actualFiles],
)
for expectedFile, actualFile in zip(expectedFiles, actualFiles):
with open(expectedFile) as expectedHandle:
with open(actualFile) as actualHandle:
self.assertMultiLineEqual(
- expectedHandle.read(), actualHandle.read()
+ expectedHandle.read(), actualHandle.read(), expectedFile
)
- def compareContents(self, output, filePath, folder):
- with open(filePath, "rb") as file:
+ def compareContents(self, output: bytes, filePath: str, folder: str):
+ with open(filePath, "r") as file:
expected = file.read()
expected = expected.replace("{{folder}}", folder)
- self.assertMultiLineEqual(output, expected)
+ self.assertMultiLineEqual(output.decode("utf-8"), expected)
def tearDown(self):
shutil.rmtree(OUT_DIR, ignore_errors=True)
@@ -124,16 +133,25 @@ class TestExport(unittest.TestCase):
def test_export(self):
result = self.exportScript()
self.assertEqual(result["returncode"], 0)
- self.compareTrees("export")
+ expectedPath = os.path.join(EXPECTED_DIR, "export")
+ actualPath = os.path.join(OUT_DIR, "tests", "export")
+ self.compareTrees(expectedPath, actualPath)
+ @pytest.mark.skip(reason="test fetches from github")
def test_import_local(self):
- output, returncode, folder = self.importLocal()
+ stdoutdata, stderrdata, returncode, folder = self.importLocal()
+ self.assertEqual(stderrdata, b"")
self.assertEqual(returncode, 0)
- self.compareTrees(os.path.join("import", "files"))
+ self.compareTrees(
+ os.path.join(EXPECTED_DIR, "import", "files", "local"),
+ os.path.join(OUT_DIR, "local"),
+ )
self.compareContents(
- output, os.path.join(testDir, "expected", "import", "output.txt"), folder
+ stdoutdata,
+ os.path.join(testDir, "expected", "import", "output.txt"),
+ folder,
)
if __name__ == "__main__":
- unittest.main()
+ main()