blob: b082c066969f0f5f0d6c982f8ac9affb64dbaa6a [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2011 the V8 project authors. All rights reserved.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
Ben Murdochb8a8cc12014-11-26 15:28:44 +000028// We change the stack size for the ARM64 simulator because at one point this
29// test enters an infinite recursion which goes through the runtime and we
30// overflow the system stack before the simulator stack.
31
32// Flags: --harmony-proxies --sim-stack-size=500
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000033
Ben Murdoch589d6972011-11-30 16:04:58 +000034
Ben Murdoch589d6972011-11-30 16:04:58 +000035// Helper.
36
Ben Murdoch3ef787d2012-04-12 10:51:47 +010037function TestWithProxies(test, x, y, z) {
38 test(Proxy.create, x, y, z)
39 test(function(h) {return Proxy.createFunction(h, function() {})}, x, y, z)
Ben Murdoch589d6972011-11-30 16:04:58 +000040}
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000041
42
Ben Murdoch3ef787d2012-04-12 10:51:47 +010043
44// Getting property descriptors (Object.getOwnPropertyDescriptor).
45
46var key
47
48function TestGetOwnProperty(handler) {
49 TestWithProxies(TestGetOwnProperty2, handler)
50}
51
52function TestGetOwnProperty2(create, handler) {
53 var p = create(handler)
54 assertEquals(42, Object.getOwnPropertyDescriptor(p, "a").value)
55 assertEquals("a", key)
56 assertEquals(42, Object.getOwnPropertyDescriptor(p, 99).value)
57 assertEquals("99", key)
58}
59
60TestGetOwnProperty({
61 getOwnPropertyDescriptor: function(k) {
62 key = k
63 return {value: 42, configurable: true}
64 }
65})
66
67TestGetOwnProperty({
68 getOwnPropertyDescriptor: function(k) {
69 return this.getOwnPropertyDescriptor2(k)
70 },
71 getOwnPropertyDescriptor2: function(k) {
72 key = k
73 return {value: 42, configurable: true}
74 }
75})
76
77TestGetOwnProperty({
78 getOwnPropertyDescriptor: function(k) {
79 key = k
80 return {get value() { return 42 }, get configurable() { return true }}
81 }
82})
83
84TestGetOwnProperty(Proxy.create({
85 get: function(pr, pk) {
86 return function(k) { key = k; return {value: 42, configurable: true} }
87 }
88}))
89
90
91function TestGetOwnPropertyThrow(handler) {
92 TestWithProxies(TestGetOwnPropertyThrow2, handler)
93}
94
95function TestGetOwnPropertyThrow2(create, handler) {
96 var p = create(handler)
97 assertThrows(function(){ Object.getOwnPropertyDescriptor(p, "a") }, "myexn")
98 assertThrows(function(){ Object.getOwnPropertyDescriptor(p, 77) }, "myexn")
99}
100
101TestGetOwnPropertyThrow({
102 getOwnPropertyDescriptor: function(k) { throw "myexn" }
103})
104
105TestGetOwnPropertyThrow({
106 getOwnPropertyDescriptor: function(k) {
107 return this.getPropertyDescriptor2(k)
108 },
109 getOwnPropertyDescriptor2: function(k) { throw "myexn" }
110})
111
112TestGetOwnPropertyThrow({
113 getOwnPropertyDescriptor: function(k) {
114 return {get value() { throw "myexn" }}
115 }
116})
117
118TestGetOwnPropertyThrow(Proxy.create({
119 get: function(pr, pk) {
120 return function(k) { throw "myexn" }
121 }
122}))
123
124
125
126// Getters (dot, brackets).
127
128var key
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000129
130function TestGet(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000131 TestWithProxies(TestGet2, handler)
132}
133
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100134function TestGet2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000135 var p = create(handler)
136 assertEquals(42, p.a)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100137 assertEquals("a", key)
Ben Murdoch589d6972011-11-30 16:04:58 +0000138 assertEquals(42, p["b"])
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100139 assertEquals("b", key)
140 assertEquals(42, p[99])
141 assertEquals("99", key)
142 assertEquals(42, (function(n) { return p[n] })("c"))
143 assertEquals("c", key)
144 assertEquals(42, (function(n) { return p[n] })(101))
145 assertEquals("101", key)
Ben Murdoch589d6972011-11-30 16:04:58 +0000146
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100147 var o = Object.create(p, {x: {value: 88}})
148 assertEquals(42, o.a)
149 assertEquals("a", key)
150 assertEquals(42, o["b"])
151 assertEquals("b", key)
152 assertEquals(42, o[99])
153 assertEquals("99", key)
154 assertEquals(88, o.x)
155 assertEquals(88, o["x"])
156 assertEquals(42, (function(n) { return o[n] })("c"))
157 assertEquals("c", key)
158 assertEquals(42, (function(n) { return o[n] })(101))
159 assertEquals("101", key)
160 assertEquals(88, (function(n) { return o[n] })("x"))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000161}
162
163TestGet({
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100164 get: function(r, k) { key = k; return 42 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000165})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000166
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000167TestGet({
168 get: function(r, k) { return this.get2(r, k) },
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100169 get2: function(r, k) { key = k; return 42 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000170})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000171
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000172TestGet({
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100173 getPropertyDescriptor: function(k) { key = k; return {value: 42} }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000174})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000175
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000176TestGet({
177 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100178 getPropertyDescriptor2: function(k) { key = k; return {value: 42} }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000179})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000180
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000181TestGet({
182 getPropertyDescriptor: function(k) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100183 key = k;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000184 return {get value() { return 42 }}
185 }
186})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000187
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000188TestGet({
189 get: undefined,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100190 getPropertyDescriptor: function(k) { key = k; return {value: 42} }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000191})
192
193TestGet(Proxy.create({
194 get: function(pr, pk) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100195 return function(r, k) { key = k; return 42 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000196 }
197}))
198
199
200function TestGetCall(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000201 TestWithProxies(TestGetCall2, handler)
202}
203
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100204function TestGetCall2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000205 var p = create(handler)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000206 assertEquals(55, p.f())
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100207 assertEquals(55, p["f"]())
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000208 assertEquals(55, p.f("unused", "arguments"))
209 assertEquals(55, p.f.call(p))
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100210 assertEquals(55, p["f"].call(p))
211 assertEquals(55, p[101].call(p))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000212 assertEquals(55, p.withargs(45, 5))
213 assertEquals(55, p.withargs.call(p, 11, 22))
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100214 assertEquals(55, (function(n) { return p[n]() })("f"))
215 assertEquals(55, (function(n) { return p[n].call(p) })("f"))
216 assertEquals(55, (function(n) { return p[n](15, 20) })("withargs"))
217 assertEquals(55, (function(n) { return p[n].call(p, 13, 21) })("withargs"))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000218 assertEquals("6655", "66" + p) // calls p.toString
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100219
220 var o = Object.create(p, {g: {value: function(x) { return x + 88 }}})
221 assertEquals(55, o.f())
222 assertEquals(55, o["f"]())
223 assertEquals(55, o.f("unused", "arguments"))
224 assertEquals(55, o.f.call(o))
225 assertEquals(55, o.f.call(p))
226 assertEquals(55, o["f"].call(p))
227 assertEquals(55, o[101].call(p))
228 assertEquals(55, o.withargs(45, 5))
229 assertEquals(55, o.withargs.call(p, 11, 22))
230 assertEquals(90, o.g(2))
231 assertEquals(91, o.g.call(o, 3))
232 assertEquals(92, o.g.call(p, 4))
233 assertEquals(55, (function(n) { return o[n]() })("f"))
234 assertEquals(55, (function(n) { return o[n].call(o) })("f"))
235 assertEquals(55, (function(n) { return o[n](15, 20) })("withargs"))
236 assertEquals(55, (function(n) { return o[n].call(o, 13, 21) })("withargs"))
237 assertEquals(93, (function(n) { return o[n](5) })("g"))
238 assertEquals(94, (function(n) { return o[n].call(o, 6) })("g"))
239 assertEquals(95, (function(n) { return o[n].call(p, 7) })("g"))
240 assertEquals("6655", "66" + o) // calls o.toString
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000241}
242
243TestGetCall({
244 get: function(r, k) { return function() { return 55 } }
245})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000246
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000247TestGetCall({
248 get: function(r, k) { return this.get2(r, k) },
249 get2: function(r, k) { return function() { return 55 } }
250})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000251
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000252TestGetCall({
253 getPropertyDescriptor: function(k) {
254 return {value: function() { return 55 }}
255 }
256})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000257
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000258TestGetCall({
259 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
260 getPropertyDescriptor2: function(k) {
261 return {value: function() { return 55 }}
262 }
263})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000264
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000265TestGetCall({
266 getPropertyDescriptor: function(k) {
267 return {get value() { return function() { return 55 } }}
268 }
269})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000270
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000271TestGetCall({
272 get: undefined,
273 getPropertyDescriptor: function(k) {
274 return {value: function() { return 55 }}
275 }
276})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000277
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000278TestGetCall({
279 get: function(r, k) {
280 if (k == "gg") {
281 return function() { return 55 }
282 } else if (k == "withargs") {
283 return function(n, m) { return n + m * 2 }
284 } else {
285 return function() { return this.gg() }
286 }
287 }
288})
289
290TestGetCall(Proxy.create({
291 get: function(pr, pk) {
292 return function(r, k) { return function() { return 55 } }
293 }
294}))
295
296
Ben Murdoch589d6972011-11-30 16:04:58 +0000297function TestGetThrow(handler) {
298 TestWithProxies(TestGetThrow2, handler)
299}
300
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100301function TestGetThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000302 var p = create(handler)
303 assertThrows(function(){ p.a }, "myexn")
304 assertThrows(function(){ p["b"] }, "myexn")
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100305 assertThrows(function(){ p[3] }, "myexn")
306 assertThrows(function(){ (function(n) { p[n] })("c") }, "myexn")
307 assertThrows(function(){ (function(n) { p[n] })(99) }, "myexn")
308
309 var o = Object.create(p, {x: {value: 88}, '4': {value: 89}})
310 assertThrows(function(){ o.a }, "myexn")
311 assertThrows(function(){ o["b"] }, "myexn")
312 assertThrows(function(){ o[3] }, "myexn")
313 assertThrows(function(){ (function(n) { o[n] })("c") }, "myexn")
314 assertThrows(function(){ (function(n) { o[n] })(99) }, "myexn")
Ben Murdoch589d6972011-11-30 16:04:58 +0000315}
316
317TestGetThrow({
318 get: function(r, k) { throw "myexn" }
319})
320
321TestGetThrow({
322 get: function(r, k) { return this.get2(r, k) },
323 get2: function(r, k) { throw "myexn" }
324})
325
326TestGetThrow({
327 getPropertyDescriptor: function(k) { throw "myexn" }
328})
329
330TestGetThrow({
331 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
332 getPropertyDescriptor2: function(k) { throw "myexn" }
333})
334
335TestGetThrow({
336 getPropertyDescriptor: function(k) {
337 return {get value() { throw "myexn" }}
338 }
339})
340
341TestGetThrow({
342 get: undefined,
343 getPropertyDescriptor: function(k) { throw "myexn" }
344})
345
346TestGetThrow(Proxy.create({
347 get: function(pr, pk) { throw "myexn" }
348}))
349
350TestGetThrow(Proxy.create({
351 get: function(pr, pk) {
352 return function(r, k) { throw "myexn" }
353 }
354}))
355
356
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000357
358// Setters.
359
360var key
361var val
Ben Murdoch589d6972011-11-30 16:04:58 +0000362
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100363function TestSet(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000364 TestWithProxies(TestSet2, handler)
365}
366
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100367function TestSet2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000368 var p = create(handler)
369 assertEquals(42, p.a = 42)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000370 assertEquals("a", key)
371 assertEquals(42, val)
Ben Murdoch589d6972011-11-30 16:04:58 +0000372 assertEquals(43, p["b"] = 43)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000373 assertEquals("b", key)
374 assertEquals(43, val)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100375 assertEquals(44, p[77] = 44)
376 assertEquals("77", key)
377 assertEquals(44, val)
378
379 assertEquals(45, (function(n) { return p[n] = 45 })("c"))
380 assertEquals("c", key)
381 assertEquals(45, val)
382 assertEquals(46, (function(n) { return p[n] = 46 })(99))
383 assertEquals("99", key)
384 assertEquals(46, val)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000385}
386
387TestSet({
388 set: function(r, k, v) { key = k; val = v; return true }
389})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000390
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000391TestSet({
392 set: function(r, k, v) { return this.set2(r, k, v) },
393 set2: function(r, k, v) { key = k; val = v; return true }
394})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000395
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000396TestSet({
397 getOwnPropertyDescriptor: function(k) { return {writable: true} },
398 defineProperty: function(k, desc) { key = k; val = desc.value }
399})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000400
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000401TestSet({
402 getOwnPropertyDescriptor: function(k) {
403 return this.getOwnPropertyDescriptor2(k)
404 },
405 getOwnPropertyDescriptor2: function(k) { return {writable: true} },
406 defineProperty: function(k, desc) { this.defineProperty2(k, desc) },
407 defineProperty2: function(k, desc) { key = k; val = desc.value }
408})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000409
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000410TestSet({
411 getOwnPropertyDescriptor: function(k) {
412 return {get writable() { return true }}
413 },
414 defineProperty: function(k, desc) { key = k; val = desc.value }
415})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000416
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000417TestSet({
418 getOwnPropertyDescriptor: function(k) {
419 return {set: function(v) { key = k; val = v }}
420 }
421})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000422
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000423TestSet({
424 getOwnPropertyDescriptor: function(k) { return null },
425 getPropertyDescriptor: function(k) { return {writable: true} },
426 defineProperty: function(k, desc) { key = k; val = desc.value }
427})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000428
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000429TestSet({
430 getOwnPropertyDescriptor: function(k) { return null },
431 getPropertyDescriptor: function(k) {
432 return {get writable() { return true }}
433 },
434 defineProperty: function(k, desc) { key = k; val = desc.value }
435})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000436
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000437TestSet({
438 getOwnPropertyDescriptor: function(k) { return null },
439 getPropertyDescriptor: function(k) {
440 return {set: function(v) { key = k; val = v }}
441 }
442})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000443
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000444TestSet({
445 getOwnPropertyDescriptor: function(k) { return null },
446 getPropertyDescriptor: function(k) { return null },
447 defineProperty: function(k, desc) { key = k, val = desc.value }
448})
449
450TestSet(Proxy.create({
451 get: function(pr, pk) {
452 return function(r, k, v) { key = k; val = v; return true }
453 }
454}))
455
456
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100457function TestSetThrow(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000458 TestWithProxies(TestSetThrow2, handler)
459}
460
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100461function TestSetThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000462 var p = create(handler)
463 assertThrows(function(){ p.a = 42 }, "myexn")
464 assertThrows(function(){ p["b"] = 42 }, "myexn")
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100465 assertThrows(function(){ p[22] = 42 }, "myexn")
466 assertThrows(function(){ (function(n) { p[n] = 45 })("c") }, "myexn")
467 assertThrows(function(){ (function(n) { p[n] = 46 })(99) }, "myexn")
Ben Murdoch589d6972011-11-30 16:04:58 +0000468}
469
470TestSetThrow({
471 set: function(r, k, v) { throw "myexn" }
472})
473
474TestSetThrow({
475 set: function(r, k, v) { return this.set2(r, k, v) },
476 set2: function(r, k, v) { throw "myexn" }
477})
478
479TestSetThrow({
480 getOwnPropertyDescriptor: function(k) { throw "myexn" },
481 defineProperty: function(k, desc) { key = k; val = desc.value }
482})
483
484TestSetThrow({
485 getOwnPropertyDescriptor: function(k) { return {writable: true} },
486 defineProperty: function(k, desc) { throw "myexn" }
487})
488
489TestSetThrow({
490 getOwnPropertyDescriptor: function(k) {
491 return this.getOwnPropertyDescriptor2(k)
492 },
493 getOwnPropertyDescriptor2: function(k) { throw "myexn" },
494 defineProperty: function(k, desc) { this.defineProperty2(k, desc) },
495 defineProperty2: function(k, desc) { key = k; val = desc.value }
496})
497
498TestSetThrow({
499 getOwnPropertyDescriptor: function(k) {
500 return this.getOwnPropertyDescriptor2(k)
501 },
502 getOwnPropertyDescriptor2: function(k) { return {writable: true} },
503 defineProperty: function(k, desc) { this.defineProperty2(k, desc) },
504 defineProperty2: function(k, desc) { throw "myexn" }
505})
506
507TestSetThrow({
508 getOwnPropertyDescriptor: function(k) { throw "myexn" },
509 defineProperty: function(k, desc) { key = k; val = desc.value }
510})
511
512TestSetThrow({
513 getOwnPropertyDescriptor: function(k) {
514 return {get writable() { return true }}
515 },
516 defineProperty: function(k, desc) { throw "myexn" }
517})
518
519TestSetThrow({
520 getOwnPropertyDescriptor: function(k) { throw "myexn" }
521})
522
523TestSetThrow({
524 getOwnPropertyDescriptor: function(k) {
525 return {set: function(v) { throw "myexn" }}
526 }
527})
528
529TestSetThrow({
530 getOwnPropertyDescriptor: function(k) { throw "myexn" },
531 getPropertyDescriptor: function(k) { return {writable: true} },
532 defineProperty: function(k, desc) { key = k; val = desc.value }
533})
534
535TestSetThrow({
536 getOwnPropertyDescriptor: function(k) { return null },
537 getPropertyDescriptor: function(k) { throw "myexn" },
538 defineProperty: function(k, desc) { key = k; val = desc.value }
539})
540
541TestSetThrow({
542 getOwnPropertyDescriptor: function(k) { return null },
543 getPropertyDescriptor: function(k) { return {writable: true} },
544 defineProperty: function(k, desc) { throw "myexn" }
545})
546
547TestSetThrow({
548 getOwnPropertyDescriptor: function(k) { return null },
549 getPropertyDescriptor: function(k) {
550 return {get writable() { throw "myexn" }}
551 },
552 defineProperty: function(k, desc) { key = k; val = desc.value }
553})
554
555TestSetThrow({
556 getOwnPropertyDescriptor: function(k) { return null },
557 getPropertyDescriptor: function(k) {
558 return {set: function(v) { throw "myexn" }}
559 }
560})
561
562TestSetThrow({
563 getOwnPropertyDescriptor: function(k) { return null },
564 getPropertyDescriptor: function(k) { return null },
565 defineProperty: function(k, desc) { throw "myexn" }
566})
567
568TestSetThrow(Proxy.create({
569 get: function(pr, pk) { throw "myexn" }
570}))
571
572TestSetThrow(Proxy.create({
573 get: function(pr, pk) {
574 return function(r, k, v) { throw "myexn" }
575 }
576}))
577
578
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000579var rec
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100580var key
581var val
582
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000583function TestSetForDerived(trap) {
584 TestWithProxies(TestSetForDerived2, trap)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100585}
586
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000587function TestSetForDerived2(create, trap) {
588 var p = create({getPropertyDescriptor: trap, getOwnPropertyDescriptor: trap})
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100589 var o = Object.create(p, {x: {value: 88, writable: true},
590 '1': {value: 89, writable: true}})
591
592 key = ""
593 assertEquals(48, o.x = 48)
594 assertEquals("", key) // trap not invoked
595 assertEquals(48, o.x)
596
597 assertEquals(47, o[1] = 47)
598 assertEquals("", key) // trap not invoked
599 assertEquals(47, o[1])
600
601 assertEquals(49, o.y = 49)
602 assertEquals("y", key)
603 assertEquals(49, o.y)
604
605 assertEquals(50, o[2] = 50)
606 assertEquals("2", key)
607 assertEquals(50, o[2])
608
609 assertEquals(44, o.p_writable = 44)
610 assertEquals("p_writable", key)
611 assertEquals(44, o.p_writable)
612
613 assertEquals(45, o.p_nonwritable = 45)
614 assertEquals("p_nonwritable", key)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000615 assertFalse(Object.prototype.hasOwnProperty.call(o, "p_nonwritable"))
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100616
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000617 assertThrows(function(){ "use strict"; o.p_nonwritable = 45 }, TypeError)
618 assertEquals("p_nonwritable", key)
619 assertFalse(Object.prototype.hasOwnProperty.call(o, "p_nonwritable"))
620
621 val = ""
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100622 assertEquals(46, o.p_setter = 46)
623 assertEquals("p_setter", key)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000624 assertSame(o, rec)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100625 assertEquals(46, val) // written to parent
626 assertFalse(Object.prototype.hasOwnProperty.call(o, "p_setter"))
627
628 val = ""
629 assertEquals(47, o.p_nosetter = 47)
630 assertEquals("p_nosetter", key)
631 assertEquals("", val) // not written at all
632 assertFalse(Object.prototype.hasOwnProperty.call(o, "p_nosetter"));
633
634 key = ""
635 assertThrows(function(){ "use strict"; o.p_nosetter = 50 }, TypeError)
636 assertEquals("p_nosetter", key)
637 assertEquals("", val) // not written at all
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000638 assertFalse(Object.prototype.hasOwnProperty.call(o, "p_nosetter"));
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100639
640 assertThrows(function(){ o.p_nonconf = 53 }, TypeError)
641 assertEquals("p_nonconf", key)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000642 assertFalse(Object.prototype.hasOwnProperty.call(o, "p_nonconf"));
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100643
644 assertThrows(function(){ o.p_throw = 51 }, "myexn")
645 assertEquals("p_throw", key)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000646 assertFalse(Object.prototype.hasOwnProperty.call(o, "p_throw"));
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100647
648 assertThrows(function(){ o.p_setterthrow = 52 }, "myexn")
649 assertEquals("p_setterthrow", key)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000650 assertFalse(Object.prototype.hasOwnProperty.call(o, "p_setterthrow"));
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100651}
652
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000653
654TestSetForDerived(
655 function(k) {
656 // TODO(yangguo): issue 2398 - throwing an error causes formatting of
657 // the message string, which can be observable through this handler.
658 // We ignore keys that occur when formatting the message string.
659 if (k == "toString" || k == "valueOf") return;
660
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100661 key = k;
662 switch (k) {
663 case "p_writable": return {writable: true, configurable: true}
664 case "p_nonwritable": return {writable: false, configurable: true}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000665 case "p_setter": return {
666 set: function(x) { rec = this; val = x },
667 configurable: true
668 }
669 case "p_nosetter": return {
670 get: function() { return 1 },
671 configurable: true
672 }
673 case "p_nonconf": return {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100674 case "p_throw": throw "myexn"
675 case "p_setterthrow": return {set: function(x) { throw "myexn" }}
676 default: return undefined
677 }
678 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000679)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100680
681
682// Evil proxy-induced side-effects shouldn't crash.
683// TODO(rossberg): proper behaviour isn't really spec'ed yet, so ignore results.
684
685TestWithProxies(function(create) {
686 var calls = 0
687 var handler = {
688 getPropertyDescriptor: function() {
689 ++calls
690 return (calls % 2 == 1)
691 ? {get: function() { return 5 }, configurable: true}
692 : {set: function() { return false }, configurable: true}
693 }
694 }
695 var p = create(handler)
696 var o = Object.create(p)
697 // Make proxy prototype property read-only after CanPut check.
698 try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
699})
700
701TestWithProxies(function(create) {
702 var handler = {
703 getPropertyDescriptor: function() {
704 Object.defineProperty(o, "x", {get: function() { return 5 }});
705 return {set: function() {}}
706 }
707 }
708 var p = create(handler)
709 var o = Object.create(p)
710 // Make object property read-only after CanPut check.
711 try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
712})
713
714
715
716// TODO(rossberg): TestSetReject, returning false
717// TODO(rossberg): TestGetProperty, TestSetProperty
718
719
Ben Murdoch589d6972011-11-30 16:04:58 +0000720
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000721// Property definition (Object.defineProperty and Object.defineProperties).
722
723var key
724var desc
Ben Murdoch589d6972011-11-30 16:04:58 +0000725
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000726function TestDefine(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000727 TestWithProxies(TestDefine2, handler)
728}
729
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100730function TestDefine2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000731 var p = create(handler)
732 assertEquals(p, Object.defineProperty(p, "a", {value: 44}))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000733 assertEquals("a", key)
734 assertEquals(1, Object.getOwnPropertyNames(desc).length)
735 assertEquals(44, desc.value)
736
Ben Murdoch589d6972011-11-30 16:04:58 +0000737 assertEquals(p, Object.defineProperty(p, "b", {value: 45, writable: false}))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000738 assertEquals("b", key)
739 assertEquals(2, Object.getOwnPropertyNames(desc).length)
740 assertEquals(45, desc.value)
741 assertEquals(false, desc.writable)
742
Ben Murdoch589d6972011-11-30 16:04:58 +0000743 assertEquals(p, Object.defineProperty(p, "c", {value: 46, enumerable: false}))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000744 assertEquals("c", key)
745 assertEquals(2, Object.getOwnPropertyNames(desc).length)
746 assertEquals(46, desc.value)
747 assertEquals(false, desc.enumerable)
748
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100749 assertEquals(p, Object.defineProperty(p, 101, {value: 47, enumerable: false}))
750 assertEquals("101", key)
751 assertEquals(2, Object.getOwnPropertyNames(desc).length)
752 assertEquals(47, desc.value)
753 assertEquals(false, desc.enumerable)
754
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000755 var attributes = {configurable: true, mine: 66, minetoo: 23}
Ben Murdoch589d6972011-11-30 16:04:58 +0000756 assertEquals(p, Object.defineProperty(p, "d", attributes))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000757 assertEquals("d", key)
758 // Modifying the attributes object after the fact should have no effect.
759 attributes.configurable = false
760 attributes.mine = 77
761 delete attributes.minetoo
762 assertEquals(3, Object.getOwnPropertyNames(desc).length)
763 assertEquals(true, desc.configurable)
764 assertEquals(66, desc.mine)
765 assertEquals(23, desc.minetoo)
766
Ben Murdoch589d6972011-11-30 16:04:58 +0000767 assertEquals(p, Object.defineProperty(p, "e", {get: function(){ return 5 }}))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000768 assertEquals("e", key)
769 assertEquals(1, Object.getOwnPropertyNames(desc).length)
770 assertEquals(5, desc.get())
771
Ben Murdoch589d6972011-11-30 16:04:58 +0000772 assertEquals(p, Object.defineProperty(p, "zzz", {}))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000773 assertEquals("zzz", key)
774 assertEquals(0, Object.getOwnPropertyNames(desc).length)
775
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100776 var d = create({
777 get: function(r, k) { return (k === "value") ? 77 : void 0 },
778 getOwnPropertyNames: function() { return ["value"] },
779 enumerate: function() { return ["value"] }
780 })
781 assertEquals(1, Object.getOwnPropertyNames(d).length)
782 assertEquals(77, d.value)
783 assertEquals(p, Object.defineProperty(p, "p", d))
784 assertEquals("p", key)
785 assertEquals(1, Object.getOwnPropertyNames(desc).length)
786 assertEquals(77, desc.value)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000787
788 var props = {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100789 '11': {},
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000790 blub: {get: function() { return true }},
791 '': {get value() { return 20 }},
792 last: {value: 21, configurable: true, mine: "eyes"}
793 }
794 Object.defineProperty(props, "hidden", {value: "hidden", enumerable: false})
Ben Murdoch589d6972011-11-30 16:04:58 +0000795 assertEquals(p, Object.defineProperties(p, props))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000796 assertEquals("last", key)
797 assertEquals(2, Object.getOwnPropertyNames(desc).length)
798 assertEquals(21, desc.value)
799 assertEquals(true, desc.configurable)
800 assertEquals(undefined, desc.mine) // Arguably a bug in the spec...
Ben Murdoch589d6972011-11-30 16:04:58 +0000801
802 var props = {bla: {get value() { throw "myexn" }}}
803 assertThrows(function(){ Object.defineProperties(p, props) }, "myexn")
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000804}
805
806TestDefine({
807 defineProperty: function(k, d) { key = k; desc = d; return true }
808})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000809
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000810TestDefine({
811 defineProperty: function(k, d) { return this.defineProperty2(k, d) },
812 defineProperty2: function(k, d) { key = k; desc = d; return true }
813})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000814
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000815TestDefine(Proxy.create({
816 get: function(pr, pk) {
817 return function(k, d) { key = k; desc = d; return true }
818 }
819}))
820
821
Ben Murdoch589d6972011-11-30 16:04:58 +0000822function TestDefineThrow(handler) {
823 TestWithProxies(TestDefineThrow2, handler)
824}
825
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100826function TestDefineThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000827 var p = create(handler)
828 assertThrows(function(){ Object.defineProperty(p, "a", {value: 44})}, "myexn")
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100829 assertThrows(function(){ Object.defineProperty(p, 0, {value: 44})}, "myexn")
Ben Murdoch589d6972011-11-30 16:04:58 +0000830
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100831 var d1 = create({
832 get: function(r, k) { throw "myexn" },
833 getOwnPropertyNames: function() { return ["value"] }
834 })
835 assertThrows(function(){ Object.defineProperty(p, "p", d1) }, "myexn")
836 var d2 = create({
837 get: function(r, k) { return 77 },
838 getOwnPropertyNames: function() { throw "myexn" }
839 })
840 assertThrows(function(){ Object.defineProperty(p, "p", d2) }, "myexn")
Ben Murdoch589d6972011-11-30 16:04:58 +0000841
842 var props = {bla: {get value() { throw "otherexn" }}}
843 assertThrows(function(){ Object.defineProperties(p, props) }, "otherexn")
844}
845
846TestDefineThrow({
847 defineProperty: function(k, d) { throw "myexn" }
848})
849
850TestDefineThrow({
851 defineProperty: function(k, d) { return this.defineProperty2(k, d) },
852 defineProperty2: function(k, d) { throw "myexn" }
853})
854
855TestDefineThrow(Proxy.create({
856 get: function(pr, pk) { throw "myexn" }
857}))
858
859TestDefineThrow(Proxy.create({
860 get: function(pr, pk) {
861 return function(k, d) { throw "myexn" }
862 }
863}))
864
865
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000866
867// Property deletion (delete).
868
869var key
Ben Murdoch589d6972011-11-30 16:04:58 +0000870
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000871function TestDelete(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000872 TestWithProxies(TestDelete2, handler)
873}
874
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100875function TestDelete2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000876 var p = create(handler)
877 assertEquals(true, delete p.a)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000878 assertEquals("a", key)
Ben Murdoch589d6972011-11-30 16:04:58 +0000879 assertEquals(true, delete p["b"])
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000880 assertEquals("b", key)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100881 assertEquals(true, delete p[1])
882 assertEquals("1", key)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000883
Ben Murdoch589d6972011-11-30 16:04:58 +0000884 assertEquals(false, delete p.z1)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000885 assertEquals("z1", key)
Ben Murdoch589d6972011-11-30 16:04:58 +0000886 assertEquals(false, delete p["z2"])
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000887 assertEquals("z2", key);
888
889 (function() {
890 "use strict"
Ben Murdoch589d6972011-11-30 16:04:58 +0000891 assertEquals(true, delete p.c)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000892 assertEquals("c", key)
Ben Murdoch589d6972011-11-30 16:04:58 +0000893 assertEquals(true, delete p["d"])
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000894 assertEquals("d", key)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100895 assertEquals(true, delete p[2])
896 assertEquals("2", key)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000897
Ben Murdoch589d6972011-11-30 16:04:58 +0000898 assertThrows(function(){ delete p.z3 }, TypeError)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000899 assertEquals("z3", key)
Ben Murdoch589d6972011-11-30 16:04:58 +0000900 assertThrows(function(){ delete p["z4"] }, TypeError)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000901 assertEquals("z4", key)
902 })()
903}
904
905TestDelete({
Ben Murdoch589d6972011-11-30 16:04:58 +0000906 delete: function(k) { key = k; return k < "z" }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000907})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000908
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000909TestDelete({
Ben Murdoch589d6972011-11-30 16:04:58 +0000910 delete: function(k) { return this.delete2(k) },
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000911 delete2: function(k) { key = k; return k < "z" }
912})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000913
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000914TestDelete(Proxy.create({
915 get: function(pr, pk) {
916 return function(k) { key = k; return k < "z" }
917 }
918}))
919
920
Ben Murdoch589d6972011-11-30 16:04:58 +0000921function TestDeleteThrow(handler) {
922 TestWithProxies(TestDeleteThrow2, handler)
923}
924
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100925function TestDeleteThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000926 var p = create(handler)
927 assertThrows(function(){ delete p.a }, "myexn")
928 assertThrows(function(){ delete p["b"] }, "myexn");
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100929 assertThrows(function(){ delete p[3] }, "myexn");
Ben Murdoch589d6972011-11-30 16:04:58 +0000930
931 (function() {
932 "use strict"
933 assertThrows(function(){ delete p.c }, "myexn")
934 assertThrows(function(){ delete p["d"] }, "myexn")
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100935 assertThrows(function(){ delete p[4] }, "myexn");
Ben Murdoch589d6972011-11-30 16:04:58 +0000936 })()
937}
938
939TestDeleteThrow({
940 delete: function(k) { throw "myexn" }
941})
942
943TestDeleteThrow({
944 delete: function(k) { return this.delete2(k) },
945 delete2: function(k) { throw "myexn" }
946})
947
948TestDeleteThrow(Proxy.create({
949 get: function(pr, pk) { throw "myexn" }
950}))
951
952TestDeleteThrow(Proxy.create({
953 get: function(pr, pk) {
954 return function(k) { throw "myexn" }
955 }
956}))
957
958
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000959
960// Property descriptors (Object.getOwnPropertyDescriptor).
961
962function TestDescriptor(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000963 TestWithProxies(TestDescriptor2, handler)
964}
965
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100966function TestDescriptor2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000967 var p = create(handler)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000968 var descs = [
969 {configurable: true},
970 {value: 34, enumerable: true, configurable: true},
971 {value: 3, writable: false, mine: "eyes", configurable: true},
972 {get value() { return 20 }, get configurable() { return true }},
973 {get: function() { "get" }, set: function() { "set" }, configurable: true}
974 ]
975 for (var i = 0; i < descs.length; ++i) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000976 assertEquals(p, Object.defineProperty(p, i, descs[i]))
977 var desc = Object.getOwnPropertyDescriptor(p, i)
978 for (prop in descs[i]) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000979 // TODO(rossberg): Ignore user attributes as long as the spec isn't
980 // fixed suitably.
Ben Murdoch589d6972011-11-30 16:04:58 +0000981 if (prop != "mine") assertEquals(descs[i][prop], desc[prop])
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000982 }
Ben Murdoch589d6972011-11-30 16:04:58 +0000983 assertEquals(undefined, Object.getOwnPropertyDescriptor(p, "absent"))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000984 }
985}
986
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000987TestDescriptor({
988 defineProperty: function(k, d) { this["__" + k] = d; return true },
989 getOwnPropertyDescriptor: function(k) { return this["__" + k] }
990})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000991
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000992TestDescriptor({
993 defineProperty: function(k, d) { this["__" + k] = d; return true },
994 getOwnPropertyDescriptor: function(k) {
995 return this.getOwnPropertyDescriptor2(k)
996 },
997 getOwnPropertyDescriptor2: function(k) { return this["__" + k] }
998})
999
1000
Ben Murdoch589d6972011-11-30 16:04:58 +00001001function TestDescriptorThrow(handler) {
1002 TestWithProxies(TestDescriptorThrow2, handler)
1003}
1004
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001005function TestDescriptorThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001006 var p = create(handler)
1007 assertThrows(function(){ Object.getOwnPropertyDescriptor(p, "a") }, "myexn")
1008}
1009
1010TestDescriptorThrow({
1011 getOwnPropertyDescriptor: function(k) { throw "myexn" }
1012})
1013
1014TestDescriptorThrow({
1015 getOwnPropertyDescriptor: function(k) {
1016 return this.getOwnPropertyDescriptor2(k)
1017 },
1018 getOwnPropertyDescriptor2: function(k) { throw "myexn" }
1019})
1020
1021
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001022
1023// Comparison.
1024
1025function TestComparison(eq) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001026 TestWithProxies(TestComparison2, eq)
1027}
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001028
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001029function TestComparison2(create, eq) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001030 var p1 = create({})
1031 var p2 = create({})
1032
1033 assertTrue(eq(p1, p1))
1034 assertTrue(eq(p2, p2))
1035 assertTrue(!eq(p1, p2))
1036 assertTrue(!eq(p1, {}))
1037 assertTrue(!eq({}, p2))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001038 assertTrue(!eq({}, {}))
1039}
1040
1041TestComparison(function(o1, o2) { return o1 == o2 })
1042TestComparison(function(o1, o2) { return o1 === o2 })
1043TestComparison(function(o1, o2) { return !(o1 != o2) })
1044TestComparison(function(o1, o2) { return !(o1 !== o2) })
1045
1046
1047
Ben Murdoch589d6972011-11-30 16:04:58 +00001048// Type (typeof).
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001049
Ben Murdoch589d6972011-11-30 16:04:58 +00001050function TestTypeof() {
1051 assertEquals("object", typeof Proxy.create({}))
1052 assertTrue(typeof Proxy.create({}) == "object")
1053 assertTrue("object" == typeof Proxy.create({}))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001054
Ben Murdoch589d6972011-11-30 16:04:58 +00001055 assertEquals("function", typeof Proxy.createFunction({}, function() {}))
1056 assertTrue(typeof Proxy.createFunction({}, function() {}) == "function")
1057 assertTrue("function" == typeof Proxy.createFunction({}, function() {}))
1058}
1059
1060TestTypeof()
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001061
1062
1063
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001064// Membership test (in).
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001065
1066var key
Ben Murdoch589d6972011-11-30 16:04:58 +00001067
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001068function TestIn(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001069 TestWithProxies(TestIn2, handler)
1070}
1071
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001072function TestIn2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001073 var p = create(handler)
1074 assertTrue("a" in p)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001075 assertEquals("a", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00001076 assertTrue(99 in p)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001077 assertEquals("99", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00001078 assertFalse("z" in p)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001079 assertEquals("z", key)
1080
Ben Murdoch589d6972011-11-30 16:04:58 +00001081 assertEquals(2, ("a" in p) ? 2 : 0)
1082 assertEquals(0, !("a" in p) ? 2 : 0)
1083 assertEquals(0, ("zzz" in p) ? 2 : 0)
1084 assertEquals(2, !("zzz" in p) ? 2 : 0)
1085
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001086 // Test compilation in conditionals.
Ben Murdoch589d6972011-11-30 16:04:58 +00001087 if ("b" in p) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001088 } else {
1089 assertTrue(false)
1090 }
1091 assertEquals("b", key)
1092
Ben Murdoch589d6972011-11-30 16:04:58 +00001093 if ("zz" in p) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001094 assertTrue(false)
1095 }
1096 assertEquals("zz", key)
1097
Ben Murdoch589d6972011-11-30 16:04:58 +00001098 if (!("c" in p)) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001099 assertTrue(false)
1100 }
1101 assertEquals("c", key)
1102
Ben Murdoch589d6972011-11-30 16:04:58 +00001103 if (!("zzz" in p)) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001104 } else {
1105 assertTrue(false)
1106 }
1107 assertEquals("zzz", key)
1108}
1109
1110TestIn({
1111 has: function(k) { key = k; return k < "z" }
1112})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001113
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001114TestIn({
1115 has: function(k) { return this.has2(k) },
1116 has2: function(k) { key = k; return k < "z" }
1117})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001118
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001119TestIn({
1120 getPropertyDescriptor: function(k) {
1121 key = k; return k < "z" ? {value: 42} : void 0
1122 }
1123})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001124
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001125TestIn({
1126 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
1127 getPropertyDescriptor2: function(k) {
1128 key = k; return k < "z" ? {value: 42} : void 0
1129 }
1130})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001131
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001132TestIn({
1133 getPropertyDescriptor: function(k) {
1134 key = k; return k < "z" ? {get value() { return 42 }} : void 0
1135 }
1136})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001137
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001138TestIn({
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001139 has: undefined,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001140 getPropertyDescriptor: function(k) {
1141 key = k; return k < "z" ? {value: 42} : void 0
1142 }
1143})
1144
1145TestIn(Proxy.create({
1146 get: function(pr, pk) {
1147 return function(k) { key = k; return k < "z" }
1148 }
1149}))
1150
1151
Ben Murdoch589d6972011-11-30 16:04:58 +00001152function TestInThrow(handler) {
1153 TestWithProxies(TestInThrow2, handler)
1154}
1155
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001156function TestInThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001157 var p = create(handler)
1158 assertThrows(function(){ return "a" in o }, "myexn")
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001159 assertThrows(function(){ return 99 in o }, "myexn")
Ben Murdoch589d6972011-11-30 16:04:58 +00001160 assertThrows(function(){ return !("a" in o) }, "myexn")
1161 assertThrows(function(){ return ("a" in o) ? 2 : 3 }, "myexn")
1162 assertThrows(function(){ if ("b" in o) {} }, "myexn")
1163 assertThrows(function(){ if (!("b" in o)) {} }, "myexn")
1164 assertThrows(function(){ if ("zzz" in o) {} }, "myexn")
1165}
1166
1167TestInThrow({
1168 has: function(k) { throw "myexn" }
1169})
1170
1171TestInThrow({
1172 has: function(k) { return this.has2(k) },
1173 has2: function(k) { throw "myexn" }
1174})
1175
1176TestInThrow({
1177 getPropertyDescriptor: function(k) { throw "myexn" }
1178})
1179
1180TestInThrow({
1181 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
1182 getPropertyDescriptor2: function(k) { throw "myexn" }
1183})
1184
1185TestInThrow({
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001186 has: undefined,
Ben Murdoch589d6972011-11-30 16:04:58 +00001187 getPropertyDescriptor: function(k) { throw "myexn" }
1188})
1189
1190TestInThrow(Proxy.create({
1191 get: function(pr, pk) { throw "myexn" }
1192}))
1193
1194TestInThrow(Proxy.create({
1195 get: function(pr, pk) {
1196 return function(k) { throw "myexn" }
1197 }
1198}))
1199
1200
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001201function TestInForDerived(handler) {
1202 TestWithProxies(TestInForDerived2, handler)
1203}
1204
1205function TestInForDerived2(create, handler) {
1206 var p = create(handler)
1207 var o = Object.create(p)
1208
1209 assertTrue("a" in o)
1210 assertEquals("a", key)
1211 assertTrue(99 in o)
1212 assertEquals("99", key)
1213 assertFalse("z" in o)
1214 assertEquals("z", key)
1215
1216 assertEquals(2, ("a" in o) ? 2 : 0)
1217 assertEquals(0, !("a" in o) ? 2 : 0)
1218 assertEquals(0, ("zzz" in o) ? 2 : 0)
1219 assertEquals(2, !("zzz" in o) ? 2 : 0)
1220
1221 if ("b" in o) {
1222 } else {
1223 assertTrue(false)
1224 }
1225 assertEquals("b", key)
1226
1227 if ("zz" in o) {
1228 assertTrue(false)
1229 }
1230 assertEquals("zz", key)
1231
1232 if (!("c" in o)) {
1233 assertTrue(false)
1234 }
1235 assertEquals("c", key)
1236
1237 if (!("zzz" in o)) {
1238 } else {
1239 assertTrue(false)
1240 }
1241 assertEquals("zzz", key)
1242}
1243
1244TestInForDerived({
1245 getPropertyDescriptor: function(k) {
1246 key = k; return k < "z" ? {value: 42, configurable: true} : void 0
1247 }
1248})
1249
1250TestInForDerived({
1251 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
1252 getPropertyDescriptor2: function(k) {
1253 key = k; return k < "z" ? {value: 42, configurable: true} : void 0
1254 }
1255})
1256
1257TestInForDerived({
1258 getPropertyDescriptor: function(k) {
1259 key = k;
1260 return k < "z" ? {get value() { return 42 }, configurable: true} : void 0
1261 }
1262})
1263
1264/* TODO(rossberg): this will work once we implement the newest proposal
1265 * regarding default traps for getPropertyDescriptor.
1266TestInForDerived({
1267 getOwnPropertyDescriptor: function(k) {
1268 key = k; return k < "z" ? {value: 42, configurable: true} : void 0
1269 }
1270})
1271
1272TestInForDerived({
1273 getOwnPropertyDescriptor: function(k) {
1274 return this.getOwnPropertyDescriptor2(k)
1275 },
1276 getOwnPropertyDescriptor2: function(k) {
1277 key = k; return k < "z" ? {value: 42, configurable: true} : void 0
1278 }
1279})
1280
1281TestInForDerived({
1282 getOwnPropertyDescriptor: function(k) {
1283 key = k;
1284 return k < "z" ? {get value() { return 42 }, configurable: true} : void 0
1285 }
1286})
1287*/
1288
1289TestInForDerived(Proxy.create({
1290 get: function(pr, pk) {
1291 return function(k) {
1292 key = k; return k < "z" ? {value: 42, configurable: true} : void 0
1293 }
1294 }
1295}))
1296
1297
1298
1299// Property descriptor conversion.
1300
1301var descget
1302
1303function TestDescriptorGetOrder(handler) {
1304 var p = Proxy.create(handler)
1305 var o = Object.create(p, {b: {value: 0}})
1306 TestDescriptorGetOrder2(function(n) { return p[n] }, "vV")
1307 TestDescriptorGetOrder2(function(n) { return n in p }, "")
1308 TestDescriptorGetOrder2(function(n) { return o[n] }, "vV")
1309 TestDescriptorGetOrder2(function(n) { return n in o }, "eEcCvVwWgs")
1310}
1311
1312function TestDescriptorGetOrder2(f, access) {
1313 descget = ""
1314 assertTrue(f("a"))
1315 assertEquals(access, descget)
1316 descget = ""
1317 assertTrue(f(99))
1318 assertEquals(access, descget)
1319 descget = ""
1320 assertFalse(!!f("z"))
1321 assertEquals("", descget)
1322}
1323
1324TestDescriptorGetOrder({
1325 getPropertyDescriptor: function(k) {
1326 if (k >= "z") return void 0
1327 // Return a proxy as property descriptor, so that we can log accesses.
1328 return Proxy.create({
1329 get: function(r, attr) {
1330 descget += attr[0].toUpperCase()
1331 return true
1332 },
1333 has: function(attr) {
1334 descget += attr[0]
1335 switch (attr) {
1336 case "writable":
1337 case "enumerable":
1338 case "configurable":
1339 case "value":
1340 return true
1341 case "get":
1342 case "set":
1343 return false
1344 default:
1345 assertUnreachable()
1346 }
1347 }
1348 })
1349 }
1350})
1351
1352
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001353
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001354// Own Properties (Object.prototype.hasOwnProperty).
1355
1356var key
Ben Murdoch589d6972011-11-30 16:04:58 +00001357
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001358function TestHasOwn(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001359 TestWithProxies(TestHasOwn2, handler)
1360}
1361
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001362function TestHasOwn2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001363 var p = create(handler)
1364 assertTrue(Object.prototype.hasOwnProperty.call(p, "a"))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001365 assertEquals("a", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00001366 assertTrue(Object.prototype.hasOwnProperty.call(p, 99))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001367 assertEquals("99", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00001368 assertFalse(Object.prototype.hasOwnProperty.call(p, "z"))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001369 assertEquals("z", key)
1370}
1371
1372TestHasOwn({
1373 hasOwn: function(k) { key = k; return k < "z" }
1374})
1375
1376TestHasOwn({
1377 hasOwn: function(k) { return this.hasOwn2(k) },
1378 hasOwn2: function(k) { key = k; return k < "z" }
1379})
1380
1381TestHasOwn({
1382 getOwnPropertyDescriptor: function(k) {
1383 key = k; return k < "z" ? {value: 42} : void 0
1384 }
1385})
1386
1387TestHasOwn({
1388 getOwnPropertyDescriptor: function(k) {
1389 return this.getOwnPropertyDescriptor2(k)
1390 },
1391 getOwnPropertyDescriptor2: function(k) {
1392 key = k; return k < "z" ? {value: 42} : void 0
1393 }
1394})
1395
1396TestHasOwn({
1397 getOwnPropertyDescriptor: function(k) {
1398 key = k; return k < "z" ? {get value() { return 42 }} : void 0
1399 }
1400})
1401
1402TestHasOwn({
1403 hasOwn: undefined,
1404 getOwnPropertyDescriptor: function(k) {
1405 key = k; return k < "z" ? {value: 42} : void 0
1406 }
1407})
1408
1409TestHasOwn(Proxy.create({
1410 get: function(pr, pk) {
1411 return function(k) { key = k; return k < "z" }
1412 }
1413}))
1414
1415
Ben Murdoch589d6972011-11-30 16:04:58 +00001416function TestHasOwnThrow(handler) {
1417 TestWithProxies(TestHasOwnThrow2, handler)
1418}
1419
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001420function TestHasOwnThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001421 var p = create(handler)
1422 assertThrows(function(){ Object.prototype.hasOwnProperty.call(p, "a")},
1423 "myexn")
1424 assertThrows(function(){ Object.prototype.hasOwnProperty.call(p, 99)},
1425 "myexn")
1426}
1427
1428TestHasOwnThrow({
1429 hasOwn: function(k) { throw "myexn" }
1430})
1431
1432TestHasOwnThrow({
1433 hasOwn: function(k) { return this.hasOwn2(k) },
1434 hasOwn2: function(k) { throw "myexn" }
1435})
1436
1437TestHasOwnThrow({
1438 getOwnPropertyDescriptor: function(k) { throw "myexn" }
1439})
1440
1441TestHasOwnThrow({
1442 getOwnPropertyDescriptor: function(k) {
1443 return this.getOwnPropertyDescriptor2(k)
1444 },
1445 getOwnPropertyDescriptor2: function(k) { throw "myexn" }
1446})
1447
1448TestHasOwnThrow({
1449 hasOwn: undefined,
1450 getOwnPropertyDescriptor: function(k) { throw "myexn" }
1451})
1452
1453TestHasOwnThrow(Proxy.create({
1454 get: function(pr, pk) { throw "myexn" }
1455}))
1456
1457TestHasOwnThrow(Proxy.create({
1458 get: function(pr, pk) {
1459 return function(k) { throw "myexn" }
1460 }
1461}))
1462
1463
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001464
1465// Instanceof (instanceof)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001466
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001467function TestProxyInstanceof() {
1468 var o1 = {}
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001469 var p1 = Proxy.create({})
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001470 var p2 = Proxy.create({}, o1)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001471 var p3 = Proxy.create({}, p2)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001472 var o2 = Object.create(p2)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001473
Ben Murdoch589d6972011-11-30 16:04:58 +00001474 var f0 = function() {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001475 f0.prototype = o1
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001476 var f1 = function() {}
1477 f1.prototype = p1
1478 var f2 = function() {}
1479 f2.prototype = p2
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001480 var f3 = function() {}
1481 f3.prototype = o2
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001482
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001483 assertTrue(o1 instanceof Object)
1484 assertFalse(o1 instanceof f0)
1485 assertFalse(o1 instanceof f1)
1486 assertFalse(o1 instanceof f2)
1487 assertFalse(o1 instanceof f3)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001488 assertFalse(p1 instanceof Object)
Ben Murdoch589d6972011-11-30 16:04:58 +00001489 assertFalse(p1 instanceof f0)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001490 assertFalse(p1 instanceof f1)
1491 assertFalse(p1 instanceof f2)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001492 assertFalse(p1 instanceof f3)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001493 assertTrue(p2 instanceof Object)
Ben Murdoch589d6972011-11-30 16:04:58 +00001494 assertTrue(p2 instanceof f0)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001495 assertFalse(p2 instanceof f1)
1496 assertFalse(p2 instanceof f2)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001497 assertFalse(p2 instanceof f3)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001498 assertTrue(p3 instanceof Object)
Ben Murdoch589d6972011-11-30 16:04:58 +00001499 assertTrue(p3 instanceof f0)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001500 assertFalse(p3 instanceof f1)
1501 assertTrue(p3 instanceof f2)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001502 assertFalse(p3 instanceof f3)
1503 assertTrue(o2 instanceof Object)
1504 assertTrue(o2 instanceof f0)
1505 assertFalse(o2 instanceof f1)
1506 assertTrue(o2 instanceof f2)
1507 assertFalse(o2 instanceof f3)
Ben Murdoch589d6972011-11-30 16:04:58 +00001508
1509 var f = Proxy.createFunction({}, function() {})
1510 assertTrue(f instanceof Function)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001511}
1512
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001513TestProxyInstanceof()
1514
1515
1516function TestInstanceofProxy() {
1517 var o0 = Object.create(null)
1518 var o1 = {}
1519 var o2 = Object.create(o0)
1520 var o3 = Object.create(o1)
1521 var o4 = Object.create(o2)
1522 var o5 = Object.create(o3)
1523
1524 function handler(o) { return {get: function() { return o } } }
1525 var f0 = Proxy.createFunction(handler(o0), function() {})
1526 var f1 = Proxy.createFunction(handler(o1), function() {})
1527 var f2 = Proxy.createFunction(handler(o2), function() {})
1528 var f3 = Proxy.createFunction(handler(o3), function() {})
1529 var f4 = Proxy.createFunction(handler(o4), function() {})
1530 var f5 = Proxy.createFunction(handler(o4), function() {})
1531
1532 assertFalse(null instanceof f0)
1533 assertFalse(o0 instanceof f0)
1534 assertFalse(o0 instanceof f1)
1535 assertFalse(o0 instanceof f2)
1536 assertFalse(o0 instanceof f3)
1537 assertFalse(o0 instanceof f4)
1538 assertFalse(o0 instanceof f5)
1539 assertFalse(o1 instanceof f0)
1540 assertFalse(o1 instanceof f1)
1541 assertFalse(o1 instanceof f2)
1542 assertFalse(o1 instanceof f3)
1543 assertFalse(o1 instanceof f4)
1544 assertFalse(o1 instanceof f5)
1545 assertTrue(o2 instanceof f0)
1546 assertFalse(o2 instanceof f1)
1547 assertFalse(o2 instanceof f2)
1548 assertFalse(o2 instanceof f3)
1549 assertFalse(o2 instanceof f4)
1550 assertFalse(o2 instanceof f5)
1551 assertFalse(o3 instanceof f0)
1552 assertTrue(o3 instanceof f1)
1553 assertFalse(o3 instanceof f2)
1554 assertFalse(o3 instanceof f3)
1555 assertFalse(o3 instanceof f4)
1556 assertFalse(o3 instanceof f5)
1557 assertTrue(o4 instanceof f0)
1558 assertFalse(o4 instanceof f1)
1559 assertTrue(o4 instanceof f2)
1560 assertFalse(o4 instanceof f3)
1561 assertFalse(o4 instanceof f4)
1562 assertFalse(o4 instanceof f5)
1563 assertFalse(o5 instanceof f0)
1564 assertTrue(o5 instanceof f1)
1565 assertFalse(o5 instanceof f2)
1566 assertTrue(o5 instanceof f3)
1567 assertFalse(o5 instanceof f4)
1568 assertFalse(o5 instanceof f5)
1569
1570 var f = Proxy.createFunction({}, function() {})
1571 var ff = Proxy.createFunction(handler(Function), function() {})
1572 assertTrue(f instanceof Function)
1573 assertFalse(f instanceof ff)
1574}
1575
1576TestInstanceofProxy()
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001577
1578
1579
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001580// Prototype (Object.getPrototypeOf, Object.prototype.isPrototypeOf).
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001581
1582function TestPrototype() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001583 var o1 = {}
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001584 var p1 = Proxy.create({})
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001585 var p2 = Proxy.create({}, o1)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001586 var p3 = Proxy.create({}, p2)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001587 var p4 = Proxy.create({}, null)
1588 var o2 = Object.create(p3)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001589
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001590 assertSame(Object.getPrototypeOf(o1), Object.prototype)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001591 assertSame(Object.getPrototypeOf(p1), null)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001592 assertSame(Object.getPrototypeOf(p2), o1)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001593 assertSame(Object.getPrototypeOf(p3), p2)
1594 assertSame(Object.getPrototypeOf(p4), null)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001595 assertSame(Object.getPrototypeOf(o2), p3)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001596
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001597 assertTrue(Object.prototype.isPrototypeOf(o1))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001598 assertFalse(Object.prototype.isPrototypeOf(p1))
1599 assertTrue(Object.prototype.isPrototypeOf(p2))
1600 assertTrue(Object.prototype.isPrototypeOf(p3))
1601 assertFalse(Object.prototype.isPrototypeOf(p4))
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001602 assertTrue(Object.prototype.isPrototypeOf(o2))
1603 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o1))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001604 assertFalse(Object.prototype.isPrototypeOf.call(Object.prototype, p1))
1605 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p2))
1606 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p3))
1607 assertFalse(Object.prototype.isPrototypeOf.call(Object.prototype, p4))
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001608 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o2))
1609 assertFalse(Object.prototype.isPrototypeOf.call(o1, o1))
1610 assertFalse(Object.prototype.isPrototypeOf.call(o1, p1))
1611 assertTrue(Object.prototype.isPrototypeOf.call(o1, p2))
1612 assertTrue(Object.prototype.isPrototypeOf.call(o1, p3))
1613 assertFalse(Object.prototype.isPrototypeOf.call(o1, p4))
1614 assertTrue(Object.prototype.isPrototypeOf.call(o1, o2))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001615 assertFalse(Object.prototype.isPrototypeOf.call(p1, p1))
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001616 assertFalse(Object.prototype.isPrototypeOf.call(p1, o1))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001617 assertFalse(Object.prototype.isPrototypeOf.call(p1, p2))
1618 assertFalse(Object.prototype.isPrototypeOf.call(p1, p3))
1619 assertFalse(Object.prototype.isPrototypeOf.call(p1, p4))
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001620 assertFalse(Object.prototype.isPrototypeOf.call(p1, o2))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001621 assertFalse(Object.prototype.isPrototypeOf.call(p2, p1))
1622 assertFalse(Object.prototype.isPrototypeOf.call(p2, p2))
1623 assertTrue(Object.prototype.isPrototypeOf.call(p2, p3))
1624 assertFalse(Object.prototype.isPrototypeOf.call(p2, p4))
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001625 assertTrue(Object.prototype.isPrototypeOf.call(p2, o2))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001626 assertFalse(Object.prototype.isPrototypeOf.call(p3, p2))
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001627 assertTrue(Object.prototype.isPrototypeOf.call(p3, o2))
1628 assertFalse(Object.prototype.isPrototypeOf.call(o2, o1))
1629 assertFalse(Object.prototype.isPrototypeOf.call(o2, p1))
1630 assertFalse(Object.prototype.isPrototypeOf.call(o2, p2))
1631 assertFalse(Object.prototype.isPrototypeOf.call(o2, p3))
1632 assertFalse(Object.prototype.isPrototypeOf.call(o2, p4))
1633 assertFalse(Object.prototype.isPrototypeOf.call(o2, o2))
Ben Murdoch589d6972011-11-30 16:04:58 +00001634
1635 var f = Proxy.createFunction({}, function() {})
1636 assertSame(Object.getPrototypeOf(f), Function.prototype)
1637 assertTrue(Object.prototype.isPrototypeOf(f))
1638 assertTrue(Object.prototype.isPrototypeOf.call(Function.prototype, f))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001639}
1640
1641TestPrototype()
1642
1643
1644
1645// Property names (Object.getOwnPropertyNames, Object.keys).
1646
1647function TestPropertyNames(names, handler) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001648 TestWithProxies(TestPropertyNames2, handler, names)
Ben Murdoch589d6972011-11-30 16:04:58 +00001649}
1650
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001651function TestPropertyNames2(create, handler, names) {
1652 var p = create(handler)
1653 assertArrayEquals(names, Object.getOwnPropertyNames(p))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001654}
1655
1656TestPropertyNames([], {
1657 getOwnPropertyNames: function() { return [] }
1658})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001659
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001660TestPropertyNames(["a", "zz", " ", "0", "toString"], {
1661 getOwnPropertyNames: function() { return ["a", "zz", " ", 0, "toString"] }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001662})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001663
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001664TestPropertyNames(["throw", "function "], {
1665 getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
1666 getOwnPropertyNames2: function() { return ["throw", "function "] }
1667})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001668
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001669TestPropertyNames(["[object Object]"], {
1670 get getOwnPropertyNames() {
1671 return function() { return [{}] }
1672 }
1673})
1674
1675
Ben Murdoch589d6972011-11-30 16:04:58 +00001676function TestPropertyNamesThrow(handler) {
1677 TestWithProxies(TestPropertyNamesThrow2, handler)
1678}
1679
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001680function TestPropertyNamesThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001681 var p = create(handler)
1682 assertThrows(function(){ Object.getOwnPropertyNames(p) }, "myexn")
1683}
1684
1685TestPropertyNamesThrow({
1686 getOwnPropertyNames: function() { throw "myexn" }
1687})
1688
1689TestPropertyNamesThrow({
1690 getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
1691 getOwnPropertyNames2: function() { throw "myexn" }
1692})
1693
1694
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001695function TestKeys(names, handler) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001696 TestWithProxies(TestKeys2, handler, names)
Ben Murdoch589d6972011-11-30 16:04:58 +00001697}
1698
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001699function TestKeys2(create, handler, names) {
1700 var p = create(handler)
1701 assertArrayEquals(names, Object.keys(p))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001702}
1703
1704TestKeys([], {
1705 keys: function() { return [] }
1706})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001707
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001708TestKeys(["a", "zz", " ", "0", "toString"], {
1709 keys: function() { return ["a", "zz", " ", 0, "toString"] }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001710})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001711
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001712TestKeys(["throw", "function "], {
1713 keys: function() { return this.keys2() },
1714 keys2: function() { return ["throw", "function "] }
1715})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001716
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001717TestKeys(["[object Object]"], {
1718 get keys() {
1719 return function() { return [{}] }
1720 }
1721})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001722
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001723TestKeys(["a", "0"], {
1724 getOwnPropertyNames: function() { return ["a", 23, "zz", "", 0] },
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001725 getOwnPropertyDescriptor: function(k) {
1726 return k == "" ? undefined : {enumerable: k.length == 1}
1727 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001728})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001729
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001730TestKeys(["23", "zz", ""], {
1731 getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
1732 getOwnPropertyNames2: function() { return ["a", 23, "zz", "", 0] },
1733 getOwnPropertyDescriptor: function(k) {
1734 return this.getOwnPropertyDescriptor2(k)
1735 },
1736 getOwnPropertyDescriptor2: function(k) { return {enumerable: k.length != 1} }
1737})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001738
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001739TestKeys(["a", "b", "c", "5"], {
1740 get getOwnPropertyNames() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001741 return function() { return ["0", 4, "a", "b", "c", 5, "ety"] }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001742 },
1743 get getOwnPropertyDescriptor() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001744 return function(k) {
1745 return k == "ety" ? undefined : {enumerable: k >= "44"}
1746 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001747 }
1748})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001749
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001750TestKeys([], {
1751 get getOwnPropertyNames() {
1752 return function() { return ["a", "b", "c"] }
1753 },
1754 getOwnPropertyDescriptor: function(k) { return {} }
1755})
1756
1757
Ben Murdoch589d6972011-11-30 16:04:58 +00001758function TestKeysThrow(handler) {
1759 TestWithProxies(TestKeysThrow2, handler)
1760}
1761
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001762function TestKeysThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001763 var p = create(handler)
1764 assertThrows(function(){ Object.keys(p) }, "myexn")
1765}
1766
1767TestKeysThrow({
1768 keys: function() { throw "myexn" }
1769})
1770
1771TestKeysThrow({
1772 keys: function() { return this.keys2() },
1773 keys2: function() { throw "myexn" }
1774})
1775
1776TestKeysThrow({
1777 getOwnPropertyNames: function() { throw "myexn" },
1778 getOwnPropertyDescriptor: function(k) { return true }
1779})
1780
1781TestKeysThrow({
1782 getOwnPropertyNames: function() { return [1, 2] },
1783 getOwnPropertyDescriptor: function(k) { throw "myexn" }
1784})
1785
1786TestKeysThrow({
1787 getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
1788 getOwnPropertyNames2: function() { throw "myexn" },
1789})
1790
1791TestKeysThrow({
1792 getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
1793 getOwnPropertyNames2: function() { return [1, 2] },
1794 getOwnPropertyDescriptor: function(k) {
1795 return this.getOwnPropertyDescriptor2(k)
1796 },
1797 getOwnPropertyDescriptor2: function(k) { throw "myexn" }
1798})
1799
1800TestKeysThrow({
1801 get getOwnPropertyNames() { throw "myexn" }
1802})
1803
1804TestKeysThrow({
1805 get getOwnPropertyNames() {
1806 return function() { throw "myexn" }
1807 },
1808})
1809
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001810TestKeysThrow({
Ben Murdoch589d6972011-11-30 16:04:58 +00001811 get getOwnPropertyNames() {
1812 return function() { return [1, 2] }
1813 },
1814 getOwnPropertyDescriptor: function(k) { throw "myexn" }
1815})
1816
1817
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001818
1819// Fixing (Object.freeze, Object.seal, Object.preventExtensions,
1820// Object.isFrozen, Object.isSealed, Object.isExtensible)
1821
1822function TestFix(names, handler) {
1823 var proto = {p: 77}
1824 var assertFixing = function(o, s, f, e) {
1825 assertEquals(s, Object.isSealed(o))
1826 assertEquals(f, Object.isFrozen(o))
1827 assertEquals(e, Object.isExtensible(o))
1828 }
1829
Ben Murdoch589d6972011-11-30 16:04:58 +00001830 var p1 = Proxy.create(handler, proto)
1831 assertFixing(p1, false, false, true)
1832 Object.seal(p1)
1833 assertFixing(p1, true, names.length === 0, false)
1834 assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p1).sort())
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001835 assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(),
Ben Murdoch589d6972011-11-30 16:04:58 +00001836 Object.keys(p1).sort())
1837 assertEquals(proto, Object.getPrototypeOf(p1))
1838 assertEquals(77, p1.p)
1839 for (var n in p1) {
1840 var desc = Object.getOwnPropertyDescriptor(p1, n)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001841 if (desc !== undefined) assertFalse(desc.configurable)
1842 }
1843
Ben Murdoch589d6972011-11-30 16:04:58 +00001844 var p2 = Proxy.create(handler, proto)
1845 assertFixing(p2, false, false, true)
1846 Object.freeze(p2)
1847 assertFixing(p2, true, true, false)
1848 assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p2).sort())
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001849 assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(),
Ben Murdoch589d6972011-11-30 16:04:58 +00001850 Object.keys(p2).sort())
1851 assertEquals(proto, Object.getPrototypeOf(p2))
1852 assertEquals(77, p2.p)
1853 for (var n in p2) {
1854 var desc = Object.getOwnPropertyDescriptor(p2, n)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001855 if (desc !== undefined) assertFalse(desc.writable)
1856 if (desc !== undefined) assertFalse(desc.configurable)
1857 }
1858
Ben Murdoch589d6972011-11-30 16:04:58 +00001859 var p3 = Proxy.create(handler, proto)
1860 assertFixing(p3, false, false, true)
1861 Object.preventExtensions(p3)
1862 assertFixing(p3, names.length === 0, names.length === 0, false)
1863 assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p3).sort())
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001864 assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(),
Ben Murdoch589d6972011-11-30 16:04:58 +00001865 Object.keys(p3).sort())
1866 assertEquals(proto, Object.getPrototypeOf(p3))
1867 assertEquals(77, p3.p)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001868
1869 var p = Proxy.create(handler, proto)
1870 var o = Object.create(p)
1871 assertFixing(p, false, false, true)
1872 assertFixing(o, false, false, true)
1873 Object.freeze(o)
1874 assertFixing(p, false, false, true)
1875 assertFixing(o, true, true, false)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001876}
1877
1878TestFix([], {
1879 fix: function() { return {} }
1880})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001881
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001882TestFix(["a", "b", "c", "3", "zz"], {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001883 fix: function() {
1884 return {
1885 a: {value: "a", writable: true, configurable: false, enumerable: true},
1886 b: {value: 33, writable: false, configurable: false, enumerable: true},
1887 c: {value: 0, writable: true, configurable: true, enumerable: true},
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001888 '3': {value: true, writable: false, configurable: true, enumerable: true},
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001889 zz: {value: 0, enumerable: false}
1890 }
1891 }
1892})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001893
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001894TestFix(["a"], {
1895 fix: function() { return this.fix2() },
1896 fix2: function() {
1897 return {a: {value: 4, writable: true, configurable: true, enumerable: true}}
1898 }
1899})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001900
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001901TestFix(["b"], {
1902 get fix() {
1903 return function() {
1904 return {b: {configurable: true, writable: true, enumerable: true}}
1905 }
1906 }
1907})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001908
1909
Ben Murdoch589d6972011-11-30 16:04:58 +00001910function TestFixFunction(fix) {
1911 var f1 = Proxy.createFunction({
1912 fix: function() { return {} }
1913 }, function() {})
1914 fix(f1)
1915 assertEquals(0, f1.length)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001916
Ben Murdoch589d6972011-11-30 16:04:58 +00001917 var f2 = Proxy.createFunction({
1918 fix: function() { return {length: {value: 3}} }
1919 }, function() {})
1920 fix(f2)
1921 assertEquals(3, f2.length)
1922
1923 var f3 = Proxy.createFunction({
1924 fix: function() { return {length: {value: "huh"}} }
1925 }, function() {})
1926 fix(f3)
1927 assertEquals(0, f1.length)
1928}
1929
1930TestFixFunction(Object.seal)
1931TestFixFunction(Object.freeze)
1932TestFixFunction(Object.preventExtensions)
1933
1934
1935function TestFixThrow(handler) {
1936 TestWithProxies(TestFixThrow2, handler)
1937}
1938
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001939function TestFixThrow2(create, handler) {
1940 var p = create(handler, {})
Ben Murdoch589d6972011-11-30 16:04:58 +00001941 assertThrows(function(){ Object.seal(p) }, "myexn")
1942 assertThrows(function(){ Object.freeze(p) }, "myexn")
1943 assertThrows(function(){ Object.preventExtensions(p) }, "myexn")
1944}
1945
1946TestFixThrow({
1947 fix: function() { throw "myexn" }
1948})
1949
1950TestFixThrow({
1951 fix: function() { return this.fix2() },
1952 fix2: function() { throw "myexn" }
1953})
1954
1955TestFixThrow({
1956 get fix() { throw "myexn" }
1957})
1958
1959TestFixThrow({
1960 get fix() {
1961 return function() { throw "myexn" }
1962 }
1963})
1964
1965
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001966// Freeze a proxy in the middle of operations on it.
1967// TODO(rossberg): actual behaviour not specified consistently at the moment,
1968// just make sure that we do not crash.
1969function TestReentrantFix(f) {
1970 TestWithProxies(f, Object.freeze)
1971 TestWithProxies(f, Object.seal)
1972 TestWithProxies(f, Object.preventExtensions)
1973}
1974
1975TestReentrantFix(function(create, freeze) {
1976 var handler = {
1977 get get() { freeze(p); return undefined },
1978 fix: function() { return {} }
1979 }
1980 var p = create(handler)
1981 // Freeze while getting get trap.
1982 try { p.x } catch (e) { assertInstanceof(e, Error) }
1983})
1984
1985TestReentrantFix(function(create, freeze) {
1986 var handler = {
1987 get: function() { freeze(p); return 3 },
1988 fix: function() { return {} }
1989 }
1990 var p = create(handler)
1991 // Freeze while executing get trap.
1992 try { p.x } catch (e) { assertInstanceof(e, Error) }
1993})
1994
1995TestReentrantFix(function(create, freeze) {
1996 var handler = {
1997 getPropertyDescriptor: function() { freeze(p); return undefined },
1998 fix: function() { return {} }
1999 }
2000 var p = create(handler)
2001 // Freeze while executing default get trap.
2002 try { p.x } catch (e) { assertInstanceof(e, Error) }
2003})
2004
2005TestReentrantFix(function(create, freeze) {
2006 var handler = {
2007 getPropertyDescriptor: function() { freeze(p); return {get: function(){}} },
2008 fix: function() { return {} }
2009 }
2010 var p = create(handler)
2011 var o = Object.create(p)
2012 // Freeze while getting a property from prototype.
2013 try { o.x } catch (e) { assertInstanceof(e, Error) }
2014})
2015
2016TestReentrantFix(function(create, freeze) {
2017 var handler = {
2018 get set() { freeze(p); return undefined },
2019 fix: function() { return {} }
2020 }
2021 var p = create(handler)
2022 // Freeze while getting set trap.
2023 try { p.x = 4 } catch (e) { assertInstanceof(e, Error) }
2024})
2025
2026TestReentrantFix(function(create, freeze) {
2027 var handler = {
2028 set: function() { freeze(p); return true },
2029 fix: function() { return {} }
2030 }
2031 var p = create(handler)
2032 // Freeze while executing set trap.
2033 try { p.x = 4 } catch (e) { assertInstanceof(e, Error) }
2034})
2035
2036TestReentrantFix(function(create, freeze) {
2037 var handler = {
2038 getOwnPropertyDescriptor: function() { freeze(p); return undefined },
2039 fix: function() { return {} }
2040 }
2041 var p = create(handler)
2042 // Freeze while executing default set trap.
2043 try { p.x } catch (e) { assertInstanceof(e, Error) }
2044})
2045
2046TestReentrantFix(function(create, freeze) {
2047 var handler = {
2048 getPropertyDescriptor: function() { freeze(p); return {set: function(){}} },
2049 fix: function() { return {} }
2050 }
2051 var p = create(handler)
2052 var o = Object.create(p)
2053 // Freeze while setting a property in prototype, dropping the property!
2054 try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
2055})
2056
2057TestReentrantFix(function(create, freeze) {
2058 var handler = {
2059 getPropertyDescriptor: function() { freeze(p); return {set: function(){}} },
2060 fix: function() { return {x: {get: function(){}}} }
2061 }
2062 var p = create(handler)
2063 var o = Object.create(p)
2064 // Freeze while setting a property in prototype, making it read-only!
2065 try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
2066})
2067
2068TestReentrantFix(function(create, freeze) {
2069 var handler = {
2070 get fix() { freeze(p); return function(){} }
2071 }
2072 var p = create(handler)
2073 // Freeze while getting fix trap.
2074 try { Object.freeze(p) } catch (e) { assertInstanceof(e, Error) }
2075 p = create(handler)
2076 try { Object.seal(p) } catch (e) { assertInstanceof(e, Error) }
2077 p = create(handler)
2078 try { Object.preventExtensions(p) } catch (e) { assertInstanceof(e, Error) }
2079})
2080
2081TestReentrantFix(function(create, freeze) {
2082 var handler = {
2083 fix: function() { freeze(p); return {} }
2084 }
2085 var p = create(handler)
2086 // Freeze while executing fix trap.
2087 try { Object.freeze(p) } catch (e) { assertInstanceof(e, Error) }
2088 p = create(handler)
2089 try { Object.seal(p) } catch (e) { assertInstanceof(e, Error) }
2090 p = create(handler)
2091 try { Object.preventExtensions(p) } catch (e) { assertInstanceof(e, Error) }
2092})
2093
2094
Ben Murdoch589d6972011-11-30 16:04:58 +00002095
2096// String conversion (Object.prototype.toString,
2097// Object.prototype.toLocaleString,
2098// Function.prototype.toString)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002099
2100var key
Ben Murdoch589d6972011-11-30 16:04:58 +00002101
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002102function TestToString(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00002103 var p = Proxy.create(handler)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002104 key = ""
Ben Murdoch589d6972011-11-30 16:04:58 +00002105 assertEquals("[object Object]", Object.prototype.toString.call(p))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002106 assertEquals("", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00002107 assertEquals("my_proxy", Object.prototype.toLocaleString.call(p))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002108 assertEquals("toString", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00002109
2110 var f = Proxy.createFunction(handler, function() {})
2111 key = ""
2112 assertEquals("[object Function]", Object.prototype.toString.call(f))
2113 assertEquals("", key)
2114 assertEquals("my_proxy", Object.prototype.toLocaleString.call(f))
2115 assertEquals("toString", key)
2116 assertDoesNotThrow(function(){ Function.prototype.toString.call(f) })
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002117
2118 var o = Object.create(p)
2119 key = ""
2120 assertEquals("[object Object]", Object.prototype.toString.call(o))
2121 assertEquals("", key)
2122 assertEquals("my_proxy", Object.prototype.toLocaleString.call(o))
2123 assertEquals("toString", key)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002124}
2125
2126TestToString({
2127 get: function(r, k) { key = k; return function() { return "my_proxy" } }
2128})
2129
2130TestToString({
2131 get: function(r, k) { return this.get2(r, k) },
2132 get2: function(r, k) { key = k; return function() { return "my_proxy" } }
2133})
2134
2135TestToString(Proxy.create({
2136 get: function(pr, pk) {
2137 return function(r, k) { key = k; return function() { return "my_proxy" } }
2138 }
2139}))
2140
2141
Ben Murdoch589d6972011-11-30 16:04:58 +00002142function TestToStringThrow(handler) {
2143 var p = Proxy.create(handler)
2144 assertEquals("[object Object]", Object.prototype.toString.call(p))
2145 assertThrows(function(){ Object.prototype.toLocaleString.call(p) }, "myexn")
2146
2147 var f = Proxy.createFunction(handler, function() {})
2148 assertEquals("[object Function]", Object.prototype.toString.call(f))
2149 assertThrows(function(){ Object.prototype.toLocaleString.call(f) }, "myexn")
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002150
2151 var o = Object.create(p)
2152 assertEquals("[object Object]", Object.prototype.toString.call(o))
2153 assertThrows(function(){ Object.prototype.toLocaleString.call(o) }, "myexn")
Ben Murdoch589d6972011-11-30 16:04:58 +00002154}
2155
2156TestToStringThrow({
2157 get: function(r, k) { throw "myexn" }
2158})
2159
2160TestToStringThrow({
2161 get: function(r, k) { return function() { throw "myexn" } }
2162})
2163
2164TestToStringThrow({
2165 get: function(r, k) { return this.get2(r, k) },
2166 get2: function(r, k) { throw "myexn" }
2167})
2168
2169TestToStringThrow(Proxy.create({
2170 get: function(pr, pk) { throw "myexn" }
2171}))
2172
2173TestToStringThrow(Proxy.create({
2174 get: function(pr, pk) {
2175 return function(r, k) { throw "myexn" }
2176 }
2177}))
2178
2179
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002180
2181// Value conversion (Object.prototype.toValue)
2182
2183function TestValueOf(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00002184 TestWithProxies(TestValueOf2, handler)
2185}
2186
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002187function TestValueOf2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00002188 var p = create(handler)
2189 assertSame(p, Object.prototype.valueOf.call(p))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002190}
2191
2192TestValueOf({})
2193
2194
2195
2196// Enumerability (Object.prototype.propertyIsEnumerable)
2197
2198var key
Ben Murdoch589d6972011-11-30 16:04:58 +00002199
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002200function TestIsEnumerable(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00002201 TestWithProxies(TestIsEnumerable2, handler)
2202}
2203
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002204function TestIsEnumerable2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00002205 var p = create(handler)
2206 assertTrue(Object.prototype.propertyIsEnumerable.call(p, "a"))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002207 assertEquals("a", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00002208 assertTrue(Object.prototype.propertyIsEnumerable.call(p, 2))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002209 assertEquals("2", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00002210 assertFalse(Object.prototype.propertyIsEnumerable.call(p, "z"))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002211 assertEquals("z", key)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002212
2213 var o = Object.create(p)
2214 key = ""
2215 assertFalse(Object.prototype.propertyIsEnumerable.call(o, "a"))
2216 assertEquals("", key) // trap not invoked
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002217}
2218
2219TestIsEnumerable({
2220 getOwnPropertyDescriptor: function(k) {
2221 key = k; return {enumerable: k < "z", configurable: true}
2222 },
2223})
2224
2225TestIsEnumerable({
2226 getOwnPropertyDescriptor: function(k) {
2227 return this.getOwnPropertyDescriptor2(k)
2228 },
2229 getOwnPropertyDescriptor2: function(k) {
2230 key = k; return {enumerable: k < "z", configurable: true}
2231 },
2232})
2233
2234TestIsEnumerable({
2235 getOwnPropertyDescriptor: function(k) {
2236 key = k; return {get enumerable() { return k < "z" }, configurable: true}
2237 },
2238})
2239
2240TestIsEnumerable(Proxy.create({
2241 get: function(pr, pk) {
2242 return function(k) {
2243 key = k; return {enumerable: k < "z", configurable: true}
2244 }
2245 }
2246}))
Ben Murdoch589d6972011-11-30 16:04:58 +00002247
2248
2249function TestIsEnumerableThrow(handler) {
2250 TestWithProxies(TestIsEnumerableThrow2, handler)
2251}
2252
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002253function TestIsEnumerableThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00002254 var p = create(handler)
2255 assertThrows(function(){ Object.prototype.propertyIsEnumerable.call(p, "a") },
2256 "myexn")
2257 assertThrows(function(){ Object.prototype.propertyIsEnumerable.call(p, 11) },
2258 "myexn")
2259}
2260
2261TestIsEnumerableThrow({
2262 getOwnPropertyDescriptor: function(k) { throw "myexn" }
2263})
2264
2265TestIsEnumerableThrow({
2266 getOwnPropertyDescriptor: function(k) {
2267 return this.getOwnPropertyDescriptor2(k)
2268 },
2269 getOwnPropertyDescriptor2: function(k) { throw "myexn" }
2270})
2271
2272TestIsEnumerableThrow({
2273 getOwnPropertyDescriptor: function(k) {
2274 return {get enumerable() { throw "myexn" }, configurable: true}
2275 },
2276})
2277
2278TestIsEnumerableThrow(Proxy.create({
2279 get: function(pr, pk) { throw "myexn" }
2280}))
2281
2282TestIsEnumerableThrow(Proxy.create({
2283 get: function(pr, pk) {
2284 return function(k) { throw "myexn" }
2285 }
2286}))
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002287
2288
2289
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002290// Constructor functions with proxy prototypes.
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002291
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002292function TestConstructorWithProxyPrototype() {
2293 TestWithProxies(TestConstructorWithProxyPrototype2, {})
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002294}
2295
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002296function TestConstructorWithProxyPrototype2(create, handler) {
2297 function C() {};
2298 C.prototype = create(handler);
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002299
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002300 var o = new C;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002301 assertSame(C.prototype, Object.getPrototypeOf(o));
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002302}
2303
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002304TestConstructorWithProxyPrototype();