Bug 1503012 - Part 2: Shim some web-platform-tests for streams into the jit-tests. r=arai,chmanchester,jimb

This is an egregious hack. The web-platform-tests were not meant to run in the shell.

The eight tests that are included are the ones that we pass with flying colors.
In most of the others, we still have a failure or two.

Differential Revision: https://phabricator.services.mozilla.com/D11533

--HG--
rename : dom/imptests/testharness.js => js/src/jit-test/lib/w3c-testharness.js
extra : moz-landing-system : lando
This commit is contained in:
Jason Orendorff 2018-12-09 15:48:33 +00:00
Родитель dc3585e58b
Коммит 45c6c35730
12 изменённых файлов: 1119 добавлений и 0 удалений

Просмотреть файл

@ -76,9 +76,12 @@ def generate_package_data(args):
# specific zips.
tests_common = args.tests_common
jsshell = args.jsshell
web_platform = getattr(args, 'web-platform')
harness_requirements = dict([(k, [tests_common]) for k in ALL_HARNESSES])
harness_requirements['jittest'].append(jsshell)
harness_requirements['jittest'].append(web_platform)
for harness in PACKAGE_SPECIFIED_HARNESSES + OPTIONAL_PACKAGES:
pkg_name = getattr(args, harness, None)
if pkg_name is None:

Просмотреть файл

