• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5
6var properties =
7    ["bla", "0", 1, Symbol(), {[Symbol.toPrimitive]() {return "a"}}];
8
9
10function TestForwarding(handler, myDelete, shouldThrow) {
11  var target = {};
12  var proxy = new Proxy(target, handler);
13
14  assertFalse(target.hasOwnProperty("doesnotexist"));
15  assertTrue(myDelete(proxy, "doesnotexist"));
16
17  for (p of properties) {
18    target[p] = 42;
19    assertTrue(myDelete(proxy, p));
20    assertFalse(target.hasOwnProperty(p));
21  }
22
23  for (p of properties) {
24    Object.defineProperty(target, p, {value: 42, configurable: false});
25    if (shouldThrow) {
26      assertThrows(() => myDelete(proxy, p), TypeError);
27    } else {
28      assertFalse(myDelete(proxy, p));
29    }
30    assertTrue(target.hasOwnProperty(p));
31  }
32};
33
34
35(function () {
36  // No trap.
37
38  var handler = {};
39
40  TestForwarding(handler,
41      (o, p) => delete o[p], false);
42  TestForwarding(handler,
43      (o, p) => Reflect.deleteProperty(o, p), false);
44  TestForwarding(handler,
45      (o, p) => {"use strict"; return delete o[p]}, true);
46  TestForwarding(handler,
47      (o, p) => {"use strict"; return Reflect.deleteProperty(o, p)}, false);
48})();
49
50
51(function () {
52  // "Undefined" trap.
53
54  var handler = { deleteProperty: null };
55
56  TestForwarding(handler,
57      (o, p) => delete o[p], false);
58  TestForwarding(handler,
59      (o, p) => Reflect.deleteProperty(o, p), false);
60  TestForwarding(handler,
61      (o, p) => {"use strict"; return delete o[p]}, true);
62  TestForwarding(handler,
63      (o, p) => {"use strict"; return Reflect.deleteProperty(o, p)}, false);
64})();
65
66
67(function () {
68  // Invalid trap.
69
70  var target = {};
71  var handler = { deleteProperty: true };
72  var proxy = new Proxy(target, handler);
73
74  assertThrows(() => delete proxy[0], TypeError);
75  assertThrows(() => Reflect.deleteProperty(proxy, 0), TypeError);
76})();
77
78
79function TestTrappingTrueish(myDelete) {
80  var handler = { deleteProperty() {return 42} };
81  var target = {};
82  var proxy = new Proxy(target, handler);
83
84  // Trap returns trueish and target doesn't own property.
85  for (p of properties) {
86    assertTrue(myDelete(proxy, p));
87  }
88
89  // Trap returns trueish and target property is configurable.
90  for (p of properties) {
91    target[p] = 42;
92    assertTrue(myDelete(proxy, p));
93  }
94
95  // Trap returns trueish but target property is not configurable.
96  for (p of properties) {
97    Object.defineProperty(target, p, {value: 42, configurable: false});
98    assertThrows(() => myDelete(proxy, p), TypeError);
99  }
100};
101
102
103TestTrappingTrueish(
104    (o, p) => delete o[p]);
105TestTrappingTrueish(
106    (o, p) => Reflect.deleteProperty(o, p));
107TestTrappingTrueish(
108    (o, p) => {"use strict"; return delete o[p]});
109TestTrappingTrueish(
110    (o, p) => {"use strict"; return Reflect.deleteProperty(o, p)});
111
112
113function TestTrappingTrueish2(myDelete) {
114  var handler = {
115      deleteProperty(target, p) {
116          Object.defineProperty(target, p, {configurable: false});
117          return 42
118      }
119  };
120  var target = {};
121  var proxy = new Proxy(target, handler);
122
123  // Trap returns trueish but target property is not configurable.  In contrast
124  // to above, here the target property was configurable before the trap call.
125  for (p of properties) {
126    target[p] = 42;
127    assertThrows(() => myDelete(proxy, p), TypeError);
128  }
129};
130
131
132TestTrappingTrueish2(
133    (o, p) => delete o[p]);
134TestTrappingTrueish2(
135    (o, p) => Reflect.deleteProperty(o, p));
136TestTrappingTrueish2(
137    (o, p) => {"use strict"; return delete o[p]});
138TestTrappingTrueish2(
139    (o, p) => {"use strict"; return Reflect.deleteProperty(o, p)});
140
141
142function TestTrappingFalsish(myDelete, shouldThrow) {
143  var handler = { deleteProperty() {return ""} };
144  var target = {};
145  var proxy = new Proxy(target, handler);
146
147  var properties =
148      ["bla", "0", 1, Symbol(), {[Symbol.toPrimitive]() {return "a"}}];
149
150  // Trap returns falsish and target doesn't own property.
151  for (p of properties) {
152    if (shouldThrow) {
153      assertThrows(() => myDelete(proxy, p), TypeError);
154    } else {
155      assertFalse(myDelete(proxy, p));
156    }
157  }
158
159  // Trap returns falsish and target property is configurable.
160  for (p of properties) {
161    target[p] = 42;
162    if (shouldThrow) {
163      assertThrows(() => myDelete(proxy, p), TypeError);
164    } else {
165      assertFalse(myDelete(proxy, p));
166    }
167  }
168
169  // Trap returns falsish and target property is not configurable.
170  for (p of properties) {
171    Object.defineProperty(target, p, {value: 42, configurable: false});
172    if (shouldThrow) {
173      assertThrows(() => myDelete(proxy, p), TypeError);
174    } else {
175      assertFalse(myDelete(proxy, p));
176    }
177  }
178};
179
180
181TestTrappingFalsish(
182    (o, p) => delete o[p], false);
183TestTrappingFalsish(
184    (o, p) => Reflect.deleteProperty(o, p), false);
185TestTrappingFalsish(
186    (o, p) => {"use strict"; return delete o[p]}, true);
187TestTrappingFalsish(
188    (o, p) => {"use strict"; return Reflect.deleteProperty(o, p)}, false);
189