From a2f0f2888d2a175be91834e42e690b1393522c48 Mon Sep 17 00:00:00 2001
From: Leonardo Balter <leonardo.balter@gmail.com>
Date: Tue, 2 Jun 2015 18:55:12 -0400
Subject: [PATCH] Proxy: getOwnPropertyDescriptor

---
 .../call-parameters.js                        | 32 +++++++++++++
 .../getOwnPropertyDescriptor/null-handler.js  | 15 ++++++
 ...t-is-undefined-target-is-not-extensible.js | 32 +++++++++++++
 ...ndefined-targetdesc-is-not-configurable.js | 33 +++++++++++++
 ...lt-is-undefined-targetdesc-is-undefined.js | 31 ++++++++++++
 .../result-is-undefined.js                    | 28 +++++++++++
 ...result-type-is-not-object-nor-undefined.js | 48 +++++++++++++++++++
 .../resultdesc-is-invalid-descriptor.js       | 31 ++++++++++++
 ...configurable-targetdesc-is-configurable.js | 39 +++++++++++++++
 ...ot-configurable-targetdesc-is-undefined.js | 47 ++++++++++++++++++
 .../resultdesc-return-configurable.js         | 30 ++++++++++++
 .../resultdesc-return-not-configurable.js     | 29 +++++++++++
 .../return-is-abrupt.js                       | 25 ++++++++++
 .../trap-is-not-callable.js                   | 30 ++++++++++++
 .../trap-is-undefined.js                      | 25 ++++++++++
 15 files changed, 475 insertions(+)
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/call-parameters.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/null-handler.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-target-is-not-extensible.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-not-configurable.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-undefined.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/result-type-is-not-object-nor-undefined.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-invalid-descriptor.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-configurable.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-undefined.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-configurable.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-not-configurable.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/return-is-abrupt.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-not-callable.js
 create mode 100644 test/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-undefined.js

diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/call-parameters.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/call-parameters.js
new file mode 100644
index 0000000000..1e785ce64f
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/call-parameters.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.5
+description: >
+    Trap is called with hander context and parameters are target and P
+info: >
+    [[GetOwnProperty]] (P)
+
+    ...
+    9. Let trapResultObj be Call(trap, handler, «target, P»).
+    ...
+---*/
+
+var _target, _handler, _prop;
+var target = {attr: 1};
+var handler = {
+    getOwnPropertyDescriptor: function(t, prop) {
+        _target = t;
+        _handler = this;
+        _prop = prop;
+
+        return Object.getOwnPropertyDescriptor(t);
+    }
+};
+var p = new Proxy(target, handler);
+
+Object.getOwnPropertyDescriptor(p, "attr");
+
+assert.sameValue(_handler, handler);
+assert.sameValue(_target, target);
+assert.sameValue(_prop, "attr");
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/null-handler.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/null-handler.js
new file mode 100644
index 0000000000..a908e072b8
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/null-handler.js
@@ -0,0 +1,15 @@
+// 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.5
+description: >
+    Throws a TypeError exception if handler is null.
+---*/
+
+var p = Proxy.revocable({}, {});
+
+p.revoke();
+
+assert.throws(TypeError, function() {
+    Object.getOwnPropertyDescriptor(p.proxy);
+});
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-target-is-not-extensible.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-target-is-not-extensible.js
new file mode 100644
index 0000000000..ababda6b3e
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-target-is-not-extensible.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.5
+description: >
+    Throws a TypeError exception if trap result is undefined and target is not
+    extensible
+info: >
+    [[GetOwnProperty]] (P)
+
+    ...
+    14. If trapResultObj is undefined, then
+        ...
+        e. If ToBoolean(extensibleTarget) is false, throw a TypeError exception.
+    ...
+---*/
+
+var target = {
+    foo: 1
+};
+
+var p = new Proxy(target, {
+    getOwnPropertyDescriptor: function(t, prop) {
+        return;
+    }
+});
+
+Object.preventExtensions(target);
+
+assert.throws(TypeError, function() {
+    Object.getOwnPropertyDescriptor(p, "foo");
+});
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-not-configurable.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-not-configurable.js
new file mode 100644
index 0000000000..fe88f63afc
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-not-configurable.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.5
+description: >
+    Throws a TypeError exception if trap result is undefined and target property
+    descriptor is not configurable
+info: >
+    [[GetOwnProperty]] (P)
+
+    ...
+    14. If trapResultObj is undefined, then
+        ...
+        b. If targetDesc.[[Configurable]] is false, throw a TypeError exception.
+    ...
+---*/
+
+var target = {};
+Object.defineProperty(target, "foo", {
+    configurable: false,
+    enumerable: false,
+    value: 1
+});
+
+var p = new Proxy(target, {
+    getOwnPropertyDescriptor: function(t, prop) {
+        return;
+    }
+});
+
+assert.throws(TypeError, function() {
+    Object.getOwnPropertyDescriptor(p, "foo");
+});
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-undefined.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-undefined.js
new file mode 100644
index 0000000000..814bbf587a
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-undefined.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.5
+description: >
+    Throws a TypeError exception if trap result is undefined and target property
+    descriptor is undefined.
+info: >
+    [[GetOwnProperty]] (P)
+
+    ...
+    14. If trapResultObj is undefined, then
+        a. If targetDesc is undefined, return undefined.
+    ...
+---*/
+
+var t = {};
+var trapped;
+var p = new Proxy(t, {
+    getOwnPropertyDescriptor: function(target, prop) {
+        trapped = true;
+        return;
+    }
+});
+
+assert.sameValue(
+    Object.getOwnPropertyDescriptor(p, "attr"),
+    undefined
+);
+
+assert(trapped);
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined.js
new file mode 100644
index 0000000000..0153d6add7
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined.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.5
+description: >
+    Return undefined if trap result is undefined and target is extensible and
+    the target property descriptor is configurable.
+info: >
+    [[GetOwnProperty]] (P)
+
+    ...
+    14. If trapResultObj is undefined, then
+        ...
+        f. Return undefined.
+    ...
+---*/
+
+var target = {
+    attr: 1
+};
+
+var p = new Proxy(target, {
+    getOwnPropertyDescriptor: function(t, prop) {
+        return;
+    }
+});
+
+assert.sameValue(Object.getOwnPropertyDescriptor(p, "attr"), undefined);
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/result-type-is-not-object-nor-undefined.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/result-type-is-not-object-nor-undefined.js
new file mode 100644
index 0000000000..3c31c62c96
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/result-type-is-not-object-nor-undefined.js
@@ -0,0 +1,48 @@
+// 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.5
+description: >
+    Throws a TypeError exception if trap result is neither Object nor Undefined
+info: >
+    [[GetOwnProperty]] (P)
+
+    ...
+    11. If Type(trapResultObj) is neither Object nor Undefined, throw a
+    TypeError exception.
+    ...
+features: [Symbol]
+---*/
+
+var target = {
+    number: 1,
+    symbol: Symbol(),
+    string: '',
+    boolean: true,
+    fn: function() {}
+};
+var p = new Proxy(target, {
+    getOwnPropertyDescriptor: function(t, prop) {
+        return t[prop];
+    }
+});
+
+assert.throws(TypeError, function() {
+    Object.getOwnPropertyDescriptor(p, "number");
+});
+
+assert.throws(TypeError, function() {
+    Object.getOwnPropertyDescriptor(p, "string");
+});
+
+assert.throws(TypeError, function() {
+    Object.getOwnPropertyDescriptor(p, "symbol");
+});
+
+assert.throws(TypeError, function() {
+    Object.getOwnPropertyDescriptor(p, "boolean");
+});
+
+assert.throws(TypeError, function() {
+    Object.getOwnPropertyDescriptor(p, "fn");
+});
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-invalid-descriptor.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-invalid-descriptor.js
new file mode 100644
index 0000000000..6d2396b1aa
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-invalid-descriptor.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.5
+description: >
+    Throws a TypeError exception if trap result and target property descriptors
+    are not compatible.
+info: >
+    [[GetOwnProperty]] (P)
+
+    ...
+    20. Let valid be IsCompatiblePropertyDescriptor (extensibleTarget,
+    resultDesc, targetDesc).
+    21. If valid is false, throw a TypeError exception.
+---*/
+
+var target = {};
+
+var p = new Proxy(target, {
+    getOwnPropertyDescriptor: function(t, prop) {
+        var foo = { bar: 1 };
+
+        return Object.getOwnPropertyDescriptor(foo, "bar");
+    }
+});
+
+Object.preventExtensions(target);
+
+assert.throws(TypeError, function() {
+    Object.getOwnPropertyDescriptor(p, "bar");
+});
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-configurable.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-configurable.js
new file mode 100644
index 0000000000..85e4bd235c
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-configurable.js
@@ -0,0 +1,39 @@
+// 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.5
+description: >
+    Throws a TypeError exception if trap result is not configurable but target
+    property descriptor is configurable.
+info: >
+    [[GetOwnProperty]] (P)
+
+    ...
+    22. If resultDesc.[[Configurable]] is false, then
+        a. If targetDesc is undefined or targetDesc.[[Configurable]] is true,
+        then
+            i. Throw a TypeError exception.
+    ...
+---*/
+
+var target = {
+    bar: 1
+};
+
+var p = new Proxy(target, {
+    getOwnPropertyDescriptor: function(t, prop) {
+        var foo = {};
+
+        Object.defineProperty(foo, "bar", {
+            configurable: false,
+            enumerable: true,
+            value: 1
+        });
+
+        return Object.getOwnPropertyDescriptor(foo, prop);
+    }
+});
+
+assert.throws(TypeError, function() {
+    Object.getOwnPropertyDescriptor(p, "bar");
+});
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-undefined.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-undefined.js
new file mode 100644
index 0000000000..357cc14a66
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-undefined.js
@@ -0,0 +1,47 @@
+// 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.5
+description: >
+    Throws a TypeError exception if trap result is not configurable but target
+    property descriptor is undefined.
+info: >
+    [[GetOwnProperty]] (P)
+
+    ...
+    2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
+    ...
+    5. Let target be the value of the [[ProxyTarget]] internal slot of O.
+    6. Let trap be GetMethod(handler, "getOwnPropertyDescriptor").
+    ...
+    9. Let trapResultObj be Call(trap, handler, «target, P»).
+    ...
+    12. Let targetDesc be target.[[GetOwnProperty]](P).
+    ...
+    17. Let resultDesc be ToPropertyDescriptor(trapResultObj).
+    ...
+    22. If resultDesc.[[Configurable]] is false, then
+        a. If targetDesc is undefined or targetDesc.[[Configurable]] is true, then
+            i. Throw a TypeError exception.
+
+---*/
+
+var target = {};
+
+var p = new Proxy(target, {
+    getOwnPropertyDescriptor: function(t, prop) {
+        var foo = {};
+
+        Object.defineProperty(foo, "bar", {
+            configurable: false,
+            enumerable: true,
+            value: 1
+        });
+
+        return Object.getOwnPropertyDescriptor(foo, prop);
+    }
+});
+
+assert.throws(TypeError, function() {
+    Object.getOwnPropertyDescriptor(p, "bar");
+});
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-configurable.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-configurable.js
new file mode 100644
index 0000000000..13f46ca31b
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-configurable.js
@@ -0,0 +1,30 @@
+// 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.5
+description: >
+    Return descriptor from trap result if it has the same value as the target
+    property descriptor.
+---*/
+
+var target = {};
+var descriptor = {
+    configurable: true,
+    enumerable: true,
+    value: 1
+};
+
+Object.defineProperty(target, "bar", descriptor);
+
+var p = new Proxy(target, {
+    getOwnPropertyDescriptor: function(t, prop) {
+        return Object.getOwnPropertyDescriptor(t, prop);
+    }
+});
+
+var proxyDesc = Object.getOwnPropertyDescriptor(p, "bar");
+
+assert(proxyDesc.configurable);
+assert(proxyDesc.enumerable);
+assert.sameValue(proxyDesc.value, 1);
+assert.sameValue(proxyDesc.writable, false);
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-not-configurable.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-not-configurable.js
new file mode 100644
index 0000000000..cc25cc694b
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-not-configurable.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.5
+description: >
+    Return descriptor from trap result if it has the same value as the target
+    property descriptor and they're not configurable.
+---*/
+
+var target = {};
+
+Object.defineProperty(target, "attr", {
+    configurable: false,
+    enumerable: true,
+    value: 1
+});
+
+var p = new Proxy(target, {
+    getOwnPropertyDescriptor: function(t, prop) {
+        return Object.getOwnPropertyDescriptor(t, prop);
+    }
+});
+
+var proxyDesc = Object.getOwnPropertyDescriptor(p, "attr");
+
+assert.sameValue(proxyDesc.configurable, false);
+assert(proxyDesc.enumerable);
+assert.sameValue(proxyDesc.value, 1);
+assert.sameValue(proxyDesc.writable, false);
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/return-is-abrupt.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/return-is-abrupt.js
new file mode 100644
index 0000000000..c98e60bd09
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/return-is-abrupt.js
@@ -0,0 +1,25 @@
+// 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.5
+description: >
+    Trap returns abrupt.
+info: >
+    [[GetOwnProperty]] (P)
+
+    ...
+    9. Let trapResultObj be Call(trap, handler, «target, P»).
+    10. ReturnIfAbrupt(trapResultObj).
+    ...
+includes: [Test262Error.js]
+---*/
+
+var p = new Proxy({}, {
+    getOwnPropertyDescriptor: function(t, prop) {
+        throw new Test262Error();
+    }
+});
+
+assert.throws(Test262Error, function() {
+    Object.getOwnPropertyDescriptor(p, "attr");
+});
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-not-callable.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-not-callable.js
new file mode 100644
index 0000000000..5fc459e59b
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-not-callable.js
@@ -0,0 +1,30 @@
+// 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.5
+description: >
+    Throws a TypeError exception if trap is not callable.
+info: >
+    [[GetOwnProperty]] (P)
+
+    ...
+    2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
+    ...
+    5. Let target be the value of the [[ProxyTarget]] internal slot of O.
+    6. Let trap be GetMethod(handler, "getOwnPropertyDescriptor").
+    ...
+        7.3.9 GetMethod (O, P)
+        ...
+        2. Let func be GetV(O, P).
+        5. If IsCallable(func) is false, throw a TypeError exception.
+        ...
+---*/
+
+var target = {};
+var p = new Proxy(target, {
+    getOwnPropertyDescriptor: {}
+});
+
+assert.throws(TypeError, function() {
+    Object.getOwnPropertyDescriptor(p, "foo");
+});
diff --git a/test/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-undefined.js b/test/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-undefined.js
new file mode 100644
index 0000000000..7e2e472378
--- /dev/null
+++ b/test/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-undefined.js
@@ -0,0 +1,25 @@
+// 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.5
+description: >
+    Return target.[[GetOwnProperty]](P) if trap is undefined.
+info: >
+    [[GetOwnProperty]] (P)
+
+    ...
+    8. If trap is undefined, then
+        a. Return target.[[GetOwnProperty]](P).
+    ...
+includes: [propertyHelper.js]
+---*/
+
+var target = {attr: 1};
+var p = new Proxy(target, {});
+
+var proxyDesc = Object.getOwnPropertyDescriptor(p, "attr");
+
+verifyEqualTo(p, "attr", 1);
+verifyWritable(p, "attr");
+verifyEnumerable(p, "attr");
+verifyConfigurable(p, "attr");
-- 
GitLab