// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Implementations of some functions from testharness.js // See https://github.com/web-platform-tests/wpt/blob/master/resources/testharness.js // Licensed as follows: // // 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 const failures = []; let lastPromise = Promise.resolve(); function test(func, description) { let maybeErr; try { func({unreached_func: unreached_func}); } catch(e) { maybeErr = e; } if (typeof maybeErr !== 'undefined') { console.log(`${description}: FAIL. ${maybeErr}`); failures.push(description); } else { console.log(`${description}: PASS.`); } } function promise_test(func, description) { lastPromise = lastPromise.then(func) .then(_ => { console.log(`${description}: PASS.`); }) .catch(err => { console.log(`${description}: FAIL. ${err}`); failures.push(description); }); } const assert_true = assertEquals.bind(null, true); const assert_false = assertEquals.bind(null, 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(expected, found, description) { if (typeof found != typeof expected) { assert_true(false, "assert_equals", description, "expected (" + typeof expected + ") ${expected} but got (" + typeof found + ") ${found}", {expected:expected, found:found}); } assert_true(same_value(found, expected), "assert_equals", description, "expected ${expected} but got ${found}", {expected:expected, found:found}); } function assert_not_equals(expected, found, description) { assert_true(!same_value(found, expected), "assert_not_equals", description, "got disallowed value ${found}", {found:found}); } function assert_array_equals(actual, expected, description) { assert_true( typeof actual === 'object' && actual !== null && 'length' in actual, 'assert_array_equals', description, 'value is ${actual}, expected array', {actual: actual}); assert_true( actual.length === expected.length, 'assert_array_equals', description, 'lengths differ, expected ${expected} got ${actual}', {expected: expected.length, actual: actual.length}); for (let i = 0; i < actual.length; i++) { assert_true( 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_true( 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]}); } } function unreached_func(msg) { return function trap() { assert_unreached(msg); }; } function assert_unreached(description) { throw new Error(`unreachable:\n${description}`); } function format_value(s) { // TODO try { return String(s); } catch(e) { return `<String(e) for type ${typeof(e)} threw>`; } } function promise_rejects(test, expected, promise, description) { return promise .then(() => assert_unreached('Should have rejected: ' + description)) .catch(function(e) { assert_throws(expected, function() { throw e; }, description); }); } function assert_class_string(object, class_string, description) { assert_equals( {}.toString.call(object), '[object ' + class_string + ']', description); } function assert_throws(code, func, description) { try { func(); } catch (e) { assert_true(e.name === code.name, "expected exception " + code.name + ", got " + e.name); return; } assert_true(false, "expected exception " + code.name + ", no exception thrown"); } function setup(func) { // TODO need to do anything fancier here? func(); }