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

---
 test/built-ins/Proxy/has/call-in.js           | 32 ++++++++++++++
 .../built-ins/Proxy/has/call-object-create.js | 37 ++++++++++++++++
 test/built-ins/Proxy/has/call-with.js         | 35 +++++++++++++++
 .../Proxy/has/null-handler-using-with.js      | 18 ++++++++
 test/built-ins/Proxy/has/null-handler.js      | 15 +++++++
 ...-false-target-not-extensible-using-with.js | 43 +++++++++++++++++++
 .../has/return-false-target-not-extensible.js | 40 +++++++++++++++++
 ...urn-false-target-prop-exists-using-with.js | 28 ++++++++++++
 .../has/return-false-target-prop-exists.js    | 24 +++++++++++
 ...-targetdesc-not-configurable-using-with.js | 38 ++++++++++++++++
 ...eturn-false-targetdesc-not-configurable.js | 35 +++++++++++++++
 .../Proxy/has/return-is-abrupt-in.js          | 25 +++++++++++
 .../Proxy/has/return-is-abrupt-with.js        | 28 ++++++++++++
 ...turn-true-target-prop-exists-using-with.js | 25 +++++++++++
 .../has/return-true-target-prop-exists.js     | 19 ++++++++
 .../return-true-without-same-target-prop.js   | 16 +++++++
 .../has/trap-is-not-callable-using-with.js    | 30 +++++++++++++
 .../Proxy/has/trap-is-not-callable.js         | 27 ++++++++++++
 .../Proxy/has/trap-is-undefined-using-with.js | 24 +++++++++++
 test/built-ins/Proxy/has/trap-is-undefined.js | 20 +++++++++
 20 files changed, 559 insertions(+)
 create mode 100644 test/built-ins/Proxy/has/call-in.js
 create mode 100644 test/built-ins/Proxy/has/call-object-create.js
 create mode 100644 test/built-ins/Proxy/has/call-with.js
 create mode 100644 test/built-ins/Proxy/has/null-handler-using-with.js
 create mode 100644 test/built-ins/Proxy/has/null-handler.js
 create mode 100644 test/built-ins/Proxy/has/return-false-target-not-extensible-using-with.js
 create mode 100644 test/built-ins/Proxy/has/return-false-target-not-extensible.js
 create mode 100644 test/built-ins/Proxy/has/return-false-target-prop-exists-using-with.js
 create mode 100644 test/built-ins/Proxy/has/return-false-target-prop-exists.js
 create mode 100644 test/built-ins/Proxy/has/return-false-targetdesc-not-configurable-using-with.js
 create mode 100644 test/built-ins/Proxy/has/return-false-targetdesc-not-configurable.js
 create mode 100644 test/built-ins/Proxy/has/return-is-abrupt-in.js
 create mode 100644 test/built-ins/Proxy/has/return-is-abrupt-with.js
 create mode 100644 test/built-ins/Proxy/has/return-true-target-prop-exists-using-with.js
 create mode 100644 test/built-ins/Proxy/has/return-true-target-prop-exists.js
 create mode 100644 test/built-ins/Proxy/has/return-true-without-same-target-prop.js
 create mode 100644 test/built-ins/Proxy/has/trap-is-not-callable-using-with.js
 create mode 100644 test/built-ins/Proxy/has/trap-is-not-callable.js
 create mode 100644 test/built-ins/Proxy/has/trap-is-undefined-using-with.js
 create mode 100644 test/built-ins/Proxy/has/trap-is-undefined.js

