blob: 4d6090faf128d1f200da99b5320039c4bde4ab74 [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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005// Flags: --harmony-tostring --harmony-proxies
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006
7var global = this;
8
9var funs = {
10 Object: [ Object ],
11 Function: [ Function ],
12 Array: [ Array ],
13 String: [ String ],
14 Boolean: [ Boolean ],
15 Number: [ Number ],
16 Date: [ Date ],
17 RegExp: [ RegExp ],
18 Error: [ Error, TypeError, RangeError, SyntaxError, ReferenceError,
19 EvalError, URIError ]
20}
21for (f in funs) {
22 for (i in funs[f]) {
23 assertEquals("[object " + f + "]",
24 Object.prototype.toString.call(new funs[f][i]),
25 funs[f][i]);
26 assertEquals("[object Function]",
27 Object.prototype.toString.call(funs[f][i]),
28 funs[f][i]);
29 }
30}
31
32function testToStringTag(className) {
33 // Using builtin toStringTags
34 var obj = {};
35 obj[Symbol.toStringTag] = className;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000036 assertEquals("[object " + className + "]",
Emily Bernierd0a1eb72015-03-24 16:35:39 -040037 Object.prototype.toString.call(obj));
38
39 // Getter throws
40 obj = {};
41 Object.defineProperty(obj, Symbol.toStringTag, {
42 get: function() { throw className; }
43 });
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044 assertThrowsEquals(function() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040045 Object.prototype.toString.call(obj);
46 }, className);
47
48 // Getter does not throw
49 obj = {};
50 Object.defineProperty(obj, Symbol.toStringTag, {
51 get: function() { return className; }
52 });
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000053 assertEquals("[object " + className + "]",
Emily Bernierd0a1eb72015-03-24 16:35:39 -040054 Object.prototype.toString.call(obj));
55
56 // Custom, non-builtin toStringTags
57 obj = {};
58 obj[Symbol.toStringTag] = "X" + className;
59 assertEquals("[object X" + className + "]",
60 Object.prototype.toString.call(obj));
61
62 // With getter
63 obj = {};
64 Object.defineProperty(obj, Symbol.toStringTag, {
65 get: function() { return "X" + className; }
66 });
67 assertEquals("[object X" + className + "]",
68 Object.prototype.toString.call(obj));
69
70 // Undefined toStringTag should return [object className]
71 var obj = className === "Arguments" ?
72 (function() { return arguments; })() : new global[className];
73 obj[Symbol.toStringTag] = undefined;
74 assertEquals("[object " + className + "]",
75 Object.prototype.toString.call(obj));
76
77 // With getter
78 var obj = className === "Arguments" ?
79 (function() { return arguments; })() : new global[className];
80 Object.defineProperty(obj, Symbol.toStringTag, {
81 get: function() { return undefined; }
82 });
83 assertEquals("[object " + className + "]",
84 Object.prototype.toString.call(obj));
85}
86
87[
88 "Arguments",
89 "Array",
90 "Boolean",
91 "Date",
92 "Error",
93 "Function",
94 "Number",
95 "RegExp",
96 "String"
97].forEach(testToStringTag);
98
99function testToStringTagNonString(value) {
100 var obj = {};
101 obj[Symbol.toStringTag] = value;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000102 assertEquals("[object Object]", Object.prototype.toString.call(obj));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400103
104 // With getter
105 obj = {};
106 Object.defineProperty(obj, Symbol.toStringTag, {
107 get: function() { return value; }
108 });
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000109 assertEquals("[object Object]", Object.prototype.toString.call(obj));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400110}
111
112[
113 null,
114 function() {},
115 [],
116 {},
117 /regexp/,
118 42,
119 Symbol("sym"),
120 new Date(),
121 (function() { return arguments; })(),
122 true,
123 new Error("oops"),
124 new String("str")
125].forEach(testToStringTagNonString);
126
127function testObjectToStringPropertyDesc() {
128 var desc = Object.getOwnPropertyDescriptor(Object.prototype, "toString");
129 assertTrue(desc.writable);
130 assertFalse(desc.enumerable);
131 assertTrue(desc.configurable);
132}
133testObjectToStringPropertyDesc();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000134
135function testObjectToStringOwnNonStringValue() {
136 var obj = Object.defineProperty({}, Symbol.toStringTag, { value: 1 });
137 assertEquals("[object Object]", ({}).toString.call(obj));
138}
139testObjectToStringOwnNonStringValue();
140
141
142// Proxies
143
144function assertTag(tag, obj) {
145 assertEquals("[object " + tag + "]", Object.prototype.toString.call(obj));
146}
147
148assertTag("Object", new Proxy({}, {}));
149assertTag("Array", new Proxy([], {}));
150assertTag("Function", new Proxy(() => 42, {}));
151assertTag("Foo", new Proxy(() => 42, {get() {return "Foo"}}));
152assertTag("Function", new Proxy(() => 42, {get() {return 666}}));
153
154revocable = Proxy.revocable([], {});
155revocable.revoke();
156assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError);
157
158handler = {};
159revocable = Proxy.revocable([], handler);
160handler.get = () => revocable.revoke();
161assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError);