mirror of
https://github.com/tc39/test262.git
synced 2025-05-04 15:00:42 +02:00
* [javascriptcore-test262-automation] changes from git@github.com:WebKit/webkit.git at sha 949e26452cfa153a7f4afe593da97e2fe9e1b706 on Tue Jul 03 2018 14:35:15 GMT-0400 (Eastern Daylight Time)
337 lines
9.0 KiB
JavaScript
337 lines
9.0 KiB
JavaScript
var errorMessage;
|
|
var self = this;
|
|
|
|
self.testRunner = {
|
|
neverInlineFunction: neverInlineFunction,
|
|
numberOfDFGCompiles: numberOfDFGCompiles
|
|
};
|
|
|
|
var silentMode = true;
|
|
var throwOnFirstFail = true;
|
|
var silentTestPass, didPassSomeTestsSilently, didFailSomeTests, successfullyParsed;
|
|
silentTestPass = false;
|
|
didPassSomeTestsSilenty = false;
|
|
didFailSomeTests = false;
|
|
|
|
function description(msg)
|
|
{
|
|
if (silentMode)
|
|
return;
|
|
print(msg);
|
|
print("\nOn success, you will see a series of \"PASS\" messages, followed by \"TEST COMPLETE\".\n");
|
|
print();
|
|
}
|
|
|
|
function debug(msg)
|
|
{
|
|
if (silentMode)
|
|
return;
|
|
print(msg);
|
|
}
|
|
|
|
function escapeString(text)
|
|
{
|
|
return text.replace(/\0/g, "");
|
|
}
|
|
|
|
function testPassed(msg)
|
|
{
|
|
if (silentTestPass)
|
|
didPassSomeTestsSilently = true;
|
|
else if (silentMode)
|
|
return;
|
|
else
|
|
print("PASS", escapeString(msg));
|
|
}
|
|
|
|
function testFailed(msg)
|
|
{
|
|
didFailSomeTests = true;
|
|
if (!silentMode)
|
|
print("FAIL", escapeString(msg));
|
|
if (throwOnFirstFail)
|
|
throw new Error(escapeString(msg));
|
|
}
|
|
|
|
function areNumbersEqual(_actual, _expected)
|
|
{
|
|
if (_expected === 0)
|
|
return _actual === _expected && (1/_actual) === (1/_expected);
|
|
if (_actual === _expected)
|
|
return true;
|
|
if (typeof(_expected) == "number" && isNaN(_expected))
|
|
return typeof(_actual) == "number" && isNaN(_actual);
|
|
return false;
|
|
}
|
|
|
|
function areArraysEqual(_a, _b)
|
|
{
|
|
try {
|
|
if (_a.length !== _b.length)
|
|
return false;
|
|
for (var i = 0; i < _a.length; i++)
|
|
if (!areNumbersEqual(_a[i], _b[i]))
|
|
return false;
|
|
} catch (ex) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function isMinusZero(n)
|
|
{
|
|
// the only way to tell 0 from -0 in JS is the fact that 1/-0 is
|
|
// -Infinity instead of Infinity
|
|
return n === 0 && 1/n < 0;
|
|
}
|
|
|
|
function isTypedArray(array)
|
|
{
|
|
return array instanceof Int8Array
|
|
|| array instanceof Int16Array
|
|
|| array instanceof Int32Array
|
|
|| array instanceof Uint8Array
|
|
|| array instanceof Uint8ClampedArray
|
|
|| array instanceof Uint16Array
|
|
|| array instanceof Uint32Array
|
|
|| array instanceof Float32Array
|
|
|| array instanceof Float64Array;
|
|
}
|
|
|
|
function isResultCorrect(_actual, _expected)
|
|
{
|
|
if (areNumbersEqual(_actual, _expected))
|
|
return true;
|
|
if (_expected
|
|
&& (Object.prototype.toString.call(_expected) ==
|
|
Object.prototype.toString.call([])
|
|
|| isTypedArray(_expected)))
|
|
return areArraysEqual(_actual, _expected);
|
|
return false;
|
|
}
|
|
|
|
function stringify(v)
|
|
{
|
|
if (v === 0 && 1/v < 0)
|
|
return "-0";
|
|
else if (isTypedArray(v))
|
|
return v.__proto__.constructor.name + ":[" + Array.prototype.join.call(v, ",") + "]";
|
|
else
|
|
return "" + v;
|
|
}
|
|
|
|
function shouldBe(_a, _b, _quiet)
|
|
{
|
|
if ((typeof _a != "function" && typeof _a != "string") || (typeof _b != "function" && typeof _b != "string"))
|
|
debug("WARN: shouldBe() expects function or string arguments");
|
|
var _exception;
|
|
var _av;
|
|
try {
|
|
_av = (typeof _a == "function" ? _a() : eval(_a));
|
|
} catch (e) {
|
|
_exception = e;
|
|
}
|
|
var _bv = (typeof _b == "function" ? _b() : eval(_b));
|
|
|
|
if (_exception)
|
|
testFailed(_a + " should be " + stringify(_bv) + ". Threw exception " + _exception);
|
|
else if (isResultCorrect(_av, _bv)) {
|
|
if (!_quiet) {
|
|
testPassed(_a + " is " + (typeof _b == "function" ? _bv : _b));
|
|
}
|
|
} else if (typeof(_av) == typeof(_bv))
|
|
testFailed(_a + " should be " + stringify(_bv) + ". Was " + stringify(_av) + ".");
|
|
else
|
|
testFailed(_a + " should be " + stringify(_bv) + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
|
|
}
|
|
|
|
function dfgShouldBe(theFunction, _a, _b)
|
|
{
|
|
if (typeof theFunction != "function" || typeof _a != "string" || typeof _b != "string")
|
|
debug("WARN: dfgShouldBe() expects a function and two strings");
|
|
noInline(theFunction);
|
|
var exception;
|
|
var values = [];
|
|
|
|
// Defend against tests that muck with numeric properties on array.prototype.
|
|
values.__proto__ = null;
|
|
values.push = Array.prototype.push;
|
|
|
|
try {
|
|
while (!dfgCompiled({f:theFunction}))
|
|
values.push(eval(_a));
|
|
values.push(eval(_a));
|
|
} catch (e) {
|
|
exception = e;
|
|
}
|
|
|
|
var _bv = eval(_b);
|
|
if (exception)
|
|
testFailed(_a + " should be " + stringify(_bv) + ". On iteration " + (values.length + 1) + ", threw exception " + exception);
|
|
else {
|
|
var allPassed = true;
|
|
for (var i = 0; i < values.length; ++i) {
|
|
var _av = values[i];
|
|
if (isResultCorrect(_av, _bv))
|
|
continue;
|
|
if (typeof(_av) == typeof(_bv))
|
|
testFailed(_a + " should be " + stringify(_bv) + ". On iteration " + (i + 1) + ", was " + stringify(_av) + ".");
|
|
else
|
|
testFailed(_a + " should be " + stringify(_bv) + " (of type " + typeof _bv + "). On iteration " + (i + 1) + ", was " + _av + " (of type " + typeof _av + ").");
|
|
allPassed = false;
|
|
}
|
|
if (allPassed)
|
|
testPassed(_a + " is " + _b + " on all iterations including after DFG tier-up.");
|
|
}
|
|
|
|
return values.length;
|
|
}
|
|
|
|
function shouldBeType(_a, _type) {
|
|
var exception;
|
|
var _av;
|
|
try {
|
|
_av = eval(_a);
|
|
} catch (e) {
|
|
exception = e;
|
|
}
|
|
|
|
var _typev = eval(_type);
|
|
if (_av instanceof _typev) {
|
|
testPassed(_a + " is an instance of " + _type);
|
|
} else {
|
|
testFailed(_a + " is not an instance of " + _type);
|
|
}
|
|
}
|
|
|
|
function shouldBeTrue(_a) { shouldBe(_a, "true"); }
|
|
function shouldBeFalse(_a) { shouldBe(_a, "false"); }
|
|
function shouldBeNaN(_a) { shouldBe(_a, "NaN"); }
|
|
function shouldBeNull(_a) { shouldBe(_a, "null"); }
|
|
|
|
function shouldBeEqualToString(a, b)
|
|
{
|
|
if (typeof a !== "string" || typeof b !== "string")
|
|
debug("WARN: shouldBeEqualToString() expects string arguments");
|
|
var unevaledString = JSON.stringify(b);
|
|
shouldBe(a, unevaledString);
|
|
}
|
|
|
|
function shouldBeUndefined(_a)
|
|
{
|
|
var exception;
|
|
var _av;
|
|
try {
|
|
_av = eval(_a);
|
|
} catch (e) {
|
|
exception = e;
|
|
}
|
|
|
|
if (exception)
|
|
testFailed(_a + " should be undefined. Threw exception " + exception);
|
|
else if (typeof _av == "undefined")
|
|
testPassed(_a + " is undefined.");
|
|
else
|
|
testFailed(_a + " should be undefined. Was " + _av);
|
|
}
|
|
|
|
function shouldNotThrow(_a, _message) {
|
|
try {
|
|
typeof _a == "function" ? _a() : eval(_a);
|
|
testPassed((_message ? _message : _a) + " did not throw exception.");
|
|
} catch (e) {
|
|
testFailed((_message ? _message : _a) + " should not throw exception. Threw exception " + e + ".");
|
|
}
|
|
}
|
|
|
|
function shouldThrow(_a, _e, _message)
|
|
{
|
|
var _exception;
|
|
var _av;
|
|
try {
|
|
_av = typeof _a == "function" ? _a() : eval(_a);
|
|
} catch (e) {
|
|
_exception = e;
|
|
}
|
|
|
|
var _ev;
|
|
if (_e)
|
|
_ev = eval(_e);
|
|
|
|
if (_exception) {
|
|
if (typeof _e == "undefined" || _exception == _ev)
|
|
testPassed((_message ? _message : _a) + " threw exception " + _exception + ".");
|
|
else
|
|
testFailed((_message ? _message : _a) + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + _exception + ".");
|
|
} else if (typeof _av == "undefined")
|
|
testFailed((_message ? _message : _a) + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined.");
|
|
else
|
|
testFailed((_message ? _message : _a) + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + ".");
|
|
}
|
|
|
|
function isSuccessfullyParsed()
|
|
{
|
|
// FIXME: Remove this and only report unexpected syntax errors.
|
|
if (!errorMessage)
|
|
successfullyParsed = true;
|
|
shouldBeTrue("successfullyParsed");
|
|
if (silentTestPass && didPassSomeTestsSilently)
|
|
debug("Passed some tests silently.");
|
|
if (silentTestPass && didFailSomeTests)
|
|
debug("Some tests failed.");
|
|
debug("\nTEST COMPLETE\n");
|
|
}
|
|
|
|
|
|
function dfgCompiled(argument)
|
|
{
|
|
var numberOfCompiles = "compiles" in argument ? argument.compiles : 1;
|
|
|
|
if (!("f" in argument))
|
|
throw new Error("dfgCompiled called with invalid argument.");
|
|
|
|
if (argument.f instanceof Array) {
|
|
for (var i = 0; i < argument.f.length; ++i) {
|
|
if (testRunner.numberOfDFGCompiles(argument.f[i]) < numberOfCompiles)
|
|
return false;
|
|
}
|
|
} else {
|
|
if (testRunner.numberOfDFGCompiles(argument.f) < numberOfCompiles)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function dfgIncrement(argument)
|
|
{
|
|
if (!self.testRunner)
|
|
return argument.i;
|
|
|
|
if (argument.i < argument.n)
|
|
return argument.i;
|
|
|
|
if (didFailSomeTests)
|
|
return argument.i;
|
|
|
|
if (!dfgCompiled(argument))
|
|
return "start" in argument ? argument.start : 0;
|
|
|
|
return argument.i;
|
|
}
|
|
|
|
function noInline(theFunction)
|
|
{
|
|
if (!self.testRunner)
|
|
return;
|
|
|
|
testRunner.neverInlineFunction(theFunction);
|
|
}
|
|
|
|
function finishJSTest()
|
|
{
|
|
isSuccessfullyParsed();
|
|
if (didFailSomeTests)
|
|
throw new Error("Some Tests Failed");
|
|
}
|