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 6 7var target = { 8 "target_one": 1 9}; 10target.__proto__ = { 11 "target_two": 2 12}; 13var handler = { 14 enumerate: function(target) { 15 function* keys() { 16 yield "foo"; 17 yield "bar"; 18 } 19 return keys(); 20 }, 21 // For-in calls "has" on every iteration, so for TestForIn() below to 22 // detect all results of the "enumerate" trap, "has" must return true. 23 has: function(target, name) { 24 return true; 25 } 26} 27 28var proxy = new Proxy(target, handler); 29 30function TestForIn(receiver, expected) { 31 var result = []; 32 for (var k in receiver) { 33 result.push(k); 34 } 35 assertEquals(expected, result); 36} 37 38TestForIn(proxy, ["foo", "bar"]); 39 40// Test revoked proxy. 41var pair = Proxy.revocable(target, handler); 42TestForIn(pair.proxy, ["foo", "bar"]); 43pair.revoke(); 44assertThrows(()=>{ TestForIn(pair.proxy, ["foo", "bar"]) }, TypeError); 45 46// Properly call traps on proxies on the prototype chain. 47var receiver = { 48 "receiver_one": 1 49}; 50receiver.__proto__ = proxy; 51TestForIn(receiver, ["receiver_one", "foo", "bar"]); 52 53// Fall through to default behavior when trap is undefined. 54handler.enumerate = undefined; 55TestForIn(proxy, ["target_one", "target_two"]); 56delete handler.enumerate; 57TestForIn(proxy, ["target_one", "target_two"]); 58 59// Non-string keys must be filtered. 60function TestNonStringKey(key) { 61 handler.enumerate = function(target) { 62 function* keys() { yield key; } 63 return keys(); 64 } 65 assertThrows("for (var k in proxy) {}", TypeError); 66} 67 68TestNonStringKey(1); 69TestNonStringKey(3.14); 70TestNonStringKey(Symbol("foo")); 71TestNonStringKey({bad: "value"}); 72TestNonStringKey(null); 73TestNonStringKey(undefined); 74TestNonStringKey(true); 75 76(function testProtoProxyEnumerate() { 77 var keys = ['a', 'b', 'c', 'd']; 78 var handler = { 79 enumerate() { return keys[Symbol.iterator]() }, 80 has(target, key) { return false } 81 }; 82 var proxy = new Proxy({}, handler); 83 var seen_keys = []; 84 for (var i in proxy) { 85 seen_keys.push(i); 86 } 87 assertEquals([], seen_keys); 88 89 handler.has = function(target, key) { return true }; 90 for (var i in proxy) { 91 seen_keys.push(i); 92 } 93 assertEquals(keys, seen_keys); 94 95 o = {__proto__:proxy}; 96 handler.has = function(target, key) { return false }; 97 seen_keys = []; 98 for (var i in o) { 99 seen_keys.push(i); 100 } 101 assertEquals([], seen_keys); 102 103 handler.has = function(target, key) { return true }; 104 seen_keys = []; 105 for (var i in o) { 106 seen_keys.push(i); 107 } 108 assertEquals(keys, seen_keys); 109})(); 110