1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
// ES6 20.3.4.45 Date.prototype[@@toPrimitive](hint)
// The toPrimitive method throws if the this value isn't an object.
var toPrimitive = Date.prototype[Symbol.toPrimitive];
assertThrowsInstanceOf(() => toPrimitive.call(undefined, "default"), TypeError);
assertThrowsInstanceOf(() => toPrimitive.call(3, "default"), TypeError);
// It doesn't have to be a Date object, though.
var obj = {
toString() { return "str"; },
valueOf() { return "val"; }
};
assertEq(toPrimitive.call(obj, "number"), "val");
assertEq(toPrimitive.call(obj, "string"), "str");
assertEq(toPrimitive.call(obj, "default"), "str");
// It throws if the hint argument is missing or not one of the three allowed values.
assertThrowsInstanceOf(() => toPrimitive.call(obj), TypeError);
assertThrowsInstanceOf(() => toPrimitive.call(obj, undefined), TypeError);
assertThrowsInstanceOf(() => toPrimitive.call(obj, "boolean"), TypeError);
assertThrowsInstanceOf(() => toPrimitive.call(obj, ["number"]), TypeError);
assertThrowsInstanceOf(() => toPrimitive.call(obj, {toString() { throw "FAIL"; }}), TypeError);
// The next few tests cover the OrdinaryToPrimitive algorithm, specified in
// ES6 7.1.1 ToPrimitive(input [, PreferredType]).
// Date.prototype.toString or .valueOf can be overridden.
var dateobj = new Date();
Date.prototype.toString = function () {
assertEq(this, dateobj);
return 14;
};
Date.prototype.valueOf = function () {
return "92";
};
assertEq(dateobj[Symbol.toPrimitive]("number"), "92");
assertEq(dateobj[Symbol.toPrimitive]("string"), 14);
assertEq(dateobj[Symbol.toPrimitive]("default"), 14);
assertEq(dateobj == 14, true); // equality comparison: passes "default"
// If this.toString is a non-callable value, this.valueOf is called instead.
Date.prototype.toString = {};
assertEq(dateobj[Symbol.toPrimitive]("string"), "92");
assertEq(dateobj[Symbol.toPrimitive]("default"), "92");
// And vice versa.
Date.prototype.toString = function () { return 15; };
Date.prototype.valueOf = "ponies";
assertEq(dateobj[Symbol.toPrimitive]("number"), 15);
// If neither is callable, it throws a TypeError.
Date.prototype.toString = "ponies";
assertThrowsInstanceOf(() => dateobj[Symbol.toPrimitive]("default"), TypeError);
// Surface features.
assertEq(toPrimitive.name, "[Symbol.toPrimitive]");
var desc = Object.getOwnPropertyDescriptor(Date.prototype, Symbol.toPrimitive);
assertEq(desc.configurable, true);
assertEq(desc.enumerable, false);
assertEq(desc.writable, false);
reportCompare(0, 0);
|