proxy-keys.js (3898B)
1 // Copyright (C) 2017 Caitlin Potter. All rights reserved. 2 // This code is governed by the BSD license found in the LICENSE file. 3 4 /*--- 5 esid: sec-object.keys 6 description: > 7 Object.keys() observably performs [[GetOwnProperty]] 8 info: | 9 19.1.2.16 Object.keys ( O ) 10 11 1. Let obj be ? ToObject(O). 12 2. Let nameList be ? EnumerableOwnProperties(obj, "key"). 13 ... 14 15 7.3.21 EnumerableOwnProperties ( O, kind ) 16 17 1. Assert: Type(O) is Object. 18 2. Let ownKeys be ? O.[[OwnPropertyKeys]](). 19 3. Let properties be a new empty List. 20 4. For each element key of ownKeys in List order, do 21 a. If Type(key) is String, then 22 i. Let desc be ? O.[[GetOwnProperty]](key). 23 ... 24 features: [Symbol] 25 ---*/ 26 27 let log = []; 28 let s = Symbol("test"); 29 let target = { 30 x: true 31 }; 32 33 let ownKeys = { 34 get length() { 35 log.push({ 36 name: "get ownKeys['length']", 37 receiver: this 38 }); 39 return 3; 40 }, 41 42 get 0() { 43 log.push({ 44 name: "get ownKeys[0]", 45 receiver: this 46 }); 47 return "a"; 48 }, 49 50 get 1() { 51 log.push({ 52 name: "get ownKeys[1]", 53 receiver: this 54 }); 55 return s; 56 }, 57 58 get 2() { 59 log.push({ 60 name: "get ownKeys[2]", 61 receiver: this 62 }); 63 return "b"; 64 } 65 }; 66 67 let ownKeysDescriptors = { 68 "a": { 69 enumerable: true, 70 configurable: true, 71 value: 1 72 }, 73 74 "b": { 75 enumerable: false, 76 configurable: true, 77 value: 2 78 }, 79 80 [s]: { 81 enumerable: true, 82 configurable: true, 83 value: 3 84 } 85 }; 86 87 let handler = { 88 get ownKeys() { 89 log.push({ 90 name: "get handler.ownKeys", 91 receiver: this 92 }); 93 return (...args) => { 94 log.push({ 95 name: "call handler.ownKeys", 96 receiver: this, 97 args 98 }); 99 return ownKeys; 100 }; 101 }, 102 103 get getOwnPropertyDescriptor() { 104 log.push({ 105 name: "get handler.getOwnPropertyDescriptor", 106 receiver: this 107 }); 108 return (...args) => { 109 log.push({ 110 name: "call handler.getOwnPropertyDescriptor", 111 receiver: this, 112 args 113 }); 114 const name = args[1]; 115 return ownKeysDescriptors[name]; 116 }; 117 } 118 }; 119 120 let proxy = new Proxy(target, handler); 121 let keys = Object.keys(proxy); 122 123 assert.sameValue(log.length, 10); 124 125 assert.sameValue(log[0].name, "get handler.ownKeys"); 126 assert.sameValue(log[0].receiver, handler); 127 128 assert.sameValue(log[1].name, "call handler.ownKeys"); 129 assert.sameValue(log[1].receiver, handler); 130 assert.sameValue(log[1].args.length, 1); 131 assert.sameValue(log[1].args[0], target); 132 133 // CreateListFromArrayLike(trapResultArray, « String, Symbol »). 134 assert.sameValue(log[2].name, "get ownKeys['length']"); 135 assert.sameValue(log[2].receiver, ownKeys); 136 137 assert.sameValue(log[3].name, "get ownKeys[0]"); 138 assert.sameValue(log[3].receiver, ownKeys); 139 140 assert.sameValue(log[4].name, "get ownKeys[1]"); 141 assert.sameValue(log[4].receiver, ownKeys); 142 143 assert.sameValue(log[5].name, "get ownKeys[2]"); 144 assert.sameValue(log[5].receiver, ownKeys); 145 146 // Let desc be ? O.[[GetOwnProperty]]("a"). 147 assert.sameValue(log[6].name, "get handler.getOwnPropertyDescriptor"); 148 assert.sameValue(log[6].receiver, handler); 149 150 assert.sameValue(log[7].name, "call handler.getOwnPropertyDescriptor"); 151 assert.sameValue(log[7].receiver, handler); 152 assert.sameValue(log[7].args.length, 2); 153 assert.sameValue(log[7].args[0], target); 154 assert.sameValue(log[7].args[1], "a"); 155 156 // Let desc be ? O.[[GetOwnProperty]]("b"). 157 assert.sameValue(log[8].name, "get handler.getOwnPropertyDescriptor"); 158 assert.sameValue(log[8].receiver, handler); 159 160 assert.sameValue(log[9].name, "call handler.getOwnPropertyDescriptor"); 161 assert.sameValue(log[9].receiver, handler); 162 assert.sameValue(log[9].args.length, 2); 163 assert.sameValue(log[9].args[0], target); 164 assert.sameValue(log[9].args[1], "b"); 165 166 // "a" is the only enumerable String-keyed property. 167 assert.sameValue(keys.length, 1); 168 assert.sameValue(keys[0], "a"); 169 170 reportCompare(0, 0);