Index: test/mjsunit/harmony/proxies-delete-property.js |
diff --git a/test/mjsunit/harmony/proxies-delete-property.js b/test/mjsunit/harmony/proxies-delete-property.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..27f9c059ccd6815cf4481d11ae33fe563ba3ec0c |
--- /dev/null |
+++ b/test/mjsunit/harmony/proxies-delete-property.js |
@@ -0,0 +1,190 @@ |
+// 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 --harmony-reflect |
+ |
+ |
+var properties = |
+ ["bla", "0", 1, Symbol(), {[Symbol.toPrimitive]() {return "a"}}]; |
+ |
+ |
+function TestForwarding(handler, myDelete, shouldThrow) { |
+ var target = {}; |
+ var proxy = new Proxy(target, handler); |
+ |
+ assertFalse(target.hasOwnProperty("doesnotexist")); |
+ assertTrue(myDelete(proxy, "doesnotexist")); |
+ |
+ for (p of properties) { |
+ target[p] = 42; |
+ assertTrue(myDelete(proxy, p)); |
+ assertFalse(target.hasOwnProperty(p)); |
+ } |
+ |
+ for (p of properties) { |
+ Object.defineProperty(target, p, {value: 42, configurable: false}); |
+ if (shouldThrow) { |
+ assertThrows(() => myDelete(proxy, p), TypeError); |
+ } else { |
+ assertFalse(myDelete(proxy, p)); |
+ } |
+ assertTrue(target.hasOwnProperty(p)); |
+ } |
+}; |
+ |
+ |
+(function () { |
+ // No trap. |
rossberg
2015/11/25 17:53:35
Nit: why not make that the function name (here and
|
+ |
+ var handler = {}; |
+ |
+ TestForwarding(handler, |
+ (o, p) => delete o[p], false); |
+ TestForwarding(handler, |
+ (o, p) => Reflect.deleteProperty(o, p), false); |
+ TestForwarding(handler, |
+ (o, p) => {"use strict"; return delete o[p]}, true); |
+ TestForwarding(handler, |
+ (o, p) => {"use strict"; return Reflect.deleteProperty(o, p)}, false); |
+})(); |
+ |
+ |
+(function () { |
+ // "Undefined" trap. |
+ |
+ var handler = { deleteProperty: null }; |
+ |
+ TestForwarding(handler, |
+ (o, p) => delete o[p], false); |
+ TestForwarding(handler, |
+ (o, p) => Reflect.deleteProperty(o, p), false); |
+ TestForwarding(handler, |
+ (o, p) => {"use strict"; return delete o[p]}, true); |
+ TestForwarding(handler, |
+ (o, p) => {"use strict"; return Reflect.deleteProperty(o, p)}, false); |
+})(); |
+ |
+ |
+(function () { |
+ // Invalid trap. |
+ |
+ var target = {}; |
+ var handler = { deleteProperty: true }; |
+ var proxy = new Proxy(target, handler); |
+ |
+ assertThrows(() => delete proxy[0], TypeError); |
+ assertThrows(() => Reflect.deleteProperty(proxy, 0), TypeError); |
+})(); |
+ |
+ |
+function TestTrappingTrueish(myDelete) { |
+ var handler = { deleteProperty() {return 42} }; |
+ var target = {}; |
+ var proxy = new Proxy(target, handler); |
+ |
+ // Trap returns trueish and target doesn't own property. |
+ for (p of properties) { |
+ assertTrue(myDelete(proxy, p)); |
+ } |
+ |
+ // Trap returns trueish and target property is configurable. |
+ for (p of properties) { |
+ target[p] = 42; |
+ assertTrue(myDelete(proxy, p)); |
+ } |
+ |
+ // Trap returns trueish but target property is not configurable. |
+ for (p of properties) { |
+ Object.defineProperty(target, p, {value: 42, configurable: false}); |
+ assertThrows(() => myDelete(proxy, p), TypeError); |
+ } |
+}; |
+ |
+ |
+TestTrappingTrueish( |
+ (o, p) => delete o[p]); |
+TestTrappingTrueish( |
+ (o, p) => Reflect.deleteProperty(o, p)); |
+TestTrappingTrueish( |
+ (o, p) => {"use strict"; return delete o[p]}); |
+TestTrappingTrueish( |
+ (o, p) => {"use strict"; return Reflect.deleteProperty(o, p)}); |
+ |
+ |
+function TestTrappingTrueish2(myDelete) { |
+ var handler = { |
+ deleteProperty(target, p) { |
+ Object.defineProperty(target, p, {configurable: false}); |
+ return 42 |
+ } |
+ }; |
+ var target = {}; |
+ var proxy = new Proxy(target, handler); |
+ |
+ // Trap returns trueish but target property is not configurable. In contrast |
+ // to above, here the target property was configurable before the trap call. |
+ for (p of properties) { |
+ target[p] = 42; |
+ assertThrows(() => myDelete(proxy, p), TypeError); |
+ } |
+}; |
+ |
+ |
+TestTrappingTrueish2( |
+ (o, p) => delete o[p]); |
+TestTrappingTrueish2( |
+ (o, p) => Reflect.deleteProperty(o, p)); |
+TestTrappingTrueish2( |
+ (o, p) => {"use strict"; return delete o[p]}); |
+TestTrappingTrueish2( |
+ (o, p) => {"use strict"; return Reflect.deleteProperty(o, p)}); |
+ |
+ |
+function TestTrappingFalsish(myDelete, shouldThrow) { |
+ var handler = { deleteProperty() {return ""} }; |
+ var target = {}; |
+ var proxy = new Proxy(target, handler); |
+ |
+ var properties = |
+ ["bla", "0", 1, Symbol(), {[Symbol.toPrimitive]() {return "a"}}]; |
+ |
+ // Trap returns falsish and target doesn't own property. |
+ for (p of properties) { |
+ if (shouldThrow) { |
+ assertThrows(() => myDelete(proxy, p), TypeError); |
+ } else { |
+ assertFalse(myDelete(proxy, p)); |
+ } |
+ } |
+ |
+ // Trap returns falsish and target property is configurable. |
+ for (p of properties) { |
+ target[p] = 42; |
+ if (shouldThrow) { |
+ assertThrows(() => myDelete(proxy, p), TypeError); |
+ } else { |
+ assertFalse(myDelete(proxy, p)); |
+ } |
+ } |
+ |
+ // Trap returns falsish and target property is not configurable. |
+ for (p of properties) { |
+ Object.defineProperty(target, p, {value: 42, configurable: false}); |
+ if (shouldThrow) { |
+ assertThrows(() => myDelete(proxy, p), TypeError); |
+ } else { |
+ assertFalse(myDelete(proxy, p)); |
+ } |
+ } |
+}; |
+ |
+ |
+TestTrappingFalsish( |
+ (o, p) => delete o[p], false); |
+TestTrappingFalsish( |
+ (o, p) => Reflect.deleteProperty(o, p), false); |
+TestTrappingFalsish( |
+ (o, p) => {"use strict"; return delete o[p]}, true); |
+TestTrappingFalsish( |
+ (o, p) => {"use strict"; return Reflect.deleteProperty(o, p)}, false); |