OLD | NEW |
| (Empty) |
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 // Flags: --harmony-proxies --harmony-reflect | |
6 | |
7 | |
8 var properties = | |
9 ["bla", "0", 1, Symbol(), {[Symbol.toPrimitive]() {return "a"}}]; | |
10 | |
11 | |
12 function 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 | |
81 function 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 | |
105 TestTrappingTrueish( | |
106 (o, p) => delete o[p]); | |
107 TestTrappingTrueish( | |
108 (o, p) => Reflect.deleteProperty(o, p)); | |
109 TestTrappingTrueish( | |
110 (o, p) => {"use strict"; return delete o[p]}); | |
111 TestTrappingTrueish( | |
112 (o, p) => {"use strict"; return Reflect.deleteProperty(o, p)}); | |
113 | |
114 | |
115 function 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 | |
134 TestTrappingTrueish2( | |
135 (o, p) => delete o[p]); | |
136 TestTrappingTrueish2( | |
137 (o, p) => Reflect.deleteProperty(o, p)); | |
138 TestTrappingTrueish2( | |
139 (o, p) => {"use strict"; return delete o[p]}); | |
140 TestTrappingTrueish2( | |
141 (o, p) => {"use strict"; return Reflect.deleteProperty(o, p)}); | |
142 | |
143 | |
144 function 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 | |
183 TestTrappingFalsish( | |
184 (o, p) => delete o[p], false); | |
185 TestTrappingFalsish( | |
186 (o, p) => Reflect.deleteProperty(o, p), false); | |
187 TestTrappingFalsish( | |
188 (o, p) => {"use strict"; return delete o[p]}, true); | |
189 TestTrappingFalsish( | |
190 (o, p) => {"use strict"; return Reflect.deleteProperty(o, p)}, false); | |
OLD | NEW |