@ -0,0 +1,897 @@
/*global self*/
/*jshint latedef: nofunc*/
/*
Distributed under both the W3C Test Suite License [1] and the W3C
3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
policies and contribution forms [3].
[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
[3] http://www.w3.org/2004/10/27-testcases
*/
/* Documentation is in docs/api.md */
(function ()
{
let tests = {timeout_multiplier: 1}; // ADDED
function step_timeout(f, t) {
var outer_this = this;
var args = Array.prototype.slice.call(arguments, 2);
return setTimeout(function() {
f.apply(outer_this, args);
}, t * tests.timeout_multiplier);
}
expose(step_timeout, 'step_timeout');
/*
* Return a string truncated to the given length, with ... added at the end
* if it was longer.
*/
function truncate(s, len)
{
if (s.length > len) {
return s.substring(0, len - 3) + "...";
}
return s;
}
/*
* Return true if object is probably a Node object.
*/
function is_node(object)
{
// I use duck-typing instead of instanceof, because
// instanceof doesn't work if the node is from another window (like an
// iframe's contentWindow):
// http://www.w3.org/Bugs/Public/show_bug.cgi?id=12295
if ("nodeType" in object &&
"nodeName" in object &&
"nodeValue" in object &&
"childNodes" in object) {
try {
object.nodeType;
} catch (e) {
// The object is probably Node.prototype or another prototype
// object that inherits from it, and not a Node instance.
return false;
}
return true;
}
return false;
}
/*
* Convert a value to a nice, human-readable string
*/
function format_value(val, seen)
{
if (!seen) {
seen = [];
}
if (typeof val === "object" && val !== null) {
if (seen.includes(val)) {
return "[...]";
}
seen.push(val);
}
if (Array.isArray(val)) {
return "[" + val.map(function(x) {return format_value(x, seen);}).join(", ") + "]";
}
switch (typeof val) {
case "string":
val = val.replace("\\", "\\\\");
for (var i = 0; i < 32; i++) {
var replace = "\\";
switch (i) {
case 0: replace += "0"; break;
case 1: replace += "x01"; break;
case 2: replace += "x02"; break;
case 3: replace += "x03"; break;
case 4: replace += "x04"; break;
case 5: replace += "x05"; break;
case 6: replace += "x06"; break;
case 7: replace += "x07"; break;
case 8: replace += "b"; break;
case 9: replace += "t"; break;
case 10: replace += "n"; break;
case 11: replace += "v"; break;
case 12: replace += "f"; break;
case 13: replace += "r"; break;
case 14: replace += "x0e"; break;
case 15: replace += "x0f"; break;
case 16: replace += "x10"; break;
case 17: replace += "x11"; break;
case 18: replace += "x12"; break;
case 19: replace += "x13"; break;
case 20: replace += "x14"; break;
case 21: replace += "x15"; break;
case 22: replace += "x16"; break;
case 23: replace += "x17"; break;
case 24: replace += "x18"; break;
case 25: replace += "x19"; break;
case 26: replace += "x1a"; break;
case 27: replace += "x1b"; break;
case 28: replace += "x1c"; break;
case 29: replace += "x1d"; break;
case 30: replace += "x1e"; break;
case 31: replace += "x1f"; break;
}
val = val.replace(RegExp(String.fromCharCode(i), "g"), replace);
}
return '"' + val.replace(/"/g, '\\"') + '"';
case "boolean":
case "undefined":
return String(val);
case "number":
// In JavaScript, -0 === 0 and String(-0) == "0", so we have to
// special-case.
if (val === -0 && 1/val === -Infinity) {
return "-0";
}
return String(val);
case "object":
if (val === null) {
return "null";
}
// Special-case Node objects, since those come up a lot in my tests. I
// ignore namespaces.
if (is_node(val)) {
switch (val.nodeType) {
case Node.ELEMENT_NODE:
var ret = "<" + val.localName;
for (var i = 0; i < val.attributes.length; i++) {
ret += " " + val.attributes[i].name + '="' + val.attributes[i].value + '"';
}
ret += ">" + val.innerHTML + "</" + val.localName + ">";
return "Element node " + truncate(ret, 60);
case Node.TEXT_NODE:
return 'Text node "' + truncate(val.data, 60) + '"';
case Node.PROCESSING_INSTRUCTION_NODE:
return "ProcessingInstruction node with target " + format_value(truncate(val.target, 60)) + " and data " + format_value(truncate(val.data, 60));
case Node.COMMENT_NODE:
return "Comment node <!--" + truncate(val.data, 60) + "-->";
case Node.DOCUMENT_NODE:
return "Document node with " + val.childNodes.length + (val.childNodes.length == 1 ? " child" : " children");
case Node.DOCUMENT_TYPE_NODE:
return "DocumentType node";
case Node.DOCUMENT_FRAGMENT_NODE:
return "DocumentFragment node with " + val.childNodes.length + (val.childNodes.length == 1 ? " child" : " children");
default:
return "Node object of unknown type";
}
}
/* falls through */
default:
return typeof val + ' "' + truncate(String(val), 60) + '"';
}
}
expose(format_value, "format_value");
/*
* Assertions
*/
function assert_true(actual, description)
{
assert(actual === true, "assert_true", description,
"expected true got ${actual}", {actual:actual});
}
expose(assert_true, "assert_true");
function assert_false(actual, description)
{
assert(actual === false, "assert_false", description,
"expected false got ${actual}", {actual:actual});
}
expose(assert_false, "assert_false");
function same_value(x, y) {
if (y !== y) {
//NaN case
return x !== x;
}
if (x === 0 && y === 0) {
//Distinguish +0 and -0
return 1/x === 1/y;
}
return x === y;
}
function assert_equals(actual, expected, description)
{
/*
* Test if two primitives are equal or two objects
* are the same object
*/
if (typeof actual != typeof expected) {
assert(false, "assert_equals", description,
"expected (" + typeof expected + ") ${expected} but got (" + typeof actual + ") ${actual}",
{expected:expected, actual:actual});
return;
}
assert(same_value(actual, expected), "assert_equals", description,
"expected ${expected} but got ${actual}",
{expected:expected, actual:actual});
}
expose(assert_equals, "assert_equals");
function assert_not_equals(actual, expected, description)
{
/*
* Test if two primitives are unequal or two objects
* are different objects
*/
assert(!same_value(actual, expected), "assert_not_equals", description,
"got disallowed value ${actual}",
{actual:actual});
}
expose(assert_not_equals, "assert_not_equals");
function assert_in_array(actual, expected, description)
{
assert(expected.includes(actual), "assert_in_array", description,
"value ${actual} not in array ${expected}",
{actual:actual, expected:expected});
}
expose(assert_in_array, "assert_in_array");
function assert_object_equals(actual, expected, description)
{
//This needs to be improved a great deal
function check_equal(actual, expected, stack)
{
stack.push(actual);
var p;
for (p in actual) {
assert(expected.hasOwnProperty(p), "assert_object_equals", description,
"unexpected property ${p}", {p:p});
if (typeof actual[p] === "object" && actual[p] !== null) {
if (!stack.includes(actual[p])) {
check_equal(actual[p], expected[p], stack);
}
} else {
assert(same_value(actual[p], expected[p]), "assert_object_equals", description,
"property ${p} expected ${expected} got ${actual}",
{p:p, expected:expected, actual:actual});
}
}
for (p in expected) {
assert(actual.hasOwnProperty(p),
"assert_object_equals", description,
"expected property ${p} missing", {p:p});
}
stack.pop();
}
check_equal(actual, expected, []);
}
expose(assert_object_equals, "assert_object_equals");
function assert_array_equals(actual, expected, description)
{
assert(actual.length === expected.length,
"assert_array_equals", description,
"lengths differ, expected ${expected} got ${actual}",
{expected:expected.length, actual:actual.length});
for (var i = 0; i < actual.length; i++) {
assert(actual.hasOwnProperty(i) === expected.hasOwnProperty(i),
"assert_array_equals", description,
"property ${i}, property expected to be ${expected} but was ${actual}",
{i:i, expected:expected.hasOwnProperty(i) ? "present" : "missing",
actual:actual.hasOwnProperty(i) ? "present" : "missing"});
assert(same_value(expected[i], actual[i]),
"assert_array_equals", description,
"property ${i}, expected ${expected} but got ${actual}",
{i:i, expected:expected[i], actual:actual[i]});
}
}
expose(assert_array_equals, "assert_array_equals");
function assert_approx_equals(actual, expected, epsilon, description)
{
/*
* Test if two primitive numbers are equal withing +/- epsilon
*/
assert(typeof actual === "number",
"assert_approx_equals", description,
"expected a number but got a ${type_actual}",
{type_actual:typeof actual});
assert(Math.abs(actual - expected) <= epsilon,
"assert_approx_equals", description,
"expected ${expected} +/- ${epsilon} but got ${actual}",
{expected:expected, actual:actual, epsilon:epsilon});
}
expose(assert_approx_equals, "assert_approx_equals");
function assert_less_than(actual, expected, description)
{
/*
* Test if a primitive number is less than another
*/
assert(typeof actual === "number",
"assert_less_than", description,
"expected a number but got a ${type_actual}",
{type_actual:typeof actual});
assert(actual < expected,
"assert_less_than", description,
"expected a number less than ${expected} but got ${actual}",
{expected:expected, actual:actual});
}
expose(assert_less_than, "assert_less_than");
function assert_greater_than(actual, expected, description)
{
/*
* Test if a primitive number is greater than another
*/
assert(typeof actual === "number",
"assert_greater_than", description,
"expected a number but got a ${type_actual}",
{type_actual:typeof actual});
assert(actual > expected,
"assert_greater_than", description,
"expected a number greater than ${expected} but got ${actual}",
{expected:expected, actual:actual});
}
expose(assert_greater_than, "assert_greater_than");
function assert_between_exclusive(actual, lower, upper, description)
{
/*
* Test if a primitive number is between two others
*/
assert(typeof actual === "number",
"assert_between_exclusive", description,
"expected a number but got a ${type_actual}",
{type_actual:typeof actual});
assert(actual > lower && actual < upper,
"assert_between_exclusive", description,
"expected a number greater than ${lower} " +
"and less than ${upper} but got ${actual}",
{lower:lower, upper:upper, actual:actual});
}
expose(assert_between_exclusive, "assert_between_exclusive");
function assert_less_than_equal(actual, expected, description)
{
/*
* Test if a primitive number is less than or equal to another
*/
assert(typeof actual === "number",
"assert_less_than_equal", description,
"expected a number but got a ${type_actual}",
{type_actual:typeof actual});
assert(actual <= expected,
"assert_less_than_equal", description,
"expected a number less than or equal to ${expected} but got ${actual}",
{expected:expected, actual:actual});
}
expose(assert_less_than_equal, "assert_less_than_equal");
function assert_greater_than_equal(actual, expected, description)
{
/*
* Test if a primitive number is greater than or equal to another
*/
assert(typeof actual === "number",
"assert_greater_than_equal", description,
"expected a number but got a ${type_actual}",
{type_actual:typeof actual});
assert(actual >= expected,
"assert_greater_than_equal", description,
"expected a number greater than or equal to ${expected} but got ${actual}",
{expected:expected, actual:actual});
}
expose(assert_greater_than_equal, "assert_greater_than_equal");
function assert_between_inclusive(actual, lower, upper, description)
{
/*
* Test if a primitive number is between to two others or equal to either of them
*/
assert(typeof actual === "number",
"assert_between_inclusive", description,
"expected a number but got a ${type_actual}",
{type_actual:typeof actual});
assert(actual >= lower && actual <= upper,
"assert_between_inclusive", description,
"expected a number greater than or equal to ${lower} " +
"and less than or equal to ${upper} but got ${actual}",
{lower:lower, upper:upper, actual:actual});
}
expose(assert_between_inclusive, "assert_between_inclusive");
function assert_regexp_match(actual, expected, description) {
/*
* Test if a string (actual) matches a regexp (expected)
*/
assert(expected.test(actual),
"assert_regexp_match", description,
"expected ${expected} but got ${actual}",
{expected:expected, actual:actual});
}
expose(assert_regexp_match, "assert_regexp_match");
function assert_class_string(object, class_string, description) {
assert_equals({}.toString.call(object), "[object " + class_string + "]",
description);
}
expose(assert_class_string, "assert_class_string");
function _assert_own_property(name) {
return function(object, property_name, description)
{
assert(object.hasOwnProperty(property_name),
name, description,
"expected property ${p} missing", {p:property_name});
};
}
expose(_assert_own_property("assert_exists"), "assert_exists");
expose(_assert_own_property("assert_own_property"), "assert_own_property");
function assert_not_exists(object, property_name, description)
{
assert(!object.hasOwnProperty(property_name),
"assert_not_exists", description,
"unexpected property ${p} found", {p:property_name});
}
expose(assert_not_exists, "assert_not_exists");
function _assert_inherits(name) {
return function (object, property_name, description)
{
assert(typeof object === "object",
name, description,
"provided value is not an object");
assert("hasOwnProperty" in object,
name, description,
"provided value is an object but has no hasOwnProperty method");
assert(!object.hasOwnProperty(property_name),
name, description,
"property ${p} found on object expected in prototype chain",
{p:property_name});
assert(property_name in object,
name, description,
"property ${p} not found in prototype chain",
{p:property_name});
};
}
expose(_assert_inherits("assert_inherits"), "assert_inherits");
expose(_assert_inherits("assert_idl_attribute"), "assert_idl_attribute");
function assert_readonly(object, property_name, description)
{
var initial_value = object[property_name];
try {
//Note that this can have side effects in the case where
//the property has PutForwards
object[property_name] = initial_value + "a"; //XXX use some other value here?
assert(same_value(object[property_name], initial_value),
"assert_readonly", description,
"changing property ${p} succeeded",
{p:property_name});
} finally {
object[property_name] = initial_value;
}
}
expose(assert_readonly, "assert_readonly");
function assert_throws(code, func, description)
{
try {
func.call(this);
assert(false, "assert_throws", description,
"${func} did not throw", {func:func});
} catch (e) {
if (e instanceof AssertionError) {
throw e;
}
if (code === null) {
return;
}
if (typeof code === "object") {
assert(typeof e == "object" && "name" in e && e.name == code.name,
"assert_throws", description,
"${func} threw ${actual} (${actual_name}) expected ${expected} (${expected_name})",
{func:func, actual:e, actual_name:e.name,
expected:code,
expected_name:code.name});
return;
}
var code_name_map = {
INDEX_SIZE_ERR: 'IndexSizeError',
HIERARCHY_REQUEST_ERR: 'HierarchyRequestError',
WRONG_DOCUMENT_ERR: 'WrongDocumentError',
INVALID_CHARACTER_ERR: 'InvalidCharacterError',
NO_MODIFICATION_ALLOWED_ERR: 'NoModificationAllowedError',
NOT_FOUND_ERR: 'NotFoundError',
NOT_SUPPORTED_ERR: 'NotSupportedError',
INVALID_STATE_ERR: 'InvalidStateError',
SYNTAX_ERR: 'SyntaxError',
INVALID_MODIFICATION_ERR: 'InvalidModificationError',
NAMESPACE_ERR: 'NamespaceError',
INVALID_ACCESS_ERR: 'InvalidAccessError',
TYPE_MISMATCH_ERR: 'TypeMismatchError',
SECURITY_ERR: 'SecurityError',
NETWORK_ERR: 'NetworkError',
ABORT_ERR: 'AbortError',
URL_MISMATCH_ERR: 'URLMismatchError',
QUOTA_EXCEEDED_ERR: 'QuotaExceededError',
TIMEOUT_ERR: 'TimeoutError',
INVALID_NODE_TYPE_ERR: 'InvalidNodeTypeError',
DATA_CLONE_ERR: 'DataCloneError'
};
var name = code in code_name_map ? code_name_map[code] : code;
var name_code_map = {
IndexSizeError: 1,
HierarchyRequestError: 3,
WrongDocumentError: 4,
InvalidCharacterError: 5,
NoModificationAllowedError: 7,
NotFoundError: 8,
NotSupportedError: 9,
InvalidStateError: 11,
SyntaxError: 12,
InvalidModificationError: 13,
NamespaceError: 14,
InvalidAccessError: 15,
TypeMismatchError: 17,
SecurityError: 18,
NetworkError: 19,
AbortError: 20,
URLMismatchError: 21,
QuotaExceededError: 22,
TimeoutError: 23,
InvalidNodeTypeError: 24,
DataCloneError: 25,
EncodingError: 0,
NotReadableError: 0,
UnknownError: 0,
ConstraintError: 0,
DataError: 0,
TransactionInactiveError: 0,
ReadOnlyError: 0,
VersionError: 0,
OperationError: 0,
};
if (!(name in name_code_map)) {
throw new AssertionError('Test bug: unrecognized DOMException code "' + code + '" passed to assert_throws()');
}
var required_props = { code: name_code_map[name] };
if (required_props.code === 0 ||
(typeof e == "object" &&
"name" in e &&
e.name !== e.name.toUpperCase() &&
e.name !== "DOMException")) {
// New style exception: also test the name property.
required_props.name = name;
}
//We'd like to test that e instanceof the appropriate interface,
//but we can't, because we don't know what window it was created
//in. It might be an instanceof the appropriate interface on some
//unknown other window. TODO: Work around this somehow?
assert(typeof e == "object",
"assert_throws", description,
"${func} threw ${e} with type ${type}, not an object",
{func:func, e:e, type:typeof e});
for (var prop in required_props) {
assert(typeof e == "object" && prop in e && e[prop] == required_props[prop],
"assert_throws", description,
"${func} threw ${e} that is not a DOMException " + code + ": property ${prop} is equal to ${actual}, expected ${expected}",
{func:func, e:e, prop:prop, actual:e[prop], expected:required_props[prop]});
}
}
}
expose(assert_throws, "assert_throws");
function assert_unreached(description) {
assert(false, "assert_unreached", description,
"Reached unreachable code");
}
expose(assert_unreached, "assert_unreached");
function assert_any(assert_func, actual, expected_array)
{
var args = [].slice.call(arguments, 3);
var errors = [];
var passed = false;
forEach(expected_array,
function(expected)
{
try {
assert_func.apply(this, [actual, expected].concat(args));
passed = true;
} catch (e) {
errors.push(e.message);
}
});
if (!passed) {
throw new AssertionError(errors.join("\n\n"));
}
}
expose(assert_any, "assert_any");
/*
* Template code
*
* A template is just a javascript structure. An element is represented as:
*
* [tag_name, {attr_name:attr_value}, child1, child2]
*
* the children can either be strings (which act like text nodes), other templates or
* functions (see below)
*
* A text node is represented as
*
* ["{text}", value]
*
* String values have a simple substitution syntax; ${foo} represents a variable foo.
*
* It is possible to embed logic in templates by using a function in a place where a
* node would usually go. The function must either return part of a template or null.
*
* In cases where a set of nodes are required as output rather than a single node
* with children it is possible to just use a list
* [node1, node2, node3]
*
* Usage:
*
* render(template, substitutions) - take a template and an object mapping
* variable names to parameters and return either a DOM node or a list of DOM nodes
*
* substitute(template, substitutions) - take a template and variable mapping object,
* make the variable substitutions and return the substituted template
*
*/
function is_single_node(template)
{
return typeof template[0] === "string";
}
function substitute(template, substitutions)
{
if (typeof template === "function") {
var replacement = template(substitutions);
if (!replacement) {
return null;
}
return substitute(replacement, substitutions);
}
if (is_single_node(template)) {
return substitute_single(template, substitutions);
}
return filter(map(template, function(x) {
return substitute(x, substitutions);
}), function(x) {return x !== null;});
}
function substitute_single(template, substitutions)
{
var substitution_re = /\$\{([^ }]*)\}/g;
function do_substitution(input) {
var components = input.split(substitution_re);
var rv = [];
for (var i = 0; i < components.length; i += 2) {
rv.push(components[i]);
if (components[i + 1]) {
rv.push(String(substitutions[components[i + 1]]));
}
}
return rv;
}
function substitute_attrs(attrs, rv)
{
rv[1] = {};
for (var name in template[1]) {
if (attrs.hasOwnProperty(name)) {
var new_name = do_substitution(name).join("");
var new_value = do_substitution(attrs[name]).join("");
rv[1][new_name] = new_value;
}
}
}
function substitute_children(children, rv)
{
for (var i = 0; i < children.length; i++) {
if (children[i] instanceof Object) {
var replacement = substitute(children[i], substitutions);
if (replacement !== null) {
if (is_single_node(replacement)) {
rv.push(replacement);
} else {
extend(rv, replacement);
}
}
} else {
extend(rv, do_substitution(String(children[i])));
}
}
return rv;
}
var rv = [];
rv.push(do_substitution(String(template[0])).join(""));
if (template[0] === "{text}") {
substitute_children(template.slice(1), rv);
} else {
substitute_attrs(template[1], rv);
substitute_children(template.slice(2), rv);
}
return rv;
}
/*
* Utility funcions
*/
function assert(expected_true, function_name, description, error, substitutions)
{
if (expected_true !== true) {
var msg = make_message(function_name, description,
error, substitutions);
throw new AssertionError(msg);
}
}
function AssertionError(message)
{
this.message = message;
this.stack = this.get_stack();
}
AssertionError.prototype = Object.create(Error.prototype);
AssertionError.prototype.get_stack = function() {
var stack = new Error().stack;
// IE11 does not initialize 'Error.stack' until the object is thrown.
if (!stack) {
try {
throw new Error();
} catch (e) {
stack = e.stack;
}
}
var lines = stack.split("\n");
// Create a pattern to match stack frames originating within testharness.js. These include the
// script URL, followed by the line/col (e.g., '/resources/testharness.js:120:21').
var re = new RegExp(("-testharness.js") + ":\\d+:\\d+"); // EDITED
// Some browsers include a preamble that specifies the type of the error object. Skip this by
// advancing until we find the first stack frame originating from testharness.js.
var i = 0;
while (!re.test(lines[i]) && i < lines.length) {
i++;
}
// Then skip the top frames originating from testharness.js to begin the stack at the test code.
while (re.test(lines[i]) && i < lines.length) {
i++;
}
// Paranoid check that we didn't skip all frames. If so, return the original stack unmodified.
if (i >= lines.length) {
return stack;
}
return lines.slice(i).join("\n");
}
function make_message(function_name, description, error, substitutions)
{
for (var p in substitutions) {
if (substitutions.hasOwnProperty(p)) {
substitutions[p] = format_value(substitutions[p]);
}
}
var node_form = substitute(["{text}", "${function_name}: ${description}" + error],
merge({function_name:function_name,
description:(description?description + " ":"")},
substitutions));
return node_form.slice(1).join("");
}
function filter(array, callable, thisObj) {
var rv = [];
for (var i = 0; i < array.length; i++) {
if (array.hasOwnProperty(i)) {
var pass = callable.call(thisObj, array[i], i, array);
if (pass) {
rv.push(array[i]);
}
}
}
return rv;
}
function map(array, callable, thisObj)
{
var rv = [];
rv.length = array.length;
for (var i = 0; i < array.length; i++) {
if (array.hasOwnProperty(i)) {
rv[i] = callable.call(thisObj, array[i], i, array);
}
}
return rv;
}
function extend(array, items)
{
Array.prototype.push.apply(array, items);
}
function forEach(array, callback, thisObj)
{
for (var i = 0; i < array.length; i++) {
if (array.hasOwnProperty(i)) {
callback.call(thisObj, array[i], i, array);
}
}
}
function merge(a,b)
{
var rv = {};
var p;
for (p in a) {
rv[p] = a[p];
}
for (p in b) {
rv[p] = b[p];
}
return rv;
}
function expose(object, name)
{
var components = name.split(".");
var target = self; // EDITED
for (var i = 0; i < components.length - 1; i++) {
if (!(components[i] in target)) {
target[components[i]] = {};
}
target = target[components[i]];
}
target[components[components.length - 1]] = object;
}
})();
// vim: set expandtab shiftwidth=4 tabstop=4:

