blob: 141070db9c6a130b3c2fbc0c27c10aa2ab115b7a [file] [log] [blame]
Ben Murdoch097c5b22016-05-18 11:27:45 +01001// Copyright 2016 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ben Murdochda12d292016-06-02 14:46:10 +01005// Flags: --harmony-object-values-entries
Ben Murdoch097c5b22016-05-18 11:27:45 +01006// Flags: --allow-natives-syntax
7
8function TestMeta() {
9 assertEquals(1, Object.values.length);
10 assertEquals(Function.prototype, Object.getPrototypeOf(Object.values));
11 assertEquals("values", Object.values.name);
12
13 var descriptor = Object.getOwnPropertyDescriptor(Object, "values");
14 assertTrue(descriptor.writable);
15 assertFalse(descriptor.enumerable);
16 assertTrue(descriptor.configurable);
17
18 assertThrows(() => new Object.values({}), TypeError);
19}
20TestMeta();
21
22
23function TestBasic() {
24 var x = 16;
25 var O = {
26 d: 1,
27 c: 3,
28 [Symbol.iterator]: void 0,
29 0: 123,
30 1000: 456,
31 [x * x]: "ducks",
32 [`0x${(x * x).toString(16)}`]: "quack"
33 };
34 O.a = 2;
35 O.b = 4;
36 Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN });
37 assertEquals([123, "ducks", 456, 1, 3, "quack", 2, 4], Object.values(O));
38 assertEquals(Object.values(O), Object.keys(O).map(key => O[key]));
39
40 assertTrue(Array.isArray(Object.values({})));
41 assertEquals(0, Object.values({}).length);
42}
43TestBasic();
44
45
46function TestToObject() {
47 assertThrows(function() { Object.values(); }, TypeError);
48 assertThrows(function() { Object.values(null); }, TypeError);
49 assertThrows(function() { Object.values(void 0); }, TypeError);
50}
51TestToObject();
52
53
54function TestOrder() {
55 var O = {
56 a: 1,
57 [Symbol.iterator]: null
58 };
59 O[456] = 123;
60 Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN });
61 var priv = %CreatePrivateSymbol("Secret");
62 O[priv] = 56;
63
64 var log = [];
65 var P = new Proxy(O, {
66 ownKeys(target) {
67 log.push("[[OwnPropertyKeys]]");
68 return Reflect.ownKeys(target);
69 },
70 get(target, name) {
71 log.push(`[[Get]](${JSON.stringify(name)})`);
72 return Reflect.get(target, name);
73 },
74 getOwnPropertyDescriptor(target, name) {
75 log.push(`[[GetOwnProperty]](${JSON.stringify(name)})`);
76 return Reflect.getOwnPropertyDescriptor(target, name);
77 },
78 set(target, name, value) {
79 assertUnreachable();
80 }
81 });
82
83 assertEquals([123, 1], Object.values(P));
84 assertEquals([
85 "[[OwnPropertyKeys]]",
86 "[[GetOwnProperty]](\"456\")",
87 "[[Get]](\"456\")",
88 "[[GetOwnProperty]](\"a\")",
89 "[[Get]](\"a\")",
90 "[[GetOwnProperty]](\"HIDDEN\")"
91 ], log);
92}
93TestOrder();
94
95
96function TestOrderWithDuplicates() {
97 var O = {
98 a: 1,
99 [Symbol.iterator]: null
100 };
101 O[456] = 123;
102 Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN });
103 O[priv] = 56;
104 var priv = %CreatePrivateSymbol("private");
105
106 var log = [];
107 var P = new Proxy(O, {
108 ownKeys(target) {
109 log.push("[[OwnPropertyKeys]]");
110 return [ "a", Symbol.iterator, "a", "456", "HIDDEN", "HIDDEN", "456" ];
111 },
112 get(target, name) {
113 log.push(`[[Get]](${JSON.stringify(name)})`);
114 return Reflect.get(target, name);
115 },
116 getOwnPropertyDescriptor(target, name) {
117 log.push(`[[GetOwnProperty]](${JSON.stringify(name)})`);
118 return Reflect.getOwnPropertyDescriptor(target, name);
119 },
120 set(target, name, value) {
121 assertUnreachable();
122 }
123 });
124
125 assertEquals([1, 1, 123, 123], Object.values(P));
126 assertEquals([
127 "[[OwnPropertyKeys]]",
128 "[[GetOwnProperty]](\"a\")",
129 "[[Get]](\"a\")",
130 "[[GetOwnProperty]](\"a\")",
131 "[[Get]](\"a\")",
132 "[[GetOwnProperty]](\"456\")",
133 "[[Get]](\"456\")",
134 "[[GetOwnProperty]](\"HIDDEN\")",
135 "[[GetOwnProperty]](\"HIDDEN\")",
136 "[[GetOwnProperty]](\"456\")",
137 "[[Get]](\"456\")",
138 ], log);
139}
140TestOrderWithDuplicates();
141
142
143function TestPropertyFilter() {
144 var object = { prop3: 30 };
145 object[2] = 40;
146 object["prop4"] = 50;
147 Object.defineProperty(object, "prop5", { value: 60, enumerable: true });
148 Object.defineProperty(object, "prop6", { value: 70, enumerable: false });
149 Object.defineProperty(object, "prop7", {
150 enumerable: true, get() { return 80; }});
151 var sym = Symbol("prop8");
152 object[sym] = 90;
153
154 values = Object.values(object);
155 assertEquals(5, values.length);
156 assertEquals([40,30,50,60,80], values);
157}
158TestPropertyFilter();
159
160
161function TestWithProxy() {
162 var obj1 = {prop1:10};
163 var proxy1 = new Proxy(obj1, { });
164 assertEquals([10], Object.values(proxy1));
165
166 var obj2 = {};
167 Object.defineProperty(obj2, "prop2", { value: 20, enumerable: true });
168 Object.defineProperty(obj2, "prop3", {
169 get() { return 30; }, enumerable: true });
170 var proxy2 = new Proxy(obj2, {
171 getOwnPropertyDescriptor(target, name) {
172 return Reflect.getOwnPropertyDescriptor(target, name);
173 }
174 });
175 assertEquals([20, 30], Object.values(proxy2));
176
177 var obj3 = {};
178 var count = 0;
179 var proxy3 = new Proxy(obj3, {
180 get(target, property, receiver) {
181 return count++ * 5;
182 },
183 getOwnPropertyDescriptor(target, property) {
184 return { configurable: true, enumerable: true };
185 },
186 ownKeys(target) {
187 return [ "prop0", "prop1", Symbol("prop2"), Symbol("prop5") ];
188 }
189 });
190 assertEquals([0, 5], Object.values(proxy3));
191}
192TestWithProxy();
193
194
195function TestMutateDuringEnumeration() {
196 var aDeletesB = {
197 get a() {
198 delete this.b;
199 return 1;
200 },
201 b: 2
202 };
203 assertEquals([1], Object.values(aDeletesB));
204
205 var aRemovesB = {
206 get a() {
207 Object.defineProperty(this, "b", { enumerable: false });
208 return 1;
209 },
210 b: 2
211 };
212 assertEquals([1], Object.values(aRemovesB));
213
214 var aAddsB = { get a() { this.b = 2; return 1; } };
215 assertEquals([1], Object.values(aAddsB));
216
217 var aMakesBEnumerable = {};
218 Object.defineProperty(aMakesBEnumerable, "a", {
219 get() {
220 Object.defineProperty(this, "b", { enumerable: true });
221 return 1;
222 },
223 enumerable: true
224 });
225 Object.defineProperty(aMakesBEnumerable, "b", {
226 value: 2, configurable:true, enumerable: false });
227 assertEquals([1, 2], Object.values(aMakesBEnumerable));
228}
229TestMutateDuringEnumeration();
Ben Murdochda12d292016-06-02 14:46:10 +0100230
231
232(function TestElementKinds() {
233 var O1 = { name: "1" }, O2 = { name: "2" }, O3 = { name: "3" };
234 var PI = 3.141592653589793;
235 var E = 2.718281828459045;
236 function fastSloppyArguments(a, b, c) {
237 delete arguments[0];
238 arguments[0] = a;
239 return arguments;
240 }
241
242 function slowSloppyArguments(a, b, c) {
243 delete arguments[0];
244 arguments[0] = a;
245 Object.defineProperties(arguments, {
246 0: {
247 enumerable: true,
248 value: a
249 },
250 9999: {
251 enumerable: false,
252 value: "Y"
253 }
254 });
255 arguments[10000] = "X";
256 return arguments;
257 }
258
259 var element_kinds = {
260 FAST_SMI_ELEMENTS: [ [1, 2, 3], [1, 2, 3] ],
261 FAST_HOLEY_SMI_ELEMENTS: [ [, , 3], [ 3 ] ],
262 FAST_ELEMENTS: [ [O1, O2, O3], [O1, O2, O3] ],
263 FAST_HOLEY_ELEMENTS: [ [, , O3], [O3] ],
264 FAST_DOUBLE_ELEMENTS: [ [E, NaN, PI], [E, NaN, PI] ],
265 FAST_HOLEY_DOUBLE_ELEMENTS: [ [, , NaN], [NaN] ],
266
267 DICTIONARY_ELEMENTS: [ Object.defineProperties({ 10000: "world" }, {
268 100: { enumerable: true, value: "hello" },
269 99: { enumerable: false, value: "nope" }
270 }), [ "hello", "world" ] ],
271 FAST_SLOPPY_ARGUMENTS_ELEMENTS: [
272 fastSloppyArguments("a", "b", "c"), ["a", "b", "c"] ],
273 SLOW_SLOPPY_ARGUMENTS_ELEMENTS: [
274 slowSloppyArguments("a", "b", "c"), [ "a", "b", "c", "X"]],
275
276 FAST_STRING_WRAPPER_ELEMENTS: [ new String("str"), ["s", "t", "r"] ],
277 SLOW_STRING_WRAPPER_ELEMENTS: [
278 Object.defineProperties(new String("str"), {
279 10000: { enumerable: false, value: "X" },
280 9999: { enumerable: true, value: "Y" }
281 }), ["s", "t", "r", "Y"] ],
282 };
283
284 for (let [kind, [object, expected]] of Object.entries(element_kinds)) {
285 let result1 = Object.values(object);
286 assertEquals(expected, result1, `fast Object.values() with ${kind}`);
287
288 let proxy = new Proxy(object, {});
289 let result2 = Object.values(proxy);
290 assertEquals(result1, result2, `slow Object.values() with ${kind}`);
291 }
292})();