From 3f214e715ff46e4b516ae4f01b5cc293170a7a3f Mon Sep 17 00:00:00 2001
From: Leonardo Balter <leonardo.balter@gmail.com>
Date: Tue, 2 Jun 2015 19:15:54 -0400
Subject: [PATCH] Proxy: ownKeys

---
 ...l-parameters-object-getownpropertynames.js | 32 +++++++++++++++++
 ...parameters-object-getownpropertysymbols.js | 35 +++++++++++++++++++
 .../ownKeys/call-parameters-object-keys.js    | 31 ++++++++++++++++
 ...rap-result-absent-not-configurable-keys.js | 27 ++++++++++++++
 .../ownKeys/extensible-return-trap-result.js  | 34 ++++++++++++++++++
 .../not-extensible-missing-keys-throws.js     | 32 +++++++++++++++++
 .../ownKeys/not-extensible-new-keys-throws.js | 29 +++++++++++++++
 .../ownKeys/not-extensible-return-keys.js     | 33 +++++++++++++++++
 test/built-ins/Proxy/ownKeys/null-handler.js  | 17 +++++++++
 .../return-all-non-configurable-keys.js       | 35 +++++++++++++++++++
 .../Proxy/ownKeys/return-is-abrupt.js         | 28 +++++++++++++++
 .../ownKeys/return-not-list-object-throws.js  | 28 +++++++++++++++
 .../Proxy/ownKeys/trap-is-not-callable.js     | 24 +++++++++++++
 .../Proxy/ownKeys/trap-is-undefined.js        | 22 ++++++++++++
 14 files changed, 407 insertions(+)
 create mode 100644 test/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertynames.js
 create mode 100644 test/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertysymbols.js
 create mode 100644 test/built-ins/Proxy/ownKeys/call-parameters-object-keys.js
 create mode 100644 test/built-ins/Proxy/ownKeys/extensible-return-trap-result-absent-not-configurable-keys.js
 create mode 100644 test/built-ins/Proxy/ownKeys/extensible-return-trap-result.js
 create mode 100644 test/built-ins/Proxy/ownKeys/not-extensible-missing-keys-throws.js
 create mode 100644 test/built-ins/Proxy/ownKeys/not-extensible-new-keys-throws.js
 create mode 100644 test/built-ins/Proxy/ownKeys/not-extensible-return-keys.js
 create mode 100644 test/built-ins/Proxy/ownKeys/null-handler.js
 create mode 100644 test/built-ins/Proxy/ownKeys/return-all-non-configurable-keys.js
 create mode 100644 test/built-ins/Proxy/ownKeys/return-is-abrupt.js
 create mode 100644 test/built-ins/Proxy/ownKeys/return-not-list-object-throws.js
 create mode 100644 test/built-ins/Proxy/ownKeys/trap-is-not-callable.js
 create mode 100644 test/built-ins/Proxy/ownKeys/trap-is-undefined.js