Просмотреть файл

@ -0,0 +1,198 @@
// Emulate W3C testharness.js in the JS shell.
//
// This file loads ./w3c-testharness.js, which consists of code copied from the
// actual W3C testharness.js file (/dom/imptests/testharness.js). But that
// code won't work in the shell without considerable help provided by this
// file.
// *** Hacky versions of DOM builtins *****************************************
(function (self) {
"use strict";
self.self = self;
self.window = self;
// Our stub version of addEventListener never actually fires events.
// This is sufficient for the tests we've copied so far.
self.addEventListener = function (event, callback) {};
let nextId = 1;
let now = 0; // bogus clock used by our stub version of setTimeout
let timeouts = [];
function enqueue(id, action, dt) {
let t = now + dt;
timeouts.push({id, action, t});
timeouts.sort((a, b) => a.t - b.t);
}
self.setTimeout = function (action, dt) {
let id = nextId++;
enqueue(id, action, dt);
return id;
}
self.clearTimeout = function (id) {
timeouts = timeouts.filter(timeout => timeout.id !== id);
}
self.setInterval = function (action, dt) {
let id = nextId++;
function scheduleNext() {
enqueue(id, () => { scheduleNext(); action(); }, dt);
}
scheduleNext();
return id;
}
self.clearInterval = self.clearTimeout;
self.drainTimeoutQueue = function drainTimeoutQueue() {
drainJobQueue();
while (timeouts.length > 0) {
let target = timeouts.shift();
let f = target.action;
let dt = target.t - now;
now = target.t;
f();
drainJobQueue();
}
};
// *** importScripts ******************************************************
// Many wpt tests use this; for sanity's sake we allow loading only a few
// files used by the particular tests we run as jit-tests.
let allowed_scripts = [
"../resources/test-utils.js",
"../resources/rs-utils.js",
"../resources/constructor-ordering.js",
"../resources/recording-streams.js",
"../resources/rs-test-templates.js",
];
self.importScripts = function (url) {
// Don't load the real test harness, as this would clobber our
// carefully constructed fake test harness that doesn't require the DOM.
if (url === "/resources/testharness.js") {
return; // this is fine
}
if (!allowed_scripts.includes(url)) {
throw new Error("can't import script: " + uneval(url));
}
// Load the file relative to the caller's filename.
let stack = new Error().stack.split("\n");
let match = /^\s*[^@]*@(.*):\d+:\d+$/.exec(stack[1]);
let callerFile = match[1];
let dir = callerFile.replace(/[^/\\]*$/, "");
load(dir + url);
};
}(this));
loadRelativeToScript("w3c-testharness.js");
// *** Hand-coded reimplementation of some parts of testharness.js ************
let all_tests = Promise.resolve();
function fail() {
print("fail() was called");
quit(1);
}
function promise_rejects(test, expected, promise) {
return promise.then(fail).catch(function(e) {
assert_throws(expected, function() { throw e });
});
}
function test(fn, description) {
promise_test(fn, description);
}
function promise_test(fn, description) {
let test = {
unreached_func(message) {
return () => { assert_unreached(description); };
},
cleanups: [],
add_cleanup(fn) {
this.cleanups.push(fn);
},
step_func(func, this_obj = this) {
return (...args) => this.step(func, this_obj, ...args);
},
step(func, this_obj, ...args) {
return func.apply(this_obj, args);
},
};
all_tests = all_tests.then(async () => {
print("* " + description);
try {
await fn(test);
print(" passed\n");
} catch (exc) {
print(" failed: " + exc + "\n");
throw exc;
} finally {
for (const cleanup of test.cleanups) {
cleanup();
}
}
});
}
function done() {
let passed;
let problem;
all_tests
.then(() => { passed = true; })
.catch(exc => { passed = false; problem = exc; });
drainTimeoutQueue();
if (passed === undefined) {
throw new Error("test didn't finish");
}
if (!passed) {
throw problem;
}
print("all tests passed");
}
// *** Test runner ********************************************************************************
function load_web_platform_test(path) {
let stabs = [
libdir + "../../../../testing/web-platform/tests/" + path,
libdir + "../../../web-platform/tests/" + path,
];
for (let filename of stabs) {
let code;
try {
code = read(filename);
} catch (exc) {
if (!(exc instanceof Error && /^can't open/.exec(exc.message))) {
throw exc;
}
continue;
}
// Successfully read the file! Now evaluate the code.
return evaluate(code, {fileName: filename, lineNumber: 1});
}
throw new Error(`can't open ${uneval(path)}: tried ${uneval(stabs)}`);
}

Просмотреть файл

@ -0,0 +1,2 @@
load(libdir + "web-platform-testharness.js");
load_web_platform_test("streams/readable-streams/bad-strategies.js");

Просмотреть файл

@ -0,0 +1,2 @@
load(libdir + "web-platform-testharness.js");
load_web_platform_test("streams/readable-streams/brand-checks.js");

Просмотреть файл

@ -0,0 +1,2 @@
load(libdir + "web-platform-testharness.js");
load_web_platform_test("streams/readable-streams/cancel.js");

Просмотреть файл

@ -0,0 +1,2 @@
load(libdir + "web-platform-testharness.js");
load_web_platform_test("streams/readable-streams/count-queuing-strategy-integration.js");

Просмотреть файл

@ -0,0 +1,2 @@
load(libdir + "web-platform-testharness.js");
load_web_platform_test("streams/readable-streams/default-reader.js");

Просмотреть файл

@ -0,0 +1,2 @@
load(libdir + "web-platform-testharness.js");
load_web_platform_test("streams/readable-streams/floating-point-total-queue-size.js");

Просмотреть файл

@ -0,0 +1,2 @@
load(libdir + "web-platform-testharness.js");
load_web_platform_test("streams/readable-streams/patched-global.js");

Просмотреть файл

@ -0,0 +1,2 @@
load(libdir + "web-platform-testharness.js");
load_web_platform_test("streams/readable-streams/tee.js");

Просмотреть файл

@ -153,6 +153,11 @@ case $cmd in
${TOPSRCDIR}/testing/mozbase \
${tgtpath}/testing/
${MKDIR} -p ${tgtpath}/testing/web-platform/tests
cp -pPR \
${TOPSRCDIR}/testing/web-platform/tests/streams \
${tgtpath}/testing/web-platform/tests/
${MKDIR} -p ${tgtpath}/taskcluster/taskgraph
cp -pPR \
${TOPSRCDIR}/taskcluster/moz.build \