diff --git a/test/built-ins/Proxy/has/call-in.js b/test/built-ins/Proxy/has/call-in.js
new file mode 100644
index 0000000000..380a3c1a20
--- /dev/null
+++ b/test/built-ins/Proxy/has/call-in.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.7
+description: >
+    A `in` check trigger trap.call(handler, target, P);
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)).
+    ...
+---*/
+
+var _handler, _target, _prop;
+var target = {};
+var handler = {
+    has: function(t, prop) {
+        _handler = this;
+        _target = t;
+        _prop = prop;
+
+        return prop in t;
+    }
+};
+var p = new Proxy(target, handler);
+
+"attr" in p;
+
+assert.sameValue(_handler, handler, "handler is context");
+assert.sameValue(_target, target, "target is the first parameter");
+assert.sameValue(_prop, "attr", "given prop is the second paramter");
diff --git a/test/built-ins/Proxy/has/call-object-create.js b/test/built-ins/Proxy/has/call-object-create.js
new file mode 100644
index 0000000000..90f5199c8f
--- /dev/null
+++ b/test/built-ins/Proxy/has/call-object-create.js
@@ -0,0 +1,37 @@
+// 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.7
+description: >
+    `.. in Object.create(proxy)` triggers trap.call(handler, target, P);
+info: >
+    [[HasProperty]] (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, "has").
+    ...
+    9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)).
+    ...
+---*/
+
+var _handler, _target, _prop;
+var target = {};
+var handler = {
+    has: function(t, prop) {
+        _handler = this;
+        _target = t;
+        _prop = prop;
+
+        return false;
+    }
+};
+var p = new Proxy(target, handler);
+
+"attr" in Object.create(p);
+
+assert.sameValue(_handler, handler, "handler is context");
+assert.sameValue(_target, target, "target is the first parameter");
+assert.sameValue(_prop, "attr", "given prop is the second paramter");
diff --git a/test/built-ins/Proxy/has/call-with.js b/test/built-ins/Proxy/has/call-with.js
new file mode 100644
index 0000000000..53f92ca699
--- /dev/null
+++ b/test/built-ins/Proxy/has/call-with.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.7
+description: >
+    A `with` variable check trigger trap.call(handler, target, P);
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)).
+    ...
+flags: [noStrict]
+---*/
+
+var _handler, _target, _prop;
+var target = {};
+var handler = {
+    has: function(t, prop) {
+        _handler = this;
+        _target = t;
+        _prop = prop;
+
+        return true;
+    }
+};
+var p = new Proxy(target, handler);
+
+with (p) {
+    (attr);
+}
+
+assert.sameValue(_handler, handler);
+assert.sameValue(_target, target);
+assert.sameValue(_prop, "attr");
diff --git a/test/built-ins/Proxy/has/null-handler-using-with.js b/test/built-ins/Proxy/has/null-handler-using-with.js
new file mode 100644
index 0000000000..06bd4eaf0e
--- /dev/null
+++ b/test/built-ins/Proxy/has/null-handler-using-with.js
@@ -0,0 +1,18 @@
+// 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.7
+description: >
+    Throws a TypeError exception if handler is null.
+flags: [noStrict]
+---*/
+
+var p = Proxy.revocable({}, {});
+
+p.revoke();
+
+assert.throws(TypeError, function() {
+    with (p.proxy) {
+        (attr);
+    }
+});
diff --git a/test/built-ins/Proxy/has/null-handler.js b/test/built-ins/Proxy/has/null-handler.js
new file mode 100644
index 0000000000..90deca388b
--- /dev/null
+++ b/test/built-ins/Proxy/has/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.7
+description: >
+    Throws a TypeError exception if handler is null.
+---*/
+
+var p = Proxy.revocable({}, {});
+
+p.revoke();
+
+assert.throws(TypeError, function() {
+    "attr" in p.proxy;
+});
diff --git a/test/built-ins/Proxy/has/return-false-target-not-extensible-using-with.js b/test/built-ins/Proxy/has/return-false-target-not-extensible-using-with.js
new file mode 100644
index 0000000000..6bc735aba5
--- /dev/null
+++ b/test/built-ins/Proxy/has/return-false-target-not-extensible-using-with.js
@@ -0,0 +1,43 @@
+// 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.7
+description: >
+    A property cannot be reported as non-existent, if it exists as an own
+    property of the target object and the target object is not extensible.
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    11. If booleanTrapResult is false, then
+        a. Let targetDesc be target.[[GetOwnProperty]](P).
+        b. ReturnIfAbrupt(targetDesc).
+        c. If targetDesc is not undefined, then
+            ...
+            ii. Let extensibleTarget be IsExtensible(target).
+            ...
+            iv. If extensibleTarget is false, throw a TypeError exception.
+    ...
+flags: [noStrict]
+---*/
+
+var target = {};
+var handler = {
+    has: function(t, prop) {
+        return 0;
+    }
+};
+var p = new Proxy(target, handler);
+
+Object.defineProperty(target, 'attr', {
+    configurable: true,
+    value: 1
+});
+
+Object.preventExtensions(target);
+
+assert.throws(TypeError, function() {
+    with (p) {
+        (attr);
+    }
+});
diff --git a/test/built-ins/Proxy/has/return-false-target-not-extensible.js b/test/built-ins/Proxy/has/return-false-target-not-extensible.js
new file mode 100644
index 0000000000..731e22d46a
--- /dev/null
+++ b/test/built-ins/Proxy/has/return-false-target-not-extensible.js
@@ -0,0 +1,40 @@
+// 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.7
+description: >
+    A property cannot be reported as non-existent, if it exists as an own
+    property of the target object and the target object is not extensible.
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    11. If booleanTrapResult is false, then
+        a. Let targetDesc be target.[[GetOwnProperty]](P).
+        b. ReturnIfAbrupt(targetDesc).
+        c. If targetDesc is not undefined, then
+            ...
+            ii. Let extensibleTarget be IsExtensible(target).
+            ...
+            iv. If extensibleTarget is false, throw a TypeError exception.
+    ...
+---*/
+
+var target = {};
+var handler = {
+    has: function(t, prop) {
+        return 0;
+    }
+};
+var p = new Proxy(target, handler);
+
+Object.defineProperty(target, "attr", {
+    configurable: true,
+    value: 1
+});
+
+Object.preventExtensions(target);
+
+assert.throws(TypeError, function() {
+    "attr" in p;
+});
diff --git a/test/built-ins/Proxy/has/return-false-target-prop-exists-using-with.js b/test/built-ins/Proxy/has/return-false-target-prop-exists-using-with.js
new file mode 100644
index 0000000000..94f253acb1
--- /dev/null
+++ b/test/built-ins/Proxy/has/return-false-target-prop-exists-using-with.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.7
+description: >
+    The result of [[HasProperty]] is a Boolean value and will affect has
+    checkings. False returned when target property exists;
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    12. Return booleanTrapResult.
+flags: [noStrict]
+---*/
+
+var target = {
+    attr: 1
+};
+var p = new Proxy(target, {
+    has: function(t, prop) {
+        return false;
+    }
+});
+
+var attr = 0;
+with (p) {
+    assert.sameValue(attr, 0);
+}
diff --git a/test/built-ins/Proxy/has/return-false-target-prop-exists.js b/test/built-ins/Proxy/has/return-false-target-prop-exists.js
new file mode 100644
index 0000000000..eff332a66a
--- /dev/null
+++ b/test/built-ins/Proxy/has/return-false-target-prop-exists.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.7
+description: >
+    The result of [[HasProperty]] is a Boolean value and will affect has
+    checkings. False returned when target property exists;
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    12. Return booleanTrapResult.
+---*/
+
+var target = {
+    attr: 1
+};
+var p = new Proxy(target, {
+    has: function(t, prop) {
+        return false;
+    }
+});
+
+assert.sameValue(("attr" in p), false);
diff --git a/test/built-ins/Proxy/has/return-false-targetdesc-not-configurable-using-with.js b/test/built-ins/Proxy/has/return-false-targetdesc-not-configurable-using-with.js
new file mode 100644
index 0000000000..2ecf01cd6f
--- /dev/null
+++ b/test/built-ins/Proxy/has/return-false-targetdesc-not-configurable-using-with.js
@@ -0,0 +1,38 @@
+// 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.7
+description: >
+    A property cannot be reported as non-existent, if it exists as a
+    non-configurable own property of the target object.
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    11. If booleanTrapResult is false, then
+        ...
+        c. If targetDesc is not undefined, then
+            i. If targetDesc.[[Configurable]] is false, throw a TypeError
+            exception.
+    ...
+flags: [noStrict]
+---*/
+
+var target = {};
+var handler = {
+    has: function(t, prop) {
+        return 0;
+    }
+};
+var p = new Proxy(target, handler);
+
+Object.defineProperty(target, "attr", {
+    configurable: false,
+    value: 1
+});
+
+assert.throws(TypeError, function() {
+    with (p) {
+        (attr);
+    }
+});
diff --git a/test/built-ins/Proxy/has/return-false-targetdesc-not-configurable.js b/test/built-ins/Proxy/has/return-false-targetdesc-not-configurable.js
new file mode 100644
index 0000000000..dce7a6d390
--- /dev/null
+++ b/test/built-ins/Proxy/has/return-false-targetdesc-not-configurable.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.7
+description: >
+    A property cannot be reported as non-existent, if it exists as a
+    non-configurable own property of the target object.
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    11. If booleanTrapResult is false, then
+        ...
+        c. If targetDesc is not undefined, then
+            i. If targetDesc.[[Configurable]] is false, throw a TypeError
+            exception.
+    ...
+---*/
+
+var target = {};
+var handler = {
+    has: function(t, prop) {
+        return 0;
+    }
+};
+var p = new Proxy(target, handler);
+
+Object.defineProperty(target, "attr", {
+    configurable: false,
+    value: 1
+});
+
+assert.throws(TypeError, function() {
+    "attr" in p;
+});
diff --git a/test/built-ins/Proxy/has/return-is-abrupt-in.js b/test/built-ins/Proxy/has/return-is-abrupt-in.js
new file mode 100644
index 0000000000..a9ae9f31ee
--- /dev/null
+++ b/test/built-ins/Proxy/has/return-is-abrupt-in.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.7
+description: >
+    Trap returns abrupt. Using `prop in obj`.
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)).
+    10. ReturnIfAbrupt(booleanTrapResult).
+    ...
+includes: [Test262Error.js]
+---*/
+
+var p = new Proxy({}, {
+    has: function() {
+        throw new Test262Error();
+    }
+});
+
+assert.throws(Test262Error, function() {
+    "attr" in p;
+});
diff --git a/test/built-ins/Proxy/has/return-is-abrupt-with.js b/test/built-ins/Proxy/has/return-is-abrupt-with.js
new file mode 100644
index 0000000000..97ff469cd2
--- /dev/null
+++ b/test/built-ins/Proxy/has/return-is-abrupt-with.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.7
+description: >
+    Trap returns abrupt. Using `with`.
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)).
+    10. ReturnIfAbrupt(booleanTrapResult).
+    ...
+flags: [noStrict]
+includes: [Test262Error.js]
+---*/
+
+var p = new Proxy({}, {
+    has: function() {
+        throw new Test262Error();
+    }
+});
+
+assert.throws(Test262Error, function() {
+    with (p) {
+        (attr);
+    }
+});
diff --git a/test/built-ins/Proxy/has/return-true-target-prop-exists-using-with.js b/test/built-ins/Proxy/has/return-true-target-prop-exists-using-with.js
new file mode 100644
index 0000000000..145073b720
--- /dev/null
+++ b/test/built-ins/Proxy/has/return-true-target-prop-exists-using-with.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.7
+description: >
+    The result of [[HasProperty]] is a Boolean value and will affect has
+    checkings. True returned when target property exists;
+flags: [noStrict]
+---*/
+
+var target = {
+    attr: 1
+};
+var p = new Proxy(target, {
+    has: function(t, prop) {
+        if (prop !== "assert") {
+            return 42;
+        }
+    }
+});
+
+var attr = 0;
+with (p) {
+    assert.sameValue(attr, 1);
+}
diff --git a/test/built-ins/Proxy/has/return-true-target-prop-exists.js b/test/built-ins/Proxy/has/return-true-target-prop-exists.js
new file mode 100644
index 0000000000..9c5a409da6
--- /dev/null
+++ b/test/built-ins/Proxy/has/return-true-target-prop-exists.js
@@ -0,0 +1,19 @@
+// 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.7
+description: >
+    The result of [[HasProperty]] is a Boolean value and will affect has
+    checkings. True returned when target property exists;
+---*/
+
+var target = {
+    attr: 1
+};
+var p = new Proxy(target, {
+    has: function(t, prop) {
+        return 1;
+    }
+});
+
+assert.sameValue(("attr" in p), true);
diff --git a/test/built-ins/Proxy/has/return-true-without-same-target-prop.js b/test/built-ins/Proxy/has/return-true-without-same-target-prop.js
new file mode 100644
index 0000000000..9186074a7d
--- /dev/null
+++ b/test/built-ins/Proxy/has/return-true-without-same-target-prop.js
@@ -0,0 +1,16 @@
+// 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.7
+description: >
+    The result of [[HasProperty]] is a Boolean value and will affect has
+    checkings. True returned when target property doesn't exists;
+---*/
+
+var p = new Proxy({}, {
+    has: function(t, prop) {
+        return true;
+    }
+});
+
+assert.sameValue(("attr" in p), true);
diff --git a/test/built-ins/Proxy/has/trap-is-not-callable-using-with.js b/test/built-ins/Proxy/has/trap-is-not-callable-using-with.js
new file mode 100644
index 0000000000..ae837ea9e0
--- /dev/null
+++ b/test/built-ins/Proxy/has/trap-is-not-callable-using-with.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.7
+description: >
+    Throws a TypeError exception if trap is not callable.
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    6. Let trap be GetMethod(handler, "has").
+    ...
+        7.3.9 GetMethod (O, P)
+        ...
+        2. Let func be GetV(O, P).
+        5. If IsCallable(func) is false, throw a TypeError exception.
+        ...
+flags: [noStrict]
+---*/
+
+var target = {};
+var p = new Proxy(target, {
+    has: {}
+});
+
+assert.throws(TypeError, function() {
+    with (p) {
+        (attr);
+    }
+});
diff --git a/test/built-ins/Proxy/has/trap-is-not-callable.js b/test/built-ins/Proxy/has/trap-is-not-callable.js
new file mode 100644
index 0000000000..7547fd398c
--- /dev/null
+++ b/test/built-ins/Proxy/has/trap-is-not-callable.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.7
+description: >
+    Throws a TypeError exception if trap is not callable.
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    6. Let trap be GetMethod(handler, "has").
+    ...
+        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, {
+    has: {}
+});
+
+assert.throws(TypeError, function() {
+    "attr" in p;
+});
diff --git a/test/built-ins/Proxy/has/trap-is-undefined-using-with.js b/test/built-ins/Proxy/has/trap-is-undefined-using-with.js
new file mode 100644
index 0000000000..2bba67f354
--- /dev/null
+++ b/test/built-ins/Proxy/has/trap-is-undefined-using-with.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.7
+description: >
+    Return target.[[HasProperty]](P) if trap is undefined.
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    8. If trap is undefined, then
+        a. Return target.[[HasProperty]](P).
+    ...
+flags: [noStrict]
+---*/
+
+var target = Object.create(Array.prototype);
+var p = new Proxy(target, {});
+
+var foo = 3;
+with (target) {
+    assert.sameValue(length, 0);
+    assert.sameValue(foo, 3);
+}
diff --git a/test/built-ins/Proxy/has/trap-is-undefined.js b/test/built-ins/Proxy/has/trap-is-undefined.js
new file mode 100644
index 0000000000..1fa9071783
--- /dev/null
+++ b/test/built-ins/Proxy/has/trap-is-undefined.js
@@ -0,0 +1,20 @@
+// 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.7
+description: >
+    Return target.[[HasProperty]](P) if trap is undefined.
+info: >
+    [[HasProperty]] (P)
+
+    ...
+    8. If trap is undefined, then
+        a. Return target.[[HasProperty]](P).
+    ...
+---*/
+
+var target = Object.create(Array.prototype);
+var p = new Proxy(target, {});
+
+assert.sameValue(("foo" in p), false);
+assert.sameValue(("length" in p), true);
-- 
GitLab