// Copyright 2017 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. // Stripped-down version of test/mjsunit/mjsunit.js that only contains // assertEquals.S var assertEquals; (function () { var ObjectPrototypeToString = Object.prototype.toString; var NumberPrototypeValueOf = Number.prototype.valueOf; var BooleanPrototypeValueOf = Boolean.prototype.valueOf; var StringPrototypeValueOf = String.prototype.valueOf; var DatePrototypeValueOf = Date.prototype.valueOf; var RegExpPrototypeToString = RegExp.prototype.toString; var ArrayPrototypeForEach = Array.prototype.forEach; var ArrayPrototypeJoin = Array.prototype.join; var ArrayPrototypeMap = Array.prototype.map; var ArrayPrototypePush = Array.prototype.push; var BigIntPrototypeValueOf; try { BigIntPrototypeValueOf = BigInt.prototype.valueOf; } catch(e) {} function classOf(object) { var string = ObjectPrototypeToString.call(object); return string.substring(8, string.length - 1); } function ValueOf(value) { switch (classOf(value)) { case "Number": return NumberPrototypeValueOf.call(value); case "BigInt": return BigIntPrototypeValueOf.call(value); case "String": return StringPrototypeValueOf.call(value); case "Boolean": return BooleanPrototypeValueOf.call(value); case "Date": return DatePrototypeValueOf.call(value); default: return value; } } function PrettyPrint(value) { switch (typeof value) { case "string": return JSON.stringify(value); case "bigint": return String(value) + "n"; case "number": if (value === 0 && (1 / value) < 0) return "-0"; // FALLTHROUGH. case "boolean": case "undefined": case "function": case "symbol": return String(value); case "object": if (value === null) return "null"; var objectClass = classOf(value); switch (objectClass) { case "Number": case "BigInt": case "String": case "Boolean": case "Date": return objectClass + "(" + PrettyPrint(ValueOf(value)) + ")"; case "RegExp": return RegExpPrototypeToString.call(value); case "Array": var mapped = ArrayPrototypeMap.call(value, PrettyPrintArrayElement); var joined = ArrayPrototypeJoin.call(mapped, ","); return "[" + joined + "]"; case "Uint8Array": case "Int8Array": case "Int16Array": case "Uint16Array": case "Uint32Array": case "Int32Array": case "Float32Array": case "Float64Array": var joined = ArrayPrototypeJoin.call(value, ","); return objectClass + "([" + joined + "])"; case "Object": break; default: return objectClass + "()"; } var name = value.constructor.name; if (name) return name + "()"; return "Object()"; default: return "-- unknown value --"; } } function PrettyPrintArrayElement(value, index, array) { if (value === undefined && !(index in array)) return ""; return PrettyPrint(value); } failWithMessage = function failWithMessage(message) { throw new Error(message); } function formatFailureText(expectedText, found, name_opt) { var message = "Fail" + "ure"; if (name_opt) { message += " (" + name_opt + ")"; } var foundText = PrettyPrint(found); if (expectedText.length <= 40 && foundText.length <= 40) { message += ": expected <" + expectedText + "> found <" + foundText + ">"; } else { message += ":\nexpected:\n" + expectedText + "\nfound:\n" + foundText; } return message; } function fail(expectedText, found, name_opt) { return failWithMessage(formatFailureText(expectedText, found, name_opt)); } function deepObjectEquals(a, b) { var aProps = Object.keys(a); aProps.sort(); var bProps = Object.keys(b); bProps.sort(); if (!deepEquals(aProps, bProps)) { return false; } for (var i = 0; i < aProps.length; i++) { if (!deepEquals(a[aProps[i]], b[aProps[i]])) { return false; } } return true; } function deepEquals(a, b) { if (a === b) { // Check for -0. if (a === 0) return (1 / a) === (1 / b); return true; } if (typeof a !== typeof b) return false; if (typeof a === "number") return isNaN(a) && isNaN(b); if (typeof a !== "object" && typeof a !== "function") return false; // Neither a nor b is primitive. var objectClass = classOf(a); if (objectClass !== classOf(b)) return false; if (objectClass === "RegExp") { // For RegExp, just compare pattern and flags using its toString. return RegExpPrototypeToString.call(a) === RegExpPrototypeToString.call(b); } // Functions are only identical to themselves. if (objectClass === "Function") return false; if (objectClass === "Array") { var elementCount = 0; if (a.length !== b.length) { return false; } for (var i = 0; i < a.length; i++) { if (!deepEquals(a[i], b[i])) return false; } return true; } if (objectClass === "String" || objectClass === "Number" || objectClass === "BigInt" || objectClass === "Boolean" || objectClass === "Date") { if (ValueOf(a) !== ValueOf(b)) return false; } return deepObjectEquals(a, b); } assertEquals = function assertEquals(expected, found, name_opt) { if (!deepEquals(found, expected)) { fail(PrettyPrint(expected), found, name_opt); } }; })();