1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved.
2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file.
4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Flags: --harmony-proxies
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar target = {
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  target: 1
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtarget.__proto__ = {
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  target_proto: 2
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar handler = {
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ownKeys: function(target) {
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return ["foo", "bar", Symbol("baz"), "non-enum", "not-found"];
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  },
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  getOwnPropertyDescriptor: function(target, name) {
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (name == "non-enum") return {configurable: true};
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (name == "not-found") return undefined;
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return {enumerable: true, configurable: true};
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar proxy = new Proxy(target, handler);
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Object.keys() ignores symbols and non-enumerable keys.
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals(["foo", "bar"], Object.keys(proxy));
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Edge case: no properties left after filtering.
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochhandler.getOwnPropertyDescriptor = undefined;
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals([], Object.keys(proxy));
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Throwing shouldn't crash.
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochhandler.getOwnPropertyDescriptor = function() { throw new Number(1); };
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertThrows("Object.keys(proxy)", Number);
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Fall through to target if there is no trap.
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochhandler.ownKeys = undefined;
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals(["target"], Object.keys(proxy));
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals(["target"], Object.keys(target));
42