1// Copyright 2015 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 5// Flags: --harmony-proxies --harmony-reflect 6 7var target = { 8 "target_one": 1 9}; 10target.__proto__ = { 11 "target_proto_two": 2 12}; 13var handler = { 14 ownKeys: function(target) { 15 return ["foo", "bar"]; 16 } 17} 18 19var proxy = new Proxy(target, handler); 20 21// Simple case. 22assertEquals(["foo", "bar"], Reflect.ownKeys(proxy)); 23 24// Test interesting steps of the algorithm: 25 26// Step 6: Fall through to target.[[OwnPropertyKeys]] if the trap is undefined. 27handler.ownKeys = undefined; 28assertEquals(["target_one"], Reflect.ownKeys(proxy)); 29 30// Step 7: Throwing traps don't crash. 31handler.ownKeys = function(target) { throw 1; }; 32assertThrows("Reflect.ownKeys(proxy)"); 33 34// Step 8: CreateListFromArrayLike error cases: 35// Returning a non-Object throws. 36var keys = 1; 37handler.ownKeys = function(target) { return keys; }; 38assertThrows("Reflect.ownKeys(proxy)", TypeError); 39keys = "string"; 40assertThrows("Reflect.ownKeys(proxy)", TypeError); 41keys = Symbol("foo"); 42assertThrows("Reflect.ownKeys(proxy)", TypeError); 43keys = null; 44assertThrows("Reflect.ownKeys(proxy)", TypeError); 45 46// "length" property is honored. 47keys = { 0: "a", 1: "b", 2: "c" }; 48keys.length = 0; 49assertEquals([], Reflect.ownKeys(proxy)); 50keys.length = 1; 51assertEquals(["a"], Reflect.ownKeys(proxy)); 52keys.length = 3; 53assertEquals(["a", "b", "c"], Reflect.ownKeys(proxy)); 54// The spec wants to allow lengths up to 2^53, but we can't allocate arrays 55// of that size, so we throw even for smaller values. 56keys.length = Math.pow(2, 33); 57assertThrows("Reflect.ownKeys(proxy)", RangeError); 58 59// Non-Name results throw. 60keys = [1]; 61assertThrows("Reflect.ownKeys(proxy)", TypeError); 62keys = [{}]; 63assertThrows("Reflect.ownKeys(proxy)", TypeError); 64keys = [{toString: function() { return "foo"; }}]; 65assertThrows("Reflect.ownKeys(proxy)", TypeError); 66keys = [null]; 67assertThrows("Reflect.ownKeys(proxy)", TypeError); 68 69// Step 17a: The trap result must include all non-configurable keys. 70Object.defineProperty(target, "nonconf", {value: 1, configurable: false}); 71keys = ["foo"]; 72assertThrows("Reflect.ownKeys(proxy)", TypeError); 73keys = ["nonconf"]; 74assertEquals(keys, Reflect.ownKeys(proxy)); 75 76// Step 19a: The trap result must all keys of a non-extensible target. 77Object.preventExtensions(target); 78assertThrows("Reflect.ownKeys(proxy)", TypeError); 79keys = ["nonconf", "target_one"]; 80assertEquals(keys, Reflect.ownKeys(proxy)); 81 82// Step 20: The trap result must not add keys to a non-extensible target. 83keys = ["nonconf", "target_one", "fantasy"]; 84assertThrows("Reflect.ownKeys(proxy)", TypeError); 85