| // Check all the algorithms that call ToPrimitive. Confirm that they're passing |
| // the correct hint, per spec. |
| |
| var STRING = "xyzzy"; |
| var NUMBER = 42; |
| |
| function assertCallsToPrimitive(f, expectedHint, expectedResult) { |
| var hint = undefined; |
| var testObj = { |
| [Symbol.toPrimitive](h) { |
| assertEq(hint, undefined); |
| hint = h; |
| return h === "number" ? NUMBER : STRING; |
| } |
| }; |
| var result = f(testObj); |
| assertEq(hint, expectedHint, String(f)); |
| assertEq(result, expectedResult, String(f)); |
| } |
| |
| // ToNumber |
| assertCallsToPrimitive(Number, "number", NUMBER); |
| |
| // ToString |
| assertCallsToPrimitive(String, "string", STRING); |
| |
| // ToPropertyKey |
| var obj = {[STRING]: "pass"}; |
| assertCallsToPrimitive(key => obj[key], "string", "pass"); |
| |
| // Abstract Relational Comparison |
| assertCallsToPrimitive(x => x >= 42, "number", true); |
| assertCallsToPrimitive(x => x > "42", "number", false); |
| |
| // Abstract Equality Comparison |
| assertCallsToPrimitive(x => x != STRING, "default", false); |
| assertCallsToPrimitive(x => STRING == x, "default", true); |
| assertCallsToPrimitive(x => x == NUMBER, "default", false); |
| assertCallsToPrimitive(x => NUMBER != x, "default", true); |
| |
| // Addition |
| assertCallsToPrimitive(x => 1 + x, "default", "1" + STRING); |
| assertCallsToPrimitive(x => "" + x, "default", STRING); |
| |
| // Date constructor |
| assertCallsToPrimitive(x => (new Date(x)).valueOf(), "default", Number(STRING)); |
| |
| // Date.prototype.toJSON |
| var expected = "a suffusion of yellow"; |
| function testJSON(x) { |
| x.toJSON = Date.prototype.toJSON; |
| x.toISOString = function () { return expected; }; |
| return JSON.stringify(x); |
| } |
| assertCallsToPrimitive(testJSON, "number", JSON.stringify(expected)); |
| |
| reportCompare(0, 0); |