diff --git a/test/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertynames.js b/test/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertynames.js
new file mode 100644
index 0000000000..b7bde1412e
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertynames.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    [[OwnPropertyKeys]] ( )
+
+    8. Let trapResultArray be Call(trap, handler, «target»).
+---*/
+
+var _target, _handler;
+var target = {
+    foo: 1,
+    bar: 2
+};
+
+var handler = {
+    ownKeys: function(t) {
+        _handler = this;
+        _target = t;
+        return Object.getOwnPropertyNames(t);
+    }
+}
+var p = new Proxy(target, handler);
+
+var names = Object.getOwnPropertyNames(p);
+
+assert.sameValue(names[0], "foo");
+assert.sameValue(names[1], "bar");
+assert.sameValue(names.length, 2);
+assert.sameValue(_handler, handler);
+assert.sameValue(_target, target);
diff --git a/test/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertysymbols.js b/test/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertysymbols.js
new file mode 100644
index 0000000000..39f3c7bd75
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertysymbols.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    [[OwnPropertyKeys]] ( )
+
+    8. Let trapResultArray be Call(trap, handler, «target»).
+features: [Symbol]
+---*/
+
+var _target, _handler;
+var target = {};
+var a = Symbol('a');
+var b = Symbol('b');
+
+target[a] = 1;
+target[b] = 2;
+
+var handler = {
+    ownKeys: function(t) {
+        _handler = this;
+        _target = t;
+        return Object.getOwnPropertySymbols(t);
+    }
+}
+var p = new Proxy(target, handler);
+
+var symbols = Object.getOwnPropertySymbols(p);
+
+assert.sameValue(symbols[0], a);
+assert.sameValue(symbols[1], b);
+assert.sameValue(symbols.length, 2);
+assert.sameValue(_handler, handler);
+assert.sameValue(_target, target);
diff --git a/test/built-ins/Proxy/ownKeys/call-parameters-object-keys.js b/test/built-ins/Proxy/ownKeys/call-parameters-object-keys.js
new file mode 100644
index 0000000000..0db31999b9
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/call-parameters-object-keys.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    [[OwnPropertyKeys]] ( )
+
+    8. Let trapResultArray be Call(trap, handler, «target»).
+---*/
+
+var _target, _handler;
+var target = {
+    foo: 1,
+    bar: 2
+};
+var handler = {
+    ownKeys: function(t) {
+        _handler = this;
+        _target = t;
+        return Object.keys(t);
+    }
+};
+var p = new Proxy(target, handler);
+
+var keys = Object.keys(p);
+
+assert.sameValue(keys[0], "foo");
+assert.sameValue(keys[1], "bar");
+assert.sameValue(keys.length, 2);
+assert.sameValue(_handler, handler);
+assert.sameValue(_target, target);
diff --git a/test/built-ins/Proxy/ownKeys/extensible-return-trap-result-absent-not-configurable-keys.js b/test/built-ins/Proxy/ownKeys/extensible-return-trap-result-absent-not-configurable-keys.js
new file mode 100644
index 0000000000..c17002ebb0
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/extensible-return-trap-result-absent-not-configurable-keys.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    If target is extensible, return the non-falsy trap result if target doesn't
+    contain any non-configurable keys.
+info: >
+    [[OwnPropertyKeys]] ( )
+
+    ...
+    19. If extensibleTarget is true and targetNonconfigurableKeys is empty, then
+        a. Return trapResult.
+---*/
+
+var p = new Proxy({attr: 42}, {
+    ownKeys: function() {
+        return ["foo", "bar"];
+    }
+});
+
+var keys = Object.getOwnPropertyNames(p);
+
+assert.sameValue(keys[0], "foo");
+assert.sameValue(keys[1], "bar");
+
+assert.sameValue(keys.length, 2);
diff --git a/test/built-ins/Proxy/ownKeys/extensible-return-trap-result.js b/test/built-ins/Proxy/ownKeys/extensible-return-trap-result.js
new file mode 100644
index 0000000000..b99a3ad13d
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/extensible-return-trap-result.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    If target is extensible, return the non-falsy trap result if it contains all
+    of target's non-configurable keys.
+info: >
+    [[OwnPropertyKeys]] ( )
+
+    ...
+    22. If extensibleTarget is true, return trapResult.
+---*/
+
+var target = {};
+
+Object.defineProperty(target, "foo", {
+    configurable: false,
+    enumerable: true,
+    value: true
+});
+
+var p = new Proxy(target, {
+    ownKeys: function() {
+        return ["foo", "bar"];
+    }
+});
+
+var keys = Object.getOwnPropertyNames(p);
+
+assert.sameValue(keys[0], "foo");
+assert.sameValue(keys[1], "bar");
+
+assert.sameValue(keys.length, 2);
diff --git a/test/built-ins/Proxy/ownKeys/not-extensible-missing-keys-throws.js b/test/built-ins/Proxy/ownKeys/not-extensible-missing-keys-throws.js
new file mode 100644
index 0000000000..6da38c0d8b
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/not-extensible-missing-keys-throws.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    If target is not extensible, the result must contain all the keys of the own
+    properties of the target object.
+info: >
+    [[OwnPropertyKeys]] ( )
+
+    ...
+    23. Repeat, for each key that is an element of targetConfigurableKeys,
+        a. If key is not an element of uncheckedResultKeys, throw a TypeError
+        exception.
+---*/
+
+var target = {
+    foo: 1,
+    bar: 2
+};
+
+var p = new Proxy(target, {
+    ownKeys: function() {
+        return ["foo"];
+    }
+});
+
+Object.preventExtensions(target);
+
+assert.throws(TypeError, function() {
+    Object.keys(p);
+});
diff --git a/test/built-ins/Proxy/ownKeys/not-extensible-new-keys-throws.js b/test/built-ins/Proxy/ownKeys/not-extensible-new-keys-throws.js
new file mode 100644
index 0000000000..d00c536f66
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/not-extensible-new-keys-throws.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    If target is not extensible, the result can't contain keys names not
+    contained in the target object.
+info: >
+    [[OwnPropertyKeys]] ( )
+
+    ...
+    24. If uncheckedResultKeys is not empty, throw a TypeError exception.
+---*/
+
+var target = {
+    foo: 1
+};
+
+var p = new Proxy(target, {
+    ownKeys: function() {
+        return ["foo", "bar"];
+    }
+});
+
+Object.preventExtensions(target);
+
+assert.throws(TypeError, function() {
+    Object.keys(p);
+});
diff --git a/test/built-ins/Proxy/ownKeys/not-extensible-return-keys.js b/test/built-ins/Proxy/ownKeys/not-extensible-return-keys.js
new file mode 100644
index 0000000000..c1ad2af7de
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/not-extensible-return-keys.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    If target is not extensible, the result must contain all the keys of the own
+    properties of the target object and no other values
+info: >
+    [[OwnPropertyKeys]] ( )
+
+    ...
+    25. Return trapResult.
+---*/
+
+var target = {
+    foo: 1,
+    bar: 2
+};
+
+var p = new Proxy(target, {
+    ownKeys: function() {
+        return ["foo", "bar"];
+    }
+});
+
+Object.preventExtensions(target);
+
+var keys = Object.keys(p);
+
+assert.sameValue(keys[0], "foo");
+assert.sameValue(keys[1], "bar");
+
+assert.sameValue(keys.length, 2);
diff --git a/test/built-ins/Proxy/ownKeys/null-handler.js b/test/built-ins/Proxy/ownKeys/null-handler.js
new file mode 100644
index 0000000000..91e1b224ac
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/null-handler.js
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    [[OwnPropertyKeys]] ( )
+
+    2. If handler is null, throw a TypeError exception.
+---*/
+
+var p = Proxy.revocable({}, {});
+
+p.revoke();
+
+assert.throws(TypeError, function() {
+    Object.keys(p.proxy);
+});
diff --git a/test/built-ins/Proxy/ownKeys/return-all-non-configurable-keys.js b/test/built-ins/Proxy/ownKeys/return-all-non-configurable-keys.js
new file mode 100644
index 0000000000..a8e4e9958a
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/return-all-non-configurable-keys.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    The result List must contain the keys of all non-configurable own properties
+    of the target object.
+info: >
+    [[OwnPropertyKeys]] ( )
+
+    ...
+    21. Repeat, for each key that is an element of targetNonconfigurableKeys,
+        a. If key is not an element of uncheckedResultKeys, throw a TypeError
+        exception.
+---*/
+
+var target = {
+    foo: 1
+};
+
+Object.defineProperty(target, "attr", {
+    configurable: false,
+    enumerable: true,
+    value: true
+});
+
+var p = new Proxy(target, {
+    ownKeys: function() {
+        return ["foo"];
+    }
+});
+
+assert.throws(TypeError, function() {
+    Object.keys(p);
+});
diff --git a/test/built-ins/Proxy/ownKeys/return-is-abrupt.js b/test/built-ins/Proxy/ownKeys/return-is-abrupt.js
new file mode 100644
index 0000000000..a95adc4111
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/return-is-abrupt.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    Trap returns abrupt.
+info: >
+    [[OwnPropertyKeys]] ( )
+
+    ...
+    8. Let trapResultArray be Call(trap, handler, «target»).
+    9. Let trapResult be CreateListFromArrayLike(trapResultArray, «‍String, Symbol»).
+        7.3.17 CreateListFromArrayLike (obj [, elementTypes] )
+
+        1. ReturnIfAbrupt(obj).
+    ...
+includes: [Test262Error.js]
+---*/
+
+var p = new Proxy({}, {
+    ownKeys: function() {
+        throw new Test262Error();
+    }
+});
+
+assert.throws(Test262Error, function() {
+    Object.keys(p);
+});
diff --git a/test/built-ins/Proxy/ownKeys/return-not-list-object-throws.js b/test/built-ins/Proxy/ownKeys/return-not-list-object-throws.js
new file mode 100644
index 0000000000..147b0b05d6
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/return-not-list-object-throws.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    If return is not a list object, throw a TypeError exception
+info: >
+    [[OwnPropertyKeys]] ( )
+
+    8. Let trapResultArray be Call(trap, handler, «target»).
+    9. Let trapResult be CreateListFromArrayLike(trapResultArray, «‍String,
+    Symbol»).
+    ...
+        7.3.17 CreateListFromArrayLike (obj [, elementTypes] )
+            3. If Type(obj) is not Object, throw a TypeError exception.
+features: [Symbol]
+---*/
+
+var target = {};
+var p = new Proxy(target, {
+    ownKeys: function() {
+        return undefined;
+    }
+});
+
+assert.throws(TypeError, function() {
+    Object.keys(p);
+});
diff --git a/test/built-ins/Proxy/ownKeys/trap-is-not-callable.js b/test/built-ins/Proxy/ownKeys/trap-is-not-callable.js
new file mode 100644
index 0000000000..417b675d1b
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/trap-is-not-callable.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    Trap is not callable.
+info: >
+    [[OwnPropertyKeys]] ( )
+
+    5. Let trap be GetMethod(handler, "ownKeys").
+    ...
+
+    7.3.9 GetMethod (O, P)
+
+    5. If IsCallable(func) is false, throw a TypeError exception.
+---*/
+
+var p = new Proxy({attr:1}, {
+    ownKeys: {}
+});
+
+assert.throws(TypeError, function() {
+    Object.keys(p);
+});
diff --git a/test/built-ins/Proxy/ownKeys/trap-is-undefined.js b/test/built-ins/Proxy/ownKeys/trap-is-undefined.js
new file mode 100644
index 0000000000..ec95ac21b8
--- /dev/null
+++ b/test/built-ins/Proxy/ownKeys/trap-is-undefined.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 9.5.12
+description: >
+    [[OwnPropertyKeys]] ( )
+
+    7. If trap is undefined, then Return target.[[OwnPropertyKeys]]()
+---*/
+
+var target = {
+    foo: 1,
+    bar: 2
+};
+var p = new Proxy(target, {});
+
+var keys = Object.keys(p);
+
+assert.sameValue(keys[0], "foo");
+assert.sameValue(keys[1], "bar");
+
+assert.sameValue(keys.length, 2);
-- 
GitLab