OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Flags: --harmony-object-values-entries --harmony-proxies --harmony-reflect | 5 // Flags: --harmony-object-values-entries --harmony-proxies --harmony-reflect |
| 6 // Flags: --allow-natives-syntax |
6 | 7 |
7 function TestMeta() { | 8 function TestMeta() { |
8 assertEquals(1, Object.entries.length); | 9 assertEquals(1, Object.entries.length); |
9 assertEquals(Function.prototype, Object.getPrototypeOf(Object.entries)); | 10 assertEquals(Function.prototype, Object.getPrototypeOf(Object.entries)); |
| 11 assertEquals("entries", Object.entries.name); |
| 12 |
| 13 var descriptor = Object.getOwnPropertyDescriptor(Object, "entries"); |
| 14 assertTrue(descriptor.writable); |
| 15 assertFalse(descriptor.enumerable); |
| 16 assertTrue(descriptor.configurable); |
| 17 |
| 18 assertThrows(() => new Object.entries({}), TypeError); |
10 } | 19 } |
11 TestMeta(); | 20 TestMeta(); |
12 | 21 |
13 | 22 |
14 function TestBasic() { | 23 function TestBasic() { |
15 var x = 16; | 24 var x = 16; |
16 var O = { | 25 var O = { |
17 d: 1, | 26 d: 1, |
18 c: 3, | 27 c: 3, |
19 [Symbol.iterator]: void 0, | 28 [Symbol.iterator]: void 0, |
20 0: 123, | 29 0: 123, |
21 1000: 456, | 30 1000: 456, |
22 [x * x]: "ducks", | 31 [x * x]: "ducks", |
23 [`0x${(x * x).toString(16)}`]: "quack" | 32 [`0x${(x * x).toString(16)}`]: "quack" |
24 }; | 33 }; |
25 O.a = 2; | 34 O.a = 2; |
26 O.b = 4; | 35 O.b = 4; |
27 Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN }); | 36 Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN }); |
28 assertEquals([ | 37 assertEquals([ |
29 ["0", 123], | 38 ["0", 123], |
30 ["256", "ducks"], | 39 ["256", "ducks"], |
31 ["1000", 456], | 40 ["1000", 456], |
32 ["d", 1], | 41 ["d", 1], |
33 ["c", 3], | 42 ["c", 3], |
34 ["0x100", "quack"], | 43 ["0x100", "quack"], |
35 ["a", 2], | 44 ["a", 2], |
36 ["b", 4] | 45 ["b", 4] |
37 ], Object.entries(O)); | 46 ], Object.entries(O)); |
38 assertEquals(Object.entries(O), Object.keys(O).map(key => [key, O[key]])); | 47 assertEquals(Object.entries(O), Object.keys(O).map(key => [key, O[key]])); |
| 48 |
| 49 assertTrue(Array.isArray(Object.entries({}))); |
| 50 assertEquals(0, Object.entries({}).length); |
39 } | 51 } |
40 TestBasic(); | 52 TestBasic(); |
41 | 53 |
42 | 54 |
| 55 function TestToObject() { |
| 56 assertThrows(function() { Object.entries(); }, TypeError); |
| 57 assertThrows(function() { Object.entries(null); }, TypeError); |
| 58 assertThrows(function() { Object.entries(void 0); }, TypeError); |
| 59 } |
| 60 TestToObject(); |
| 61 |
| 62 |
43 function TestOrder() { | 63 function TestOrder() { |
44 var O = { | 64 var O = { |
45 a: 1, | 65 a: 1, |
46 [Symbol.iterator]: null | 66 [Symbol.iterator]: null |
47 }; | 67 }; |
48 O[456] = 123; | 68 O[456] = 123; |
49 Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN }); | 69 Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN }); |
| 70 var priv = %CreatePrivateSymbol("Secret"); |
| 71 O[priv] = 56; |
50 | 72 |
51 var log = []; | 73 var log = []; |
52 var P = new Proxy(O, { | 74 var P = new Proxy(O, { |
53 ownKeys(target) { | 75 ownKeys(target) { |
54 log.push("[[OwnPropertyKeys]]"); | 76 log.push("[[OwnPropertyKeys]]"); |
55 return Reflect.ownKeys(target); | 77 return Reflect.ownKeys(target); |
56 }, | 78 }, |
57 get(target, name) { | 79 get(target, name) { |
58 log.push(`[[Get]](${JSON.stringify(name)})`); | 80 log.push(`[[Get]](${JSON.stringify(name)})`); |
59 return Reflect.get(target, name); | 81 return Reflect.get(target, name); |
60 }, | 82 }, |
| 83 getOwnPropertyDescriptor(target, name) { |
| 84 log.push(`[[GetOwnProperty]](${JSON.stringify(name)})`); |
| 85 return Reflect.getOwnPropertyDescriptor(target, name); |
| 86 }, |
61 set(target, name, value) { | 87 set(target, name, value) { |
62 assertUnreachable(); | 88 assertUnreachable(); |
63 } | 89 } |
64 }); | 90 }); |
65 | 91 |
66 assertEquals([["456", 123], ["a", 1]], Object.entries(P)); | 92 assertEquals([["456", 123], ["a", 1]], Object.entries(P)); |
67 assertEquals([ | 93 assertEquals([ |
68 "[[OwnPropertyKeys]]", | 94 "[[OwnPropertyKeys]]", |
| 95 "[[GetOwnProperty]](\"456\")", |
69 "[[Get]](\"456\")", | 96 "[[Get]](\"456\")", |
70 "[[Get]](\"a\")" | 97 "[[GetOwnProperty]](\"a\")", |
| 98 "[[Get]](\"a\")", |
| 99 "[[GetOwnProperty]](\"HIDDEN\")" |
71 ], log); | 100 ], log); |
72 } | 101 } |
73 TestOrder(); | 102 TestOrder(); |
| 103 |
| 104 |
| 105 function TestOrderWithDuplicates() { |
| 106 var O = { |
| 107 a: 1, |
| 108 [Symbol.iterator]: null |
| 109 }; |
| 110 O[456] = 123; |
| 111 Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN }); |
| 112 var priv = %CreatePrivateSymbol("Secret"); |
| 113 O[priv] = 56; |
| 114 |
| 115 var log = []; |
| 116 var P = new Proxy(O, { |
| 117 ownKeys(target) { |
| 118 log.push("[[OwnPropertyKeys]]"); |
| 119 return ["a", Symbol.iterator, "a", "456", "HIDDEN", "HIDDEN", "456"]; |
| 120 }, |
| 121 get(target, name) { |
| 122 log.push(`[[Get]](${JSON.stringify(name)})`); |
| 123 return Reflect.get(target, name); |
| 124 }, |
| 125 getOwnPropertyDescriptor(target, name) { |
| 126 log.push(`[[GetOwnProperty]](${JSON.stringify(name)})`); |
| 127 return Reflect.getOwnPropertyDescriptor(target, name); |
| 128 }, |
| 129 set(target, name, value) { |
| 130 assertUnreachable(); |
| 131 } |
| 132 }); |
| 133 |
| 134 assertEquals([ |
| 135 ["a", 1], |
| 136 ["a", 1], |
| 137 ["456", 123], |
| 138 ["456", 123] |
| 139 ], Object.entries(P)); |
| 140 assertEquals([ |
| 141 "[[OwnPropertyKeys]]", |
| 142 "[[GetOwnProperty]](\"a\")", |
| 143 "[[Get]](\"a\")", |
| 144 "[[GetOwnProperty]](\"a\")", |
| 145 "[[Get]](\"a\")", |
| 146 "[[GetOwnProperty]](\"456\")", |
| 147 "[[Get]](\"456\")", |
| 148 "[[GetOwnProperty]](\"HIDDEN\")", |
| 149 "[[GetOwnProperty]](\"HIDDEN\")", |
| 150 "[[GetOwnProperty]](\"456\")", |
| 151 "[[Get]](\"456\")" |
| 152 ], log); |
| 153 } |
| 154 TestOrderWithDuplicates(); |
| 155 |
| 156 |
| 157 function TestPropertyFilter() { |
| 158 var object = { prop3: 30 }; |
| 159 object[2] = 40; |
| 160 object["prop4"] = 50; |
| 161 Object.defineProperty(object, "prop5", { value: 60, enumerable: true }); |
| 162 Object.defineProperty(object, "prop6", { value: 70, enumerable: false }); |
| 163 Object.defineProperty(object, "prop7", { |
| 164 enumerable: true, get() { return 80; }}); |
| 165 var sym = Symbol("prop8"); |
| 166 object[sym] = 90; |
| 167 |
| 168 values = Object.entries(object); |
| 169 assertEquals(5, values.length); |
| 170 assertEquals([ |
| 171 [ "2", 40 ], |
| 172 [ "prop3", 30 ], |
| 173 [ "prop4", 50 ], |
| 174 [ "prop5", 60 ], |
| 175 [ "prop7", 80 ] |
| 176 ], values); |
| 177 } |
| 178 TestPropertyFilter(); |
| 179 |
| 180 |
| 181 function TestWithProxy() { |
| 182 var obj1 = {prop1:10}; |
| 183 var proxy1 = new Proxy(obj1, { }); |
| 184 assertEquals([ [ "prop1", 10 ] ], Object.entries(proxy1)); |
| 185 |
| 186 var obj2 = {}; |
| 187 Object.defineProperty(obj2, "prop2", { value: 20, enumerable: true }); |
| 188 Object.defineProperty(obj2, "prop3", { |
| 189 get() { return 30; }, enumerable: true }); |
| 190 var proxy2 = new Proxy(obj2, { |
| 191 getOwnPropertyDescriptor(target, name) { |
| 192 return Reflect.getOwnPropertyDescriptor(target, name); |
| 193 } |
| 194 }); |
| 195 assertEquals([ [ "prop2", 20 ], [ "prop3", 30 ] ], Object.entries(proxy2)); |
| 196 |
| 197 var obj3 = {}; |
| 198 var count = 0; |
| 199 var proxy3 = new Proxy(obj3, { |
| 200 get(target, property, receiver) { |
| 201 return count++ * 5; |
| 202 }, |
| 203 getOwnPropertyDescriptor(target, property) { |
| 204 return { configurable: true, enumerable: true }; |
| 205 }, |
| 206 ownKeys(target) { |
| 207 return [ "prop0", "prop1", Symbol("prop2"), Symbol("prop5") ]; |
| 208 } |
| 209 }); |
| 210 assertEquals([ [ "prop0", 0 ], [ "prop1", 5 ] ], Object.entries(proxy3)); |
| 211 } |
| 212 TestWithProxy(); |
| 213 |
| 214 |
| 215 function TestMutateDuringEnumeration() { |
| 216 var aDeletesB = { |
| 217 get a() { |
| 218 delete this.b; |
| 219 return 1; |
| 220 }, |
| 221 b: 2 |
| 222 }; |
| 223 assertEquals([ [ "a", 1 ] ], Object.entries(aDeletesB)); |
| 224 |
| 225 var aRemovesB = { |
| 226 get a() { |
| 227 Object.defineProperty(this, "b", { enumerable: false }); |
| 228 return 1; |
| 229 }, |
| 230 b: 2 |
| 231 }; |
| 232 assertEquals([ [ "a", 1 ] ], Object.entries(aRemovesB)); |
| 233 |
| 234 var aAddsB = { get a() { this.b = 2; return 1; } }; |
| 235 assertEquals([ [ "a", 1 ] ], Object.entries(aAddsB)); |
| 236 |
| 237 var aMakesBEnumerable = {}; |
| 238 Object.defineProperty(aMakesBEnumerable, "a", { |
| 239 get() { |
| 240 Object.defineProperty(this, "b", { enumerable: true }); |
| 241 return 1; |
| 242 }, |
| 243 enumerable: true |
| 244 }); |
| 245 Object.defineProperty(aMakesBEnumerable, "b", { |
| 246 value: 2, configurable:true, enumerable: false }); |
| 247 assertEquals([ [ "a", 1 ], [ "b", 2 ] ], Object.entries(aMakesBEnumerable)); |
| 248 } |
| 249 TestMutateDuringEnumeration(); |
OLD | NEW |