| 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 | |
| 7 | 6 |
| 8 function TestMeta() { | 7 function TestMeta() { |
| 9 assertEquals(1, Object.entries.length); | 8 assertEquals(1, Object.entries.length); |
| 10 assertEquals(Function.prototype, Object.getPrototypeOf(Object.entries)); | 9 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); | |
| 19 } | 10 } |
| 20 TestMeta(); | 11 TestMeta(); |
| 21 | 12 |
| 22 | 13 |
| 23 function TestBasic() { | 14 function TestBasic() { |
| 24 var x = 16; | 15 var x = 16; |
| 25 var O = { | 16 var O = { |
| 26 d: 1, | 17 d: 1, |
| 27 c: 3, | 18 c: 3, |
| 28 [Symbol.iterator]: void 0, | 19 [Symbol.iterator]: void 0, |
| 29 0: 123, | 20 0: 123, |
| 30 1000: 456, | 21 1000: 456, |
| 31 [x * x]: "ducks", | 22 [x * x]: "ducks", |
| 32 [`0x${(x * x).toString(16)}`]: "quack" | 23 [`0x${(x * x).toString(16)}`]: "quack" |
| 33 }; | 24 }; |
| 34 O.a = 2; | 25 O.a = 2; |
| 35 O.b = 4; | 26 O.b = 4; |
| 36 Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN }); | 27 Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN }); |
| 37 assertEquals([ | 28 assertEquals([ |
| 38 ["0", 123], | 29 ["0", 123], |
| 39 ["256", "ducks"], | 30 ["256", "ducks"], |
| 40 ["1000", 456], | 31 ["1000", 456], |
| 41 ["d", 1], | 32 ["d", 1], |
| 42 ["c", 3], | 33 ["c", 3], |
| 43 ["0x100", "quack"], | 34 ["0x100", "quack"], |
| 44 ["a", 2], | 35 ["a", 2], |
| 45 ["b", 4] | 36 ["b", 4] |
| 46 ], Object.entries(O)); | 37 ], Object.entries(O)); |
| 47 assertEquals(Object.entries(O), Object.keys(O).map(key => [key, O[key]])); | 38 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); | |
| 51 } | 39 } |
| 52 TestBasic(); | 40 TestBasic(); |
| 53 | 41 |
| 54 | 42 |
| 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 | |
| 63 function TestOrder() { | 43 function TestOrder() { |
| 64 var O = { | 44 var O = { |
| 65 a: 1, | 45 a: 1, |
| 66 [Symbol.iterator]: null | 46 [Symbol.iterator]: null |
| 67 }; | 47 }; |
| 68 O[456] = 123; | 48 O[456] = 123; |
| 69 Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN }); | 49 Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN }); |
| 70 var priv = %CreatePrivateSymbol("Secret"); | |
| 71 O[priv] = 56; | |
| 72 | 50 |
| 73 var log = []; | 51 var log = []; |
| 74 var P = new Proxy(O, { | 52 var P = new Proxy(O, { |
| 75 ownKeys(target) { | 53 ownKeys(target) { |
| 76 log.push("[[OwnPropertyKeys]]"); | 54 log.push("[[OwnPropertyKeys]]"); |
| 77 return Reflect.ownKeys(target); | 55 return Reflect.ownKeys(target); |
| 78 }, | 56 }, |
| 79 get(target, name) { | 57 get(target, name) { |
| 80 log.push(`[[Get]](${JSON.stringify(name)})`); | 58 log.push(`[[Get]](${JSON.stringify(name)})`); |
| 81 return Reflect.get(target, name); | 59 return Reflect.get(target, name); |
| 82 }, | 60 }, |
| 83 getOwnPropertyDescriptor(target, name) { | |
| 84 log.push(`[[GetOwnProperty]](${JSON.stringify(name)})`); | |
| 85 return Reflect.getOwnPropertyDescriptor(target, name); | |
| 86 }, | |
| 87 set(target, name, value) { | 61 set(target, name, value) { |
| 88 assertUnreachable(); | 62 assertUnreachable(); |
| 89 } | 63 } |
| 90 }); | 64 }); |
| 91 | 65 |
| 92 assertEquals([["456", 123], ["a", 1]], Object.entries(P)); | 66 assertEquals([["456", 123], ["a", 1]], Object.entries(P)); |
| 93 assertEquals([ | 67 assertEquals([ |
| 94 "[[OwnPropertyKeys]]", | 68 "[[OwnPropertyKeys]]", |
| 95 "[[GetOwnProperty]](\"456\")", | |
| 96 "[[Get]](\"456\")", | 69 "[[Get]](\"456\")", |
| 97 "[[GetOwnProperty]](\"a\")", | 70 "[[Get]](\"a\")" |
| 98 "[[Get]](\"a\")", | |
| 99 "[[GetOwnProperty]](\"HIDDEN\")" | |
| 100 ], log); | 71 ], log); |
| 101 } | 72 } |
| 102 TestOrder(); | 73 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 |