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