// Copyright 2015 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Flags: --harmony-proxies var target = { "target_one": 1 }; target.__proto__ = { "target_two": 2 }; var handler = { enumerate: function(target) { function* keys() { yield "foo"; yield "bar"; } return keys(); }, // For-in calls "has" on every iteration, so for TestForIn() below to // detect all results of the "enumerate" trap, "has" must return true. has: function(target, name) { return true; } } var proxy = new Proxy(target, handler); function TestForIn(receiver, expected) { var result = []; for (var k in receiver) { result.push(k); } assertEquals(expected, result); } TestForIn(proxy, ["foo", "bar"]); // Test revoked proxy. var pair = Proxy.revocable(target, handler); TestForIn(pair.proxy, ["foo", "bar"]); pair.revoke(); assertThrows(()=>{ TestForIn(pair.proxy, ["foo", "bar"]) }, TypeError); // Properly call traps on proxies on the prototype chain. var receiver = { "receiver_one": 1 }; receiver.__proto__ = proxy; TestForIn(receiver, ["receiver_one", "foo", "bar"]); // Fall through to default behavior when trap is undefined. handler.enumerate = undefined; TestForIn(proxy, ["target_one", "target_two"]); delete handler.enumerate; TestForIn(proxy, ["target_one", "target_two"]); // Non-string keys must be filtered. function TestNonStringKey(key) { handler.enumerate = function(target) { function* keys() { yield key; } return keys(); } assertThrows("for (var k in proxy) {}", TypeError); } TestNonStringKey(1); TestNonStringKey(3.14); TestNonStringKey(Symbol("foo")); TestNonStringKey({bad: "value"}); TestNonStringKey(null); TestNonStringKey(undefined); TestNonStringKey(true); (function testProtoProxyEnumerate() { var keys = ['a', 'b', 'c', 'd']; var handler = { enumerate() { return keys[Symbol.iterator]() }, has(target, key) { return false } }; var proxy = new Proxy({}, handler); var seen_keys = []; for (var i in proxy) { seen_keys.push(i); } assertEquals([], seen_keys); handler.has = function(target, key) { return true }; for (var i in proxy) { seen_keys.push(i); } assertEquals(keys, seen_keys); o = {__proto__:proxy}; handler.has = function(target, key) { return false }; seen_keys = []; for (var i in o) { seen_keys.push(i); } assertEquals([], seen_keys); handler.has = function(target, key) { return true }; seen_keys = []; for (var i in o) { seen_keys.push(i); } assertEquals(keys, seen_keys); })();