blob: 7a46b9b3b2369b978882afc020856095975f2a1c [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005
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);