blob: 29d07f263a41b9cf6b70bae5e821d9d58bfabe94 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 the V8 project authors. All rights reserved.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005var global = this;
6
7var funs = {
8 Object: [ Object ],
9 Function: [ Function ],
10 Array: [ Array ],
11 String: [ String ],
12 Boolean: [ Boolean ],
13 Number: [ Number ],
14 Date: [ Date ],
15 RegExp: [ RegExp ],
16 Error: [ Error, TypeError, RangeError, SyntaxError, ReferenceError,
17 EvalError, URIError ]
18}
19for (f in funs) {
20 for (i in funs[f]) {
21 assertEquals("[object " + f + "]",
22 Object.prototype.toString.call(new funs[f][i]),
23 funs[f][i]);
24 assertEquals("[object Function]",
25 Object.prototype.toString.call(funs[f][i]),
26 funs[f][i]);
27 }
28}
29
30function testToStringTag(className) {
31 // Using builtin toStringTags
32 var obj = {};
33 obj[Symbol.toStringTag] = className;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000034 assertEquals("[object " + className + "]",
Emily Bernierd0a1eb72015-03-24 16:35:39 -040035 Object.prototype.toString.call(obj));
36
37 // Getter throws
38 obj = {};
39 Object.defineProperty(obj, Symbol.toStringTag, {
40 get: function() { throw className; }
41 });
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000042 assertThrowsEquals(function() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040043 Object.prototype.toString.call(obj);
44 }, className);
45
46 // Getter does not throw
47 obj = {};
48 Object.defineProperty(obj, Symbol.toStringTag, {
49 get: function() { return className; }
50 });
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000051 assertEquals("[object " + className + "]",
Emily Bernierd0a1eb72015-03-24 16:35:39 -040052 Object.prototype.toString.call(obj));
53
54 // Custom, non-builtin toStringTags
55 obj = {};
56 obj[Symbol.toStringTag] = "X" + className;
57 assertEquals("[object X" + className + "]",
58 Object.prototype.toString.call(obj));
59
60 // With getter
61 obj = {};
62 Object.defineProperty(obj, Symbol.toStringTag, {
63 get: function() { return "X" + className; }
64 });
65 assertEquals("[object X" + className + "]",
66 Object.prototype.toString.call(obj));
67
68 // Undefined toStringTag should return [object className]
69 var obj = className === "Arguments" ?
70 (function() { return arguments; })() : new global[className];
71 obj[Symbol.toStringTag] = undefined;
72 assertEquals("[object " + className + "]",
73 Object.prototype.toString.call(obj));
74
75 // With getter
76 var obj = className === "Arguments" ?
77 (function() { return arguments; })() : new global[className];
78 Object.defineProperty(obj, Symbol.toStringTag, {
79 get: function() { return undefined; }
80 });
81 assertEquals("[object " + className + "]",
82 Object.prototype.toString.call(obj));
83}
84
85[
86 "Arguments",
87 "Array",
88 "Boolean",
89 "Date",
90 "Error",
91 "Function",
92 "Number",
93 "RegExp",
94 "String"
95].forEach(testToStringTag);
96
97function testToStringTagNonString(value) {
98 var obj = {};
99 obj[Symbol.toStringTag] = value;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000100 assertEquals("[object Object]", Object.prototype.toString.call(obj));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400101
102 // With getter
103 obj = {};
104 Object.defineProperty(obj, Symbol.toStringTag, {
105 get: function() { return value; }
106 });
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000107 assertEquals("[object Object]", Object.prototype.toString.call(obj));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400108}
109
110[
111 null,
112 function() {},
113 [],
114 {},
115 /regexp/,
116 42,
117 Symbol("sym"),
118 new Date(),
119 (function() { return arguments; })(),
120 true,
121 new Error("oops"),
122 new String("str")
123].forEach(testToStringTagNonString);
124
125function testObjectToStringPropertyDesc() {
126 var desc = Object.getOwnPropertyDescriptor(Object.prototype, "toString");
127 assertTrue(desc.writable);
128 assertFalse(desc.enumerable);
129 assertTrue(desc.configurable);
130}
131testObjectToStringPropertyDesc();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000132
133function testObjectToStringOwnNonStringValue() {
134 var obj = Object.defineProperty({}, Symbol.toStringTag, { value: 1 });
135 assertEquals("[object Object]", ({}).toString.call(obj));
136}
137testObjectToStringOwnNonStringValue();
138
139
140// Proxies
141
142function assertTag(tag, obj) {
143 assertEquals("[object " + tag + "]", Object.prototype.toString.call(obj));
144}
145
146assertTag("Object", new Proxy({}, {}));
147assertTag("Array", new Proxy([], {}));
148assertTag("Function", new Proxy(() => 42, {}));
149assertTag("Foo", new Proxy(() => 42, {get() {return "Foo"}}));
150assertTag("Function", new Proxy(() => 42, {get() {return 666}}));
151
152revocable = Proxy.revocable([], {});
153revocable.revoke();
154assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError);
155
156handler = {};
157revocable = Proxy.revocable([], handler);
158handler.get = () => revocable.revoke();
159assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError);