1// Copyright JS Foundation and other contributors, http://js.foundation 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15// Copyright 2015 the V8 project authors. All rights reserved. 16// Use of this source code is governed by a BSD-style license that can be 17// found in the LICENSE file. 18 19function array_check(result_array, expected_array) { 20 assert(result_array instanceof Array); 21 assert(result_array.length === expected_array.length); 22 for (var idx = 0; idx < expected_array.length; idx++) { 23 assert(result_array[idx] === expected_array[idx]); 24 } 25} 26 27var target = {}; 28var handler = { ownKeys (target) { 29 throw 42; 30}}; 31 32var proxy = new Proxy(target, handler); 33 34try { 35 // Array.prototype.sort 36 Array.prototype.sort.call(proxy); 37 assert(false); 38} catch (e) { 39 assert(e === 42); 40} 41 42try { 43 // 19.1.2.14.4 44 Object.keys(proxy); 45 assert(false); 46} catch (e) { 47 assert(e === 42); 48} 49 50try { 51 // 19.1.2.7.1 52 Object.getOwnPropertyNames(proxy); 53 assert(false); 54} catch (e) { 55 assert(e === 42); 56} 57 58try { 59 // 19.1.2.8.1 60 Object.getOwnPropertySymbols(proxy); 61 assert(false); 62} catch (e) { 63 assert(e === 42); 64} 65 66// test basic functionality 67var symA = Symbol("smA"); 68var symB = Symbol("smB"); 69var target = { prop1: "prop1", prop2: "prop2"}; 70target[symB] = "s3"; 71var handler = { 72 ownKeys: function(target) { 73 return ["foo", "bar", symA]; 74 } 75} 76 77var proxy = new Proxy(target, handler); 78 79array_check(Reflect.ownKeys(proxy), ["foo", "bar", symA]); 80array_check(Object.getOwnPropertyNames(proxy), ["foo", "bar"]); 81array_check(Object.keys(proxy), ["foo", "bar"]); 82array_check(Object.getOwnPropertySymbols(proxy), [symA]); 83 84handler.ownKeys = function(target) {return Object.getOwnPropertyNames(target);}; 85 86array_check(Reflect.ownKeys(proxy), ["prop1", "prop2"]); 87array_check(Object.getOwnPropertyNames(proxy), ["prop1", "prop2"]); 88array_check(Object.keys(proxy), ["prop1", "prop2"]); 89array_check(Object.getOwnPropertySymbols(proxy), []); 90 91// test with no trap 92var target = { prop1: "prop1", prop2: "prop2"}; 93var handler = {}; 94var proxy = new Proxy(target, handler); 95 96assert(JSON.stringify(Object.getOwnPropertyNames(proxy)) === '["prop1","prop2"]'); 97 98// test wtih "undefined" trap 99var target = { prop1: "prop1", prop2: "prop2"}; 100var handler = {ownKeys: null}; 101var proxy = new Proxy(target, handler); 102 103assert(JSON.stringify(Object.getOwnPropertyNames(proxy)) === '["prop1","prop2"]'); 104 105// test with invalid trap 106var target = { prop1: "prop1", prop2: "prop2"}; 107var handler = {ownKeys: 42}; 108var proxy = new Proxy(target, handler); 109 110try { 111 Object.getOwnPropertyNames(proxy); 112 assert(false); 113} catch (e) { 114 assert(e instanceof TypeError); 115} 116 117// test when CreateListFromArrayLike called on non-object 118var target = { prop1: "prop1", prop2: "prop2"}; 119var handler = { 120 ownKeys: function(target) { 121 return "foo"; 122 } 123}; 124 125var proxy = new Proxy(target, handler); 126 127try { 128 Object.getOwnPropertyNames(proxy); 129 assert(false); 130} catch (e) { 131 assert(e instanceof TypeError); 132} 133 134// test with invalid property key 135var target = {}; 136var handler = { 137 ownKeys: function(target) { 138 return [5]; 139 } 140}; 141 142var proxy = new Proxy(target, handler); 143 144try { 145 Object.getOwnPropertyNames(proxy); 146 assert(false); 147} catch (e) { 148 assert(e instanceof TypeError); 149} 150 151// test with duplicated keys 152var target = { prop1: "prop1", prop2: "prop2"}; 153var handler = { 154 ownKeys: function(target) { 155 return ["a", "a", "a"]; 156 } 157}; 158 159var proxy = new Proxy(target, handler); 160 161assert(JSON.stringify(Object.getOwnPropertyNames(proxy)) === '["a","a","a"]'); 162 163// test with lots of keys 164var keyslist = []; 165 166var handler = { 167 ownKeys: function(target) { 168 for (var idx = 0; idx < 30; idx++) { 169 keyslist.push("K" + idx); 170 } 171 return keyslist; 172 } 173}; 174 175var proxy = new Proxy(target, handler); 176assert(JSON.stringify(Object.getOwnPropertyNames(proxy)) === JSON.stringify(keyslist)); 177 178// test when invariants gets violated 179var target = { 180 "target_one": 1 181}; 182Object.defineProperty(target, "nonconf", {value: 1, configurable: false}); 183 184var keys = ["foo"]; 185 186var handler = { 187 ownKeys: function(target) { 188 return keys; 189 } 190}; 191 192var proxy = new Proxy(target, handler); 193 194try { 195 Object.getOwnPropertyNames(proxy); 196 assert(false); 197} catch (e) { 198 assert(e instanceof TypeError); 199} 200 201keys = ["nonconf"]; 202assert(JSON.stringify(Object.getOwnPropertyNames(proxy)) === '["nonconf"]'); 203 204Object.preventExtensions(target); 205keys = ["foo", "nonconf"]; 206 207try { 208 Object.getOwnPropertyNames(proxy); 209 assert(false); 210} catch (e) { 211 assert(e instanceof TypeError); 212} 213 214keys = ["target_one", "nonconf"]; 215 216assert(JSON.stringify(Object.getOwnPropertyNames(proxy)) === '["target_one","nonconf"]'); 217 218keys = ["target_one", "nonconf", "foo"]; 219 220try { 221 Object.getOwnPropertyNames(proxy); 222 assert(false); 223} catch (e) { 224 assert(e instanceof TypeError); 225} 226