blob: 8d8f83996e255832168fa0c3c5a2d3f117888cb8 [file] [log] [blame]
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001// 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 Murdoch589d6972011-11-30 16:04:58 +000028// Flags: --harmony-proxies
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000029
Ben Murdoch589d6972011-11-30 16:04:58 +000030
Ben Murdoch589d6972011-11-30 16:04:58 +000031// Helper.
32
Ben Murdoch592a9fc2012-03-05 11:04:45 +000033function TestWithProxies(test, x, y, z) {
34 test(Proxy.create, x, y, z)
35 test(function(h) {return Proxy.createFunction(h, function() {})}, x, y, z)
Ben Murdoch589d6972011-11-30 16:04:58 +000036}
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000037
38
Ben Murdoch592a9fc2012-03-05 11:04:45 +000039
40// Getting property descriptors (Object.getOwnPropertyDescriptor).
41
42var key
43
44function TestGetOwnProperty(handler) {
45 TestWithProxies(TestGetOwnProperty2, handler)
46}
47
48function TestGetOwnProperty2(create, handler) {
49 var p = create(handler)
50 assertEquals(42, Object.getOwnPropertyDescriptor(p, "a").value)
51 assertEquals("a", key)
52 assertEquals(42, Object.getOwnPropertyDescriptor(p, 99).value)
53 assertEquals("99", key)
54}
55
56TestGetOwnProperty({
57 getOwnPropertyDescriptor: function(k) {
58 key = k
59 return {value: 42, configurable: true}
60 }
61})
62
63TestGetOwnProperty({
64 getOwnPropertyDescriptor: function(k) {
65 return this.getOwnPropertyDescriptor2(k)
66 },
67 getOwnPropertyDescriptor2: function(k) {
68 key = k
69 return {value: 42, configurable: true}
70 }
71})
72
73TestGetOwnProperty({
74 getOwnPropertyDescriptor: function(k) {
75 key = k
76 return {get value() { return 42 }, get configurable() { return true }}
77 }
78})
79
80TestGetOwnProperty(Proxy.create({
81 get: function(pr, pk) {
82 return function(k) { key = k; return {value: 42, configurable: true} }
83 }
84}))
85
86
87function TestGetOwnPropertyThrow(handler) {
88 TestWithProxies(TestGetOwnPropertyThrow2, handler)
89}
90
91function TestGetOwnPropertyThrow2(create, handler) {
92 var p = create(handler)
93 assertThrows(function(){ Object.getOwnPropertyDescriptor(p, "a") }, "myexn")
94 assertThrows(function(){ Object.getOwnPropertyDescriptor(p, 77) }, "myexn")
95}
96
97TestGetOwnPropertyThrow({
98 getOwnPropertyDescriptor: function(k) { throw "myexn" }
99})
100
101TestGetOwnPropertyThrow({
102 getOwnPropertyDescriptor: function(k) {
103 return this.getPropertyDescriptor2(k)
104 },
105 getOwnPropertyDescriptor2: function(k) { throw "myexn" }
106})
107
108TestGetOwnPropertyThrow({
109 getOwnPropertyDescriptor: function(k) {
110 return {get value() { throw "myexn" }}
111 }
112})
113
114TestGetOwnPropertyThrow(Proxy.create({
115 get: function(pr, pk) {
116 return function(k) { throw "myexn" }
117 }
118}))
119
120
121
122// Getters (dot, brackets).
123
124var key
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000125
126function TestGet(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000127 TestWithProxies(TestGet2, handler)
128}
129
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000130function TestGet2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000131 var p = create(handler)
132 assertEquals(42, p.a)
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000133 assertEquals("a", key)
Ben Murdoch589d6972011-11-30 16:04:58 +0000134 assertEquals(42, p["b"])
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000135 assertEquals("b", key)
136 assertEquals(42, p[99])
137 assertEquals("99", key)
138 assertEquals(42, (function(n) { return p[n] })("c"))
139 assertEquals("c", key)
140 assertEquals(42, (function(n) { return p[n] })(101))
141 assertEquals("101", key)
Ben Murdoch589d6972011-11-30 16:04:58 +0000142
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000143 var o = Object.create(p, {x: {value: 88}})
144 assertEquals(42, o.a)
145 assertEquals("a", key)
146 assertEquals(42, o["b"])
147 assertEquals("b", key)
148 assertEquals(42, o[99])
149 assertEquals("99", key)
150 assertEquals(88, o.x)
151 assertEquals(88, o["x"])
152 assertEquals(42, (function(n) { return o[n] })("c"))
153 assertEquals("c", key)
154 assertEquals(42, (function(n) { return o[n] })(101))
155 assertEquals("101", key)
156 assertEquals(88, (function(n) { return o[n] })("x"))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000157}
158
159TestGet({
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000160 get: function(r, k) { key = k; return 42 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000161})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000162
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000163TestGet({
164 get: function(r, k) { return this.get2(r, k) },
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000165 get2: function(r, k) { key = k; return 42 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000166})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000167
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000168TestGet({
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000169 getPropertyDescriptor: function(k) { key = k; return {value: 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({
173 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000174 getPropertyDescriptor2: function(k) { key = k; return {value: 42} }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000175})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000176
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000177TestGet({
178 getPropertyDescriptor: function(k) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000179 key = k;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000180 return {get value() { return 42 }}
181 }
182})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000183
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000184TestGet({
185 get: undefined,
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000186 getPropertyDescriptor: function(k) { key = k; return {value: 42} }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000187})
188
189TestGet(Proxy.create({
190 get: function(pr, pk) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000191 return function(r, k) { key = k; return 42 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000192 }
193}))
194
195
196function TestGetCall(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000197 TestWithProxies(TestGetCall2, handler)
198}
199
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000200function TestGetCall2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000201 var p = create(handler)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000202 assertEquals(55, p.f())
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000203 assertEquals(55, p["f"]())
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000204 assertEquals(55, p.f("unused", "arguments"))
205 assertEquals(55, p.f.call(p))
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000206 assertEquals(55, p["f"].call(p))
207 assertEquals(55, p[101].call(p))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000208 assertEquals(55, p.withargs(45, 5))
209 assertEquals(55, p.withargs.call(p, 11, 22))
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000210 assertEquals(55, (function(n) { return p[n]() })("f"))
211 assertEquals(55, (function(n) { return p[n].call(p) })("f"))
212 assertEquals(55, (function(n) { return p[n](15, 20) })("withargs"))
213 assertEquals(55, (function(n) { return p[n].call(p, 13, 21) })("withargs"))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000214 assertEquals("6655", "66" + p) // calls p.toString
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000215
216 var o = Object.create(p, {g: {value: function(x) { return x + 88 }}})
217 assertEquals(55, o.f())
218 assertEquals(55, o["f"]())
219 assertEquals(55, o.f("unused", "arguments"))
220 assertEquals(55, o.f.call(o))
221 assertEquals(55, o.f.call(p))
222 assertEquals(55, o["f"].call(p))
223 assertEquals(55, o[101].call(p))
224 assertEquals(55, o.withargs(45, 5))
225 assertEquals(55, o.withargs.call(p, 11, 22))
226 assertEquals(90, o.g(2))
227 assertEquals(91, o.g.call(o, 3))
228 assertEquals(92, o.g.call(p, 4))
229 assertEquals(55, (function(n) { return o[n]() })("f"))
230 assertEquals(55, (function(n) { return o[n].call(o) })("f"))
231 assertEquals(55, (function(n) { return o[n](15, 20) })("withargs"))
232 assertEquals(55, (function(n) { return o[n].call(o, 13, 21) })("withargs"))
233 assertEquals(93, (function(n) { return o[n](5) })("g"))
234 assertEquals(94, (function(n) { return o[n].call(o, 6) })("g"))
235 assertEquals(95, (function(n) { return o[n].call(p, 7) })("g"))
236 assertEquals("6655", "66" + o) // calls o.toString
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000237}
238
239TestGetCall({
240 get: function(r, k) { return function() { return 55 } }
241})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000242
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000243TestGetCall({
244 get: function(r, k) { return this.get2(r, k) },
245 get2: function(r, k) { return function() { return 55 } }
246})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000247
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000248TestGetCall({
249 getPropertyDescriptor: function(k) {
250 return {value: function() { return 55 }}
251 }
252})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000253
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000254TestGetCall({
255 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
256 getPropertyDescriptor2: function(k) {
257 return {value: function() { return 55 }}
258 }
259})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000260
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000261TestGetCall({
262 getPropertyDescriptor: function(k) {
263 return {get value() { return function() { return 55 } }}
264 }
265})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000266
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000267TestGetCall({
268 get: undefined,
269 getPropertyDescriptor: function(k) {
270 return {value: function() { return 55 }}
271 }
272})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000273
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000274TestGetCall({
275 get: function(r, k) {
276 if (k == "gg") {
277 return function() { return 55 }
278 } else if (k == "withargs") {
279 return function(n, m) { return n + m * 2 }
280 } else {
281 return function() { return this.gg() }
282 }
283 }
284})
285
286TestGetCall(Proxy.create({
287 get: function(pr, pk) {
288 return function(r, k) { return function() { return 55 } }
289 }
290}))
291
292
Ben Murdoch589d6972011-11-30 16:04:58 +0000293function TestGetThrow(handler) {
294 TestWithProxies(TestGetThrow2, handler)
295}
296
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000297function TestGetThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000298 var p = create(handler)
299 assertThrows(function(){ p.a }, "myexn")
300 assertThrows(function(){ p["b"] }, "myexn")
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000301 assertThrows(function(){ p[3] }, "myexn")
302 assertThrows(function(){ (function(n) { p[n] })("c") }, "myexn")
303 assertThrows(function(){ (function(n) { p[n] })(99) }, "myexn")
304
305 var o = Object.create(p, {x: {value: 88}, '4': {value: 89}})
306 assertThrows(function(){ o.a }, "myexn")
307 assertThrows(function(){ o["b"] }, "myexn")
308 assertThrows(function(){ o[3] }, "myexn")
309 assertThrows(function(){ (function(n) { o[n] })("c") }, "myexn")
310 assertThrows(function(){ (function(n) { o[n] })(99) }, "myexn")
Ben Murdoch589d6972011-11-30 16:04:58 +0000311}
312
313TestGetThrow({
314 get: function(r, k) { throw "myexn" }
315})
316
317TestGetThrow({
318 get: function(r, k) { return this.get2(r, k) },
319 get2: function(r, k) { throw "myexn" }
320})
321
322TestGetThrow({
323 getPropertyDescriptor: function(k) { throw "myexn" }
324})
325
326TestGetThrow({
327 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
328 getPropertyDescriptor2: function(k) { throw "myexn" }
329})
330
331TestGetThrow({
332 getPropertyDescriptor: function(k) {
333 return {get value() { throw "myexn" }}
334 }
335})
336
337TestGetThrow({
338 get: undefined,
339 getPropertyDescriptor: function(k) { throw "myexn" }
340})
341
342TestGetThrow(Proxy.create({
343 get: function(pr, pk) { throw "myexn" }
344}))
345
346TestGetThrow(Proxy.create({
347 get: function(pr, pk) {
348 return function(r, k) { throw "myexn" }
349 }
350}))
351
352
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000353
354// Setters.
355
356var key
357var val
Ben Murdoch589d6972011-11-30 16:04:58 +0000358
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000359function TestSet(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000360 TestWithProxies(TestSet2, handler)
361}
362
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000363function TestSet2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000364 var p = create(handler)
365 assertEquals(42, p.a = 42)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000366 assertEquals("a", key)
367 assertEquals(42, val)
Ben Murdoch589d6972011-11-30 16:04:58 +0000368 assertEquals(43, p["b"] = 43)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000369 assertEquals("b", key)
370 assertEquals(43, val)
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000371 assertEquals(44, p[77] = 44)
372 assertEquals("77", key)
373 assertEquals(44, val)
374
375 assertEquals(45, (function(n) { return p[n] = 45 })("c"))
376 assertEquals("c", key)
377 assertEquals(45, val)
378 assertEquals(46, (function(n) { return p[n] = 46 })(99))
379 assertEquals("99", key)
380 assertEquals(46, val)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000381}
382
383TestSet({
384 set: function(r, k, v) { key = k; val = v; return true }
385})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000386
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000387TestSet({
388 set: function(r, k, v) { return this.set2(r, k, v) },
389 set2: function(r, k, v) { key = k; val = v; return true }
390})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000391
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000392TestSet({
393 getOwnPropertyDescriptor: function(k) { return {writable: true} },
394 defineProperty: function(k, desc) { key = k; val = desc.value }
395})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000396
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000397TestSet({
398 getOwnPropertyDescriptor: function(k) {
399 return this.getOwnPropertyDescriptor2(k)
400 },
401 getOwnPropertyDescriptor2: function(k) { return {writable: true} },
402 defineProperty: function(k, desc) { this.defineProperty2(k, desc) },
403 defineProperty2: function(k, desc) { key = k; val = desc.value }
404})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000405
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000406TestSet({
407 getOwnPropertyDescriptor: function(k) {
408 return {get writable() { return true }}
409 },
410 defineProperty: function(k, desc) { key = k; val = desc.value }
411})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000412
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000413TestSet({
414 getOwnPropertyDescriptor: function(k) {
415 return {set: function(v) { key = k; val = v }}
416 }
417})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000418
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000419TestSet({
420 getOwnPropertyDescriptor: function(k) { return null },
421 getPropertyDescriptor: function(k) { return {writable: true} },
422 defineProperty: function(k, desc) { key = k; val = desc.value }
423})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000424
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000425TestSet({
426 getOwnPropertyDescriptor: function(k) { return null },
427 getPropertyDescriptor: function(k) {
428 return {get writable() { return true }}
429 },
430 defineProperty: function(k, desc) { key = k; val = desc.value }
431})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000432
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000433TestSet({
434 getOwnPropertyDescriptor: function(k) { return null },
435 getPropertyDescriptor: function(k) {
436 return {set: function(v) { key = k; val = v }}
437 }
438})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000439
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000440TestSet({
441 getOwnPropertyDescriptor: function(k) { return null },
442 getPropertyDescriptor: function(k) { return null },
443 defineProperty: function(k, desc) { key = k, val = desc.value }
444})
445
446TestSet(Proxy.create({
447 get: function(pr, pk) {
448 return function(r, k, v) { key = k; val = v; return true }
449 }
450}))
451
452
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000453function TestSetThrow(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000454 TestWithProxies(TestSetThrow2, handler)
455}
456
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000457function TestSetThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000458 var p = create(handler)
459 assertThrows(function(){ p.a = 42 }, "myexn")
460 assertThrows(function(){ p["b"] = 42 }, "myexn")
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000461 assertThrows(function(){ p[22] = 42 }, "myexn")
462 assertThrows(function(){ (function(n) { p[n] = 45 })("c") }, "myexn")
463 assertThrows(function(){ (function(n) { p[n] = 46 })(99) }, "myexn")
Ben Murdoch589d6972011-11-30 16:04:58 +0000464}
465
466TestSetThrow({
467 set: function(r, k, v) { throw "myexn" }
468})
469
470TestSetThrow({
471 set: function(r, k, v) { return this.set2(r, k, v) },
472 set2: function(r, k, v) { throw "myexn" }
473})
474
475TestSetThrow({
476 getOwnPropertyDescriptor: function(k) { throw "myexn" },
477 defineProperty: function(k, desc) { key = k; val = desc.value }
478})
479
480TestSetThrow({
481 getOwnPropertyDescriptor: function(k) { return {writable: true} },
482 defineProperty: function(k, desc) { throw "myexn" }
483})
484
485TestSetThrow({
486 getOwnPropertyDescriptor: function(k) {
487 return this.getOwnPropertyDescriptor2(k)
488 },
489 getOwnPropertyDescriptor2: function(k) { throw "myexn" },
490 defineProperty: function(k, desc) { this.defineProperty2(k, desc) },
491 defineProperty2: function(k, desc) { key = k; val = desc.value }
492})
493
494TestSetThrow({
495 getOwnPropertyDescriptor: function(k) {
496 return this.getOwnPropertyDescriptor2(k)
497 },
498 getOwnPropertyDescriptor2: function(k) { return {writable: true} },
499 defineProperty: function(k, desc) { this.defineProperty2(k, desc) },
500 defineProperty2: function(k, desc) { throw "myexn" }
501})
502
503TestSetThrow({
504 getOwnPropertyDescriptor: function(k) { throw "myexn" },
505 defineProperty: function(k, desc) { key = k; val = desc.value }
506})
507
508TestSetThrow({
509 getOwnPropertyDescriptor: function(k) {
510 return {get writable() { return true }}
511 },
512 defineProperty: function(k, desc) { throw "myexn" }
513})
514
515TestSetThrow({
516 getOwnPropertyDescriptor: function(k) { throw "myexn" }
517})
518
519TestSetThrow({
520 getOwnPropertyDescriptor: function(k) {
521 return {set: function(v) { throw "myexn" }}
522 }
523})
524
525TestSetThrow({
526 getOwnPropertyDescriptor: function(k) { throw "myexn" },
527 getPropertyDescriptor: function(k) { return {writable: true} },
528 defineProperty: function(k, desc) { key = k; val = desc.value }
529})
530
531TestSetThrow({
532 getOwnPropertyDescriptor: function(k) { return null },
533 getPropertyDescriptor: function(k) { throw "myexn" },
534 defineProperty: function(k, desc) { key = k; val = desc.value }
535})
536
537TestSetThrow({
538 getOwnPropertyDescriptor: function(k) { return null },
539 getPropertyDescriptor: function(k) { return {writable: true} },
540 defineProperty: function(k, desc) { throw "myexn" }
541})
542
543TestSetThrow({
544 getOwnPropertyDescriptor: function(k) { return null },
545 getPropertyDescriptor: function(k) {
546 return {get writable() { throw "myexn" }}
547 },
548 defineProperty: function(k, desc) { key = k; val = desc.value }
549})
550
551TestSetThrow({
552 getOwnPropertyDescriptor: function(k) { return null },
553 getPropertyDescriptor: function(k) {
554 return {set: function(v) { throw "myexn" }}
555 }
556})
557
558TestSetThrow({
559 getOwnPropertyDescriptor: function(k) { return null },
560 getPropertyDescriptor: function(k) { return null },
561 defineProperty: function(k, desc) { throw "myexn" }
562})
563
564TestSetThrow(Proxy.create({
565 get: function(pr, pk) { throw "myexn" }
566}))
567
568TestSetThrow(Proxy.create({
569 get: function(pr, pk) {
570 return function(r, k, v) { throw "myexn" }
571 }
572}))
573
574
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000575var key
576var val
577
578function TestSetForDerived(handler) {
579 TestWithProxies(TestSetForDerived2, handler)
580}
581
582function TestSetForDerived2(create, handler) {
583 var p = create(handler)
584 var o = Object.create(p, {x: {value: 88, writable: true},
585 '1': {value: 89, writable: true}})
586
587 key = ""
588 assertEquals(48, o.x = 48)
589 assertEquals("", key) // trap not invoked
590 assertEquals(48, o.x)
591
592 assertEquals(47, o[1] = 47)
593 assertEquals("", key) // trap not invoked
594 assertEquals(47, o[1])
595
596 assertEquals(49, o.y = 49)
597 assertEquals("y", key)
598 assertEquals(49, o.y)
599
600 assertEquals(50, o[2] = 50)
601 assertEquals("2", key)
602 assertEquals(50, o[2])
603
604 assertEquals(44, o.p_writable = 44)
605 assertEquals("p_writable", key)
606 assertEquals(44, o.p_writable)
607
608 assertEquals(45, o.p_nonwritable = 45)
609 assertEquals("p_nonwritable", key)
610 assertEquals(45, o.p_nonwritable)
611
612 assertEquals(46, o.p_setter = 46)
613 assertEquals("p_setter", key)
614 assertEquals(46, val) // written to parent
615 assertFalse(Object.prototype.hasOwnProperty.call(o, "p_setter"))
616
617 val = ""
618 assertEquals(47, o.p_nosetter = 47)
619 assertEquals("p_nosetter", key)
620 assertEquals("", val) // not written at all
621 assertFalse(Object.prototype.hasOwnProperty.call(o, "p_nosetter"));
622
623 key = ""
624 assertThrows(function(){ "use strict"; o.p_nosetter = 50 }, TypeError)
625 assertEquals("p_nosetter", key)
626 assertEquals("", val) // not written at all
627
628 assertThrows(function(){ o.p_nonconf = 53 }, TypeError)
629 assertEquals("p_nonconf", key)
630
631 assertThrows(function(){ o.p_throw = 51 }, "myexn")
632 assertEquals("p_throw", key)
633
634 assertThrows(function(){ o.p_setterthrow = 52 }, "myexn")
635 assertEquals("p_setterthrow", key)
636}
637
638TestSetForDerived({
639 getPropertyDescriptor: function(k) {
640 key = k;
641 switch (k) {
642 case "p_writable": return {writable: true, configurable: true}
643 case "p_nonwritable": return {writable: false, configurable: true}
644 case "p_setter":return {set: function(x) { val = x }, configurable: true}
645 case "p_nosetter": return {get: function() { return 1 }, configurable: true}
646 case "p_nonconf":return {}
647 case "p_throw": throw "myexn"
648 case "p_setterthrow": return {set: function(x) { throw "myexn" }}
649 default: return undefined
650 }
651 }
652})
653
654
655// Evil proxy-induced side-effects shouldn't crash.
656// TODO(rossberg): proper behaviour isn't really spec'ed yet, so ignore results.
657
658TestWithProxies(function(create) {
659 var calls = 0
660 var handler = {
661 getPropertyDescriptor: function() {
662 ++calls
663 return (calls % 2 == 1)
664 ? {get: function() { return 5 }, configurable: true}
665 : {set: function() { return false }, configurable: true}
666 }
667 }
668 var p = create(handler)
669 var o = Object.create(p)
670 // Make proxy prototype property read-only after CanPut check.
671 try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
672})
673
674TestWithProxies(function(create) {
675 var handler = {
676 getPropertyDescriptor: function() {
677 Object.defineProperty(o, "x", {get: function() { return 5 }});
678 return {set: function() {}}
679 }
680 }
681 var p = create(handler)
682 var o = Object.create(p)
683 // Make object property read-only after CanPut check.
684 try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
685})
686
687
688
689// TODO(rossberg): TestSetReject, returning false
690// TODO(rossberg): TestGetProperty, TestSetProperty
691
692
Ben Murdoch589d6972011-11-30 16:04:58 +0000693
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000694// Property definition (Object.defineProperty and Object.defineProperties).
695
696var key
697var desc
Ben Murdoch589d6972011-11-30 16:04:58 +0000698
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000699function TestDefine(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000700 TestWithProxies(TestDefine2, handler)
701}
702
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000703function TestDefine2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000704 var p = create(handler)
705 assertEquals(p, Object.defineProperty(p, "a", {value: 44}))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000706 assertEquals("a", key)
707 assertEquals(1, Object.getOwnPropertyNames(desc).length)
708 assertEquals(44, desc.value)
709
Ben Murdoch589d6972011-11-30 16:04:58 +0000710 assertEquals(p, Object.defineProperty(p, "b", {value: 45, writable: false}))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000711 assertEquals("b", key)
712 assertEquals(2, Object.getOwnPropertyNames(desc).length)
713 assertEquals(45, desc.value)
714 assertEquals(false, desc.writable)
715
Ben Murdoch589d6972011-11-30 16:04:58 +0000716 assertEquals(p, Object.defineProperty(p, "c", {value: 46, enumerable: false}))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000717 assertEquals("c", key)
718 assertEquals(2, Object.getOwnPropertyNames(desc).length)
719 assertEquals(46, desc.value)
720 assertEquals(false, desc.enumerable)
721
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000722 assertEquals(p, Object.defineProperty(p, 101, {value: 47, enumerable: false}))
723 assertEquals("101", key)
724 assertEquals(2, Object.getOwnPropertyNames(desc).length)
725 assertEquals(47, desc.value)
726 assertEquals(false, desc.enumerable)
727
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000728 var attributes = {configurable: true, mine: 66, minetoo: 23}
Ben Murdoch589d6972011-11-30 16:04:58 +0000729 assertEquals(p, Object.defineProperty(p, "d", attributes))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000730 assertEquals("d", key)
731 // Modifying the attributes object after the fact should have no effect.
732 attributes.configurable = false
733 attributes.mine = 77
734 delete attributes.minetoo
735 assertEquals(3, Object.getOwnPropertyNames(desc).length)
736 assertEquals(true, desc.configurable)
737 assertEquals(66, desc.mine)
738 assertEquals(23, desc.minetoo)
739
Ben Murdoch589d6972011-11-30 16:04:58 +0000740 assertEquals(p, Object.defineProperty(p, "e", {get: function(){ return 5 }}))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000741 assertEquals("e", key)
742 assertEquals(1, Object.getOwnPropertyNames(desc).length)
743 assertEquals(5, desc.get())
744
Ben Murdoch589d6972011-11-30 16:04:58 +0000745 assertEquals(p, Object.defineProperty(p, "zzz", {}))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000746 assertEquals("zzz", key)
747 assertEquals(0, Object.getOwnPropertyNames(desc).length)
748
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000749 var d = create({
750 get: function(r, k) { return (k === "value") ? 77 : void 0 },
751 getOwnPropertyNames: function() { return ["value"] },
752 enumerate: function() { return ["value"] }
753 })
754 assertEquals(1, Object.getOwnPropertyNames(d).length)
755 assertEquals(77, d.value)
756 assertEquals(p, Object.defineProperty(p, "p", d))
757 assertEquals("p", key)
758 assertEquals(1, Object.getOwnPropertyNames(desc).length)
759 assertEquals(77, desc.value)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000760
761 var props = {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000762 '11': {},
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000763 blub: {get: function() { return true }},
764 '': {get value() { return 20 }},
765 last: {value: 21, configurable: true, mine: "eyes"}
766 }
767 Object.defineProperty(props, "hidden", {value: "hidden", enumerable: false})
Ben Murdoch589d6972011-11-30 16:04:58 +0000768 assertEquals(p, Object.defineProperties(p, props))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000769 assertEquals("last", key)
770 assertEquals(2, Object.getOwnPropertyNames(desc).length)
771 assertEquals(21, desc.value)
772 assertEquals(true, desc.configurable)
773 assertEquals(undefined, desc.mine) // Arguably a bug in the spec...
Ben Murdoch589d6972011-11-30 16:04:58 +0000774
775 var props = {bla: {get value() { throw "myexn" }}}
776 assertThrows(function(){ Object.defineProperties(p, props) }, "myexn")
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000777}
778
779TestDefine({
780 defineProperty: function(k, d) { key = k; desc = d; return true }
781})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000782
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000783TestDefine({
784 defineProperty: function(k, d) { return this.defineProperty2(k, d) },
785 defineProperty2: function(k, d) { key = k; desc = d; return true }
786})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000787
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000788TestDefine(Proxy.create({
789 get: function(pr, pk) {
790 return function(k, d) { key = k; desc = d; return true }
791 }
792}))
793
794
Ben Murdoch589d6972011-11-30 16:04:58 +0000795function TestDefineThrow(handler) {
796 TestWithProxies(TestDefineThrow2, handler)
797}
798
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000799function TestDefineThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000800 var p = create(handler)
801 assertThrows(function(){ Object.defineProperty(p, "a", {value: 44})}, "myexn")
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000802 assertThrows(function(){ Object.defineProperty(p, 0, {value: 44})}, "myexn")
Ben Murdoch589d6972011-11-30 16:04:58 +0000803
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000804 var d1 = create({
805 get: function(r, k) { throw "myexn" },
806 getOwnPropertyNames: function() { return ["value"] }
807 })
808 assertThrows(function(){ Object.defineProperty(p, "p", d1) }, "myexn")
809 var d2 = create({
810 get: function(r, k) { return 77 },
811 getOwnPropertyNames: function() { throw "myexn" }
812 })
813 assertThrows(function(){ Object.defineProperty(p, "p", d2) }, "myexn")
Ben Murdoch589d6972011-11-30 16:04:58 +0000814
815 var props = {bla: {get value() { throw "otherexn" }}}
816 assertThrows(function(){ Object.defineProperties(p, props) }, "otherexn")
817}
818
819TestDefineThrow({
820 defineProperty: function(k, d) { throw "myexn" }
821})
822
823TestDefineThrow({
824 defineProperty: function(k, d) { return this.defineProperty2(k, d) },
825 defineProperty2: function(k, d) { throw "myexn" }
826})
827
828TestDefineThrow(Proxy.create({
829 get: function(pr, pk) { throw "myexn" }
830}))
831
832TestDefineThrow(Proxy.create({
833 get: function(pr, pk) {
834 return function(k, d) { throw "myexn" }
835 }
836}))
837
838
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000839
840// Property deletion (delete).
841
842var key
Ben Murdoch589d6972011-11-30 16:04:58 +0000843
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000844function TestDelete(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000845 TestWithProxies(TestDelete2, handler)
846}
847
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000848function TestDelete2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000849 var p = create(handler)
850 assertEquals(true, delete p.a)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000851 assertEquals("a", key)
Ben Murdoch589d6972011-11-30 16:04:58 +0000852 assertEquals(true, delete p["b"])
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000853 assertEquals("b", key)
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000854 assertEquals(true, delete p[1])
855 assertEquals("1", key)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000856
Ben Murdoch589d6972011-11-30 16:04:58 +0000857 assertEquals(false, delete p.z1)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000858 assertEquals("z1", key)
Ben Murdoch589d6972011-11-30 16:04:58 +0000859 assertEquals(false, delete p["z2"])
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000860 assertEquals("z2", key);
861
862 (function() {
863 "use strict"
Ben Murdoch589d6972011-11-30 16:04:58 +0000864 assertEquals(true, delete p.c)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000865 assertEquals("c", key)
Ben Murdoch589d6972011-11-30 16:04:58 +0000866 assertEquals(true, delete p["d"])
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000867 assertEquals("d", key)
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000868 assertEquals(true, delete p[2])
869 assertEquals("2", key)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000870
Ben Murdoch589d6972011-11-30 16:04:58 +0000871 assertThrows(function(){ delete p.z3 }, TypeError)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000872 assertEquals("z3", key)
Ben Murdoch589d6972011-11-30 16:04:58 +0000873 assertThrows(function(){ delete p["z4"] }, TypeError)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000874 assertEquals("z4", key)
875 })()
876}
877
878TestDelete({
Ben Murdoch589d6972011-11-30 16:04:58 +0000879 delete: function(k) { key = k; return k < "z" }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000880})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000881
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000882TestDelete({
Ben Murdoch589d6972011-11-30 16:04:58 +0000883 delete: function(k) { return this.delete2(k) },
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000884 delete2: function(k) { key = k; return k < "z" }
885})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000886
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000887TestDelete(Proxy.create({
888 get: function(pr, pk) {
889 return function(k) { key = k; return k < "z" }
890 }
891}))
892
893
Ben Murdoch589d6972011-11-30 16:04:58 +0000894function TestDeleteThrow(handler) {
895 TestWithProxies(TestDeleteThrow2, handler)
896}
897
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000898function TestDeleteThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000899 var p = create(handler)
900 assertThrows(function(){ delete p.a }, "myexn")
901 assertThrows(function(){ delete p["b"] }, "myexn");
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000902 assertThrows(function(){ delete p[3] }, "myexn");
Ben Murdoch589d6972011-11-30 16:04:58 +0000903
904 (function() {
905 "use strict"
906 assertThrows(function(){ delete p.c }, "myexn")
907 assertThrows(function(){ delete p["d"] }, "myexn")
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000908 assertThrows(function(){ delete p[4] }, "myexn");
Ben Murdoch589d6972011-11-30 16:04:58 +0000909 })()
910}
911
912TestDeleteThrow({
913 delete: function(k) { throw "myexn" }
914})
915
916TestDeleteThrow({
917 delete: function(k) { return this.delete2(k) },
918 delete2: function(k) { throw "myexn" }
919})
920
921TestDeleteThrow(Proxy.create({
922 get: function(pr, pk) { throw "myexn" }
923}))
924
925TestDeleteThrow(Proxy.create({
926 get: function(pr, pk) {
927 return function(k) { throw "myexn" }
928 }
929}))
930
931
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000932
933// Property descriptors (Object.getOwnPropertyDescriptor).
934
935function TestDescriptor(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000936 TestWithProxies(TestDescriptor2, handler)
937}
938
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000939function TestDescriptor2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000940 var p = create(handler)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000941 var descs = [
942 {configurable: true},
943 {value: 34, enumerable: true, configurable: true},
944 {value: 3, writable: false, mine: "eyes", configurable: true},
945 {get value() { return 20 }, get configurable() { return true }},
946 {get: function() { "get" }, set: function() { "set" }, configurable: true}
947 ]
948 for (var i = 0; i < descs.length; ++i) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000949 assertEquals(p, Object.defineProperty(p, i, descs[i]))
950 var desc = Object.getOwnPropertyDescriptor(p, i)
951 for (prop in descs[i]) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000952 // TODO(rossberg): Ignore user attributes as long as the spec isn't
953 // fixed suitably.
Ben Murdoch589d6972011-11-30 16:04:58 +0000954 if (prop != "mine") assertEquals(descs[i][prop], desc[prop])
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000955 }
Ben Murdoch589d6972011-11-30 16:04:58 +0000956 assertEquals(undefined, Object.getOwnPropertyDescriptor(p, "absent"))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000957 }
958}
959
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000960TestDescriptor({
961 defineProperty: function(k, d) { this["__" + k] = d; return true },
962 getOwnPropertyDescriptor: function(k) { return this["__" + k] }
963})
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000964
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000965TestDescriptor({
966 defineProperty: function(k, d) { this["__" + k] = d; return true },
967 getOwnPropertyDescriptor: function(k) {
968 return this.getOwnPropertyDescriptor2(k)
969 },
970 getOwnPropertyDescriptor2: function(k) { return this["__" + k] }
971})
972
973
Ben Murdoch589d6972011-11-30 16:04:58 +0000974function TestDescriptorThrow(handler) {
975 TestWithProxies(TestDescriptorThrow2, handler)
976}
977
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000978function TestDescriptorThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000979 var p = create(handler)
980 assertThrows(function(){ Object.getOwnPropertyDescriptor(p, "a") }, "myexn")
981}
982
983TestDescriptorThrow({
984 getOwnPropertyDescriptor: function(k) { throw "myexn" }
985})
986
987TestDescriptorThrow({
988 getOwnPropertyDescriptor: function(k) {
989 return this.getOwnPropertyDescriptor2(k)
990 },
991 getOwnPropertyDescriptor2: function(k) { throw "myexn" }
992})
993
994
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000995
996// Comparison.
997
998function TestComparison(eq) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000999 TestWithProxies(TestComparison2, eq)
1000}
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001001
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001002function TestComparison2(create, eq) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001003 var p1 = create({})
1004 var p2 = create({})
1005
1006 assertTrue(eq(p1, p1))
1007 assertTrue(eq(p2, p2))
1008 assertTrue(!eq(p1, p2))
1009 assertTrue(!eq(p1, {}))
1010 assertTrue(!eq({}, p2))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001011 assertTrue(!eq({}, {}))
1012}
1013
1014TestComparison(function(o1, o2) { return o1 == o2 })
1015TestComparison(function(o1, o2) { return o1 === o2 })
1016TestComparison(function(o1, o2) { return !(o1 != o2) })
1017TestComparison(function(o1, o2) { return !(o1 !== o2) })
1018
1019
1020
Ben Murdoch589d6972011-11-30 16:04:58 +00001021// Type (typeof).
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001022
Ben Murdoch589d6972011-11-30 16:04:58 +00001023function TestTypeof() {
1024 assertEquals("object", typeof Proxy.create({}))
1025 assertTrue(typeof Proxy.create({}) == "object")
1026 assertTrue("object" == typeof Proxy.create({}))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001027
Ben Murdoch589d6972011-11-30 16:04:58 +00001028 assertEquals("function", typeof Proxy.createFunction({}, function() {}))
1029 assertTrue(typeof Proxy.createFunction({}, function() {}) == "function")
1030 assertTrue("function" == typeof Proxy.createFunction({}, function() {}))
1031}
1032
1033TestTypeof()
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001034
1035
1036
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001037// Membership test (in).
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001038
1039var key
Ben Murdoch589d6972011-11-30 16:04:58 +00001040
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001041function TestIn(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001042 TestWithProxies(TestIn2, handler)
1043}
1044
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001045function TestIn2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001046 var p = create(handler)
1047 assertTrue("a" in p)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001048 assertEquals("a", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00001049 assertTrue(99 in p)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001050 assertEquals("99", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00001051 assertFalse("z" in p)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001052 assertEquals("z", key)
1053
Ben Murdoch589d6972011-11-30 16:04:58 +00001054 assertEquals(2, ("a" in p) ? 2 : 0)
1055 assertEquals(0, !("a" in p) ? 2 : 0)
1056 assertEquals(0, ("zzz" in p) ? 2 : 0)
1057 assertEquals(2, !("zzz" in p) ? 2 : 0)
1058
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001059 // Test compilation in conditionals.
Ben Murdoch589d6972011-11-30 16:04:58 +00001060 if ("b" in p) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001061 } else {
1062 assertTrue(false)
1063 }
1064 assertEquals("b", key)
1065
Ben Murdoch589d6972011-11-30 16:04:58 +00001066 if ("zz" in p) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001067 assertTrue(false)
1068 }
1069 assertEquals("zz", key)
1070
Ben Murdoch589d6972011-11-30 16:04:58 +00001071 if (!("c" in p)) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001072 assertTrue(false)
1073 }
1074 assertEquals("c", key)
1075
Ben Murdoch589d6972011-11-30 16:04:58 +00001076 if (!("zzz" in p)) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001077 } else {
1078 assertTrue(false)
1079 }
1080 assertEquals("zzz", key)
1081}
1082
1083TestIn({
1084 has: function(k) { key = k; return k < "z" }
1085})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001086
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001087TestIn({
1088 has: function(k) { return this.has2(k) },
1089 has2: function(k) { key = k; return k < "z" }
1090})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001091
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001092TestIn({
1093 getPropertyDescriptor: function(k) {
1094 key = k; return k < "z" ? {value: 42} : void 0
1095 }
1096})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001097
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001098TestIn({
1099 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
1100 getPropertyDescriptor2: function(k) {
1101 key = k; return k < "z" ? {value: 42} : void 0
1102 }
1103})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001104
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001105TestIn({
1106 getPropertyDescriptor: function(k) {
1107 key = k; return k < "z" ? {get value() { return 42 }} : void 0
1108 }
1109})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001110
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001111TestIn({
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001112 has: undefined,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001113 getPropertyDescriptor: function(k) {
1114 key = k; return k < "z" ? {value: 42} : void 0
1115 }
1116})
1117
1118TestIn(Proxy.create({
1119 get: function(pr, pk) {
1120 return function(k) { key = k; return k < "z" }
1121 }
1122}))
1123
1124
Ben Murdoch589d6972011-11-30 16:04:58 +00001125function TestInThrow(handler) {
1126 TestWithProxies(TestInThrow2, handler)
1127}
1128
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001129function TestInThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001130 var p = create(handler)
1131 assertThrows(function(){ return "a" in o }, "myexn")
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001132 assertThrows(function(){ return 99 in o }, "myexn")
Ben Murdoch589d6972011-11-30 16:04:58 +00001133 assertThrows(function(){ return !("a" in o) }, "myexn")
1134 assertThrows(function(){ return ("a" in o) ? 2 : 3 }, "myexn")
1135 assertThrows(function(){ if ("b" in o) {} }, "myexn")
1136 assertThrows(function(){ if (!("b" in o)) {} }, "myexn")
1137 assertThrows(function(){ if ("zzz" in o) {} }, "myexn")
1138}
1139
1140TestInThrow({
1141 has: function(k) { throw "myexn" }
1142})
1143
1144TestInThrow({
1145 has: function(k) { return this.has2(k) },
1146 has2: function(k) { throw "myexn" }
1147})
1148
1149TestInThrow({
1150 getPropertyDescriptor: function(k) { throw "myexn" }
1151})
1152
1153TestInThrow({
1154 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
1155 getPropertyDescriptor2: function(k) { throw "myexn" }
1156})
1157
1158TestInThrow({
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001159 has: undefined,
Ben Murdoch589d6972011-11-30 16:04:58 +00001160 getPropertyDescriptor: function(k) { throw "myexn" }
1161})
1162
1163TestInThrow(Proxy.create({
1164 get: function(pr, pk) { throw "myexn" }
1165}))
1166
1167TestInThrow(Proxy.create({
1168 get: function(pr, pk) {
1169 return function(k) { throw "myexn" }
1170 }
1171}))
1172
1173
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001174function TestInForDerived(handler) {
1175 TestWithProxies(TestInForDerived2, handler)
1176}
1177
1178function TestInForDerived2(create, handler) {
1179 var p = create(handler)
1180 var o = Object.create(p)
1181
1182 assertTrue("a" in o)
1183 assertEquals("a", key)
1184 assertTrue(99 in o)
1185 assertEquals("99", key)
1186 assertFalse("z" in o)
1187 assertEquals("z", key)
1188
1189 assertEquals(2, ("a" in o) ? 2 : 0)
1190 assertEquals(0, !("a" in o) ? 2 : 0)
1191 assertEquals(0, ("zzz" in o) ? 2 : 0)
1192 assertEquals(2, !("zzz" in o) ? 2 : 0)
1193
1194 if ("b" in o) {
1195 } else {
1196 assertTrue(false)
1197 }
1198 assertEquals("b", key)
1199
1200 if ("zz" in o) {
1201 assertTrue(false)
1202 }
1203 assertEquals("zz", key)
1204
1205 if (!("c" in o)) {
1206 assertTrue(false)
1207 }
1208 assertEquals("c", key)
1209
1210 if (!("zzz" in o)) {
1211 } else {
1212 assertTrue(false)
1213 }
1214 assertEquals("zzz", key)
1215}
1216
1217TestInForDerived({
1218 getPropertyDescriptor: function(k) {
1219 key = k; return k < "z" ? {value: 42, configurable: true} : void 0
1220 }
1221})
1222
1223TestInForDerived({
1224 getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
1225 getPropertyDescriptor2: function(k) {
1226 key = k; return k < "z" ? {value: 42, configurable: true} : void 0
1227 }
1228})
1229
1230TestInForDerived({
1231 getPropertyDescriptor: function(k) {
1232 key = k;
1233 return k < "z" ? {get value() { return 42 }, configurable: true} : void 0
1234 }
1235})
1236
1237/* TODO(rossberg): this will work once we implement the newest proposal
1238 * regarding default traps for getPropertyDescriptor.
1239TestInForDerived({
1240 getOwnPropertyDescriptor: function(k) {
1241 key = k; return k < "z" ? {value: 42, configurable: true} : void 0
1242 }
1243})
1244
1245TestInForDerived({
1246 getOwnPropertyDescriptor: function(k) {
1247 return this.getOwnPropertyDescriptor2(k)
1248 },
1249 getOwnPropertyDescriptor2: function(k) {
1250 key = k; return k < "z" ? {value: 42, configurable: true} : void 0
1251 }
1252})
1253
1254TestInForDerived({
1255 getOwnPropertyDescriptor: function(k) {
1256 key = k;
1257 return k < "z" ? {get value() { return 42 }, configurable: true} : void 0
1258 }
1259})
1260*/
1261
1262TestInForDerived(Proxy.create({
1263 get: function(pr, pk) {
1264 return function(k) {
1265 key = k; return k < "z" ? {value: 42, configurable: true} : void 0
1266 }
1267 }
1268}))
1269
1270
1271
1272// Property descriptor conversion.
1273
1274var descget
1275
1276function TestDescriptorGetOrder(handler) {
1277 var p = Proxy.create(handler)
1278 var o = Object.create(p, {b: {value: 0}})
1279 TestDescriptorGetOrder2(function(n) { return p[n] }, "vV")
1280 TestDescriptorGetOrder2(function(n) { return n in p }, "")
1281 TestDescriptorGetOrder2(function(n) { return o[n] }, "vV")
1282 TestDescriptorGetOrder2(function(n) { return n in o }, "eEcCvVwWgs")
1283}
1284
1285function TestDescriptorGetOrder2(f, access) {
1286 descget = ""
1287 assertTrue(f("a"))
1288 assertEquals(access, descget)
1289 descget = ""
1290 assertTrue(f(99))
1291 assertEquals(access, descget)
1292 descget = ""
1293 assertFalse(!!f("z"))
1294 assertEquals("", descget)
1295}
1296
1297TestDescriptorGetOrder({
1298 getPropertyDescriptor: function(k) {
1299 if (k >= "z") return void 0
1300 // Return a proxy as property descriptor, so that we can log accesses.
1301 return Proxy.create({
1302 get: function(r, attr) {
1303 descget += attr[0].toUpperCase()
1304 return true
1305 },
1306 has: function(attr) {
1307 descget += attr[0]
1308 switch (attr) {
1309 case "writable":
1310 case "enumerable":
1311 case "configurable":
1312 case "value":
1313 return true
1314 case "get":
1315 case "set":
1316 return false
1317 default:
1318 assertUnreachable()
1319 }
1320 }
1321 })
1322 }
1323})
1324
1325
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001326
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001327// Own Properties (Object.prototype.hasOwnProperty).
1328
1329var key
Ben Murdoch589d6972011-11-30 16:04:58 +00001330
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001331function TestHasOwn(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001332 TestWithProxies(TestHasOwn2, handler)
1333}
1334
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001335function TestHasOwn2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001336 var p = create(handler)
1337 assertTrue(Object.prototype.hasOwnProperty.call(p, "a"))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001338 assertEquals("a", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00001339 assertTrue(Object.prototype.hasOwnProperty.call(p, 99))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001340 assertEquals("99", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00001341 assertFalse(Object.prototype.hasOwnProperty.call(p, "z"))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001342 assertEquals("z", key)
1343}
1344
1345TestHasOwn({
1346 hasOwn: function(k) { key = k; return k < "z" }
1347})
1348
1349TestHasOwn({
1350 hasOwn: function(k) { return this.hasOwn2(k) },
1351 hasOwn2: function(k) { key = k; return k < "z" }
1352})
1353
1354TestHasOwn({
1355 getOwnPropertyDescriptor: function(k) {
1356 key = k; return k < "z" ? {value: 42} : void 0
1357 }
1358})
1359
1360TestHasOwn({
1361 getOwnPropertyDescriptor: function(k) {
1362 return this.getOwnPropertyDescriptor2(k)
1363 },
1364 getOwnPropertyDescriptor2: function(k) {
1365 key = k; return k < "z" ? {value: 42} : void 0
1366 }
1367})
1368
1369TestHasOwn({
1370 getOwnPropertyDescriptor: function(k) {
1371 key = k; return k < "z" ? {get value() { return 42 }} : void 0
1372 }
1373})
1374
1375TestHasOwn({
1376 hasOwn: undefined,
1377 getOwnPropertyDescriptor: function(k) {
1378 key = k; return k < "z" ? {value: 42} : void 0
1379 }
1380})
1381
1382TestHasOwn(Proxy.create({
1383 get: function(pr, pk) {
1384 return function(k) { key = k; return k < "z" }
1385 }
1386}))
1387
1388
Ben Murdoch589d6972011-11-30 16:04:58 +00001389function TestHasOwnThrow(handler) {
1390 TestWithProxies(TestHasOwnThrow2, handler)
1391}
1392
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001393function TestHasOwnThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001394 var p = create(handler)
1395 assertThrows(function(){ Object.prototype.hasOwnProperty.call(p, "a")},
1396 "myexn")
1397 assertThrows(function(){ Object.prototype.hasOwnProperty.call(p, 99)},
1398 "myexn")
1399}
1400
1401TestHasOwnThrow({
1402 hasOwn: function(k) { throw "myexn" }
1403})
1404
1405TestHasOwnThrow({
1406 hasOwn: function(k) { return this.hasOwn2(k) },
1407 hasOwn2: function(k) { throw "myexn" }
1408})
1409
1410TestHasOwnThrow({
1411 getOwnPropertyDescriptor: function(k) { throw "myexn" }
1412})
1413
1414TestHasOwnThrow({
1415 getOwnPropertyDescriptor: function(k) {
1416 return this.getOwnPropertyDescriptor2(k)
1417 },
1418 getOwnPropertyDescriptor2: function(k) { throw "myexn" }
1419})
1420
1421TestHasOwnThrow({
1422 hasOwn: undefined,
1423 getOwnPropertyDescriptor: function(k) { throw "myexn" }
1424})
1425
1426TestHasOwnThrow(Proxy.create({
1427 get: function(pr, pk) { throw "myexn" }
1428}))
1429
1430TestHasOwnThrow(Proxy.create({
1431 get: function(pr, pk) {
1432 return function(k) { throw "myexn" }
1433 }
1434}))
1435
1436
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001437
1438// Instanceof (instanceof)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001439
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001440function TestProxyInstanceof() {
1441 var o1 = {}
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001442 var p1 = Proxy.create({})
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001443 var p2 = Proxy.create({}, o1)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001444 var p3 = Proxy.create({}, p2)
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001445 var o2 = Object.create(p2)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001446
Ben Murdoch589d6972011-11-30 16:04:58 +00001447 var f0 = function() {}
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001448 f0.prototype = o1
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001449 var f1 = function() {}
1450 f1.prototype = p1
1451 var f2 = function() {}
1452 f2.prototype = p2
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001453 var f3 = function() {}
1454 f3.prototype = o2
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001455
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001456 assertTrue(o1 instanceof Object)
1457 assertFalse(o1 instanceof f0)
1458 assertFalse(o1 instanceof f1)
1459 assertFalse(o1 instanceof f2)
1460 assertFalse(o1 instanceof f3)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001461 assertFalse(p1 instanceof Object)
Ben Murdoch589d6972011-11-30 16:04:58 +00001462 assertFalse(p1 instanceof f0)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001463 assertFalse(p1 instanceof f1)
1464 assertFalse(p1 instanceof f2)
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001465 assertFalse(p1 instanceof f3)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001466 assertTrue(p2 instanceof Object)
Ben Murdoch589d6972011-11-30 16:04:58 +00001467 assertTrue(p2 instanceof f0)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001468 assertFalse(p2 instanceof f1)
1469 assertFalse(p2 instanceof f2)
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001470 assertFalse(p2 instanceof f3)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001471 assertTrue(p3 instanceof Object)
Ben Murdoch589d6972011-11-30 16:04:58 +00001472 assertTrue(p3 instanceof f0)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001473 assertFalse(p3 instanceof f1)
1474 assertTrue(p3 instanceof f2)
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001475 assertFalse(p3 instanceof f3)
1476 assertTrue(o2 instanceof Object)
1477 assertTrue(o2 instanceof f0)
1478 assertFalse(o2 instanceof f1)
1479 assertTrue(o2 instanceof f2)
1480 assertFalse(o2 instanceof f3)
Ben Murdoch589d6972011-11-30 16:04:58 +00001481
1482 var f = Proxy.createFunction({}, function() {})
1483 assertTrue(f instanceof Function)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001484}
1485
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001486TestProxyInstanceof()
1487
1488
1489function TestInstanceofProxy() {
1490 var o0 = Object.create(null)
1491 var o1 = {}
1492 var o2 = Object.create(o0)
1493 var o3 = Object.create(o1)
1494 var o4 = Object.create(o2)
1495 var o5 = Object.create(o3)
1496
1497 function handler(o) { return {get: function() { return o } } }
1498 var f0 = Proxy.createFunction(handler(o0), function() {})
1499 var f1 = Proxy.createFunction(handler(o1), function() {})
1500 var f2 = Proxy.createFunction(handler(o2), function() {})
1501 var f3 = Proxy.createFunction(handler(o3), function() {})
1502 var f4 = Proxy.createFunction(handler(o4), function() {})
1503 var f5 = Proxy.createFunction(handler(o4), function() {})
1504
1505 assertFalse(null instanceof f0)
1506 assertFalse(o0 instanceof f0)
1507 assertFalse(o0 instanceof f1)
1508 assertFalse(o0 instanceof f2)
1509 assertFalse(o0 instanceof f3)
1510 assertFalse(o0 instanceof f4)
1511 assertFalse(o0 instanceof f5)
1512 assertFalse(o1 instanceof f0)
1513 assertFalse(o1 instanceof f1)
1514 assertFalse(o1 instanceof f2)
1515 assertFalse(o1 instanceof f3)
1516 assertFalse(o1 instanceof f4)
1517 assertFalse(o1 instanceof f5)
1518 assertTrue(o2 instanceof f0)
1519 assertFalse(o2 instanceof f1)
1520 assertFalse(o2 instanceof f2)
1521 assertFalse(o2 instanceof f3)
1522 assertFalse(o2 instanceof f4)
1523 assertFalse(o2 instanceof f5)
1524 assertFalse(o3 instanceof f0)
1525 assertTrue(o3 instanceof f1)
1526 assertFalse(o3 instanceof f2)
1527 assertFalse(o3 instanceof f3)
1528 assertFalse(o3 instanceof f4)
1529 assertFalse(o3 instanceof f5)
1530 assertTrue(o4 instanceof f0)
1531 assertFalse(o4 instanceof f1)
1532 assertTrue(o4 instanceof f2)
1533 assertFalse(o4 instanceof f3)
1534 assertFalse(o4 instanceof f4)
1535 assertFalse(o4 instanceof f5)
1536 assertFalse(o5 instanceof f0)
1537 assertTrue(o5 instanceof f1)
1538 assertFalse(o5 instanceof f2)
1539 assertTrue(o5 instanceof f3)
1540 assertFalse(o5 instanceof f4)
1541 assertFalse(o5 instanceof f5)
1542
1543 var f = Proxy.createFunction({}, function() {})
1544 var ff = Proxy.createFunction(handler(Function), function() {})
1545 assertTrue(f instanceof Function)
1546 assertFalse(f instanceof ff)
1547}
1548
1549TestInstanceofProxy()
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001550
1551
1552
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001553// Prototype (Object.getPrototypeOf, Object.prototype.isPrototypeOf).
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001554
1555function TestPrototype() {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001556 var o1 = {}
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001557 var p1 = Proxy.create({})
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001558 var p2 = Proxy.create({}, o1)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001559 var p3 = Proxy.create({}, p2)
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001560 var p4 = Proxy.create({}, null)
1561 var o2 = Object.create(p3)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001562
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001563 assertSame(Object.getPrototypeOf(o1), Object.prototype)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001564 assertSame(Object.getPrototypeOf(p1), null)
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001565 assertSame(Object.getPrototypeOf(p2), o1)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001566 assertSame(Object.getPrototypeOf(p3), p2)
1567 assertSame(Object.getPrototypeOf(p4), null)
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001568 assertSame(Object.getPrototypeOf(o2), p3)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001569
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001570 assertTrue(Object.prototype.isPrototypeOf(o1))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001571 assertFalse(Object.prototype.isPrototypeOf(p1))
1572 assertTrue(Object.prototype.isPrototypeOf(p2))
1573 assertTrue(Object.prototype.isPrototypeOf(p3))
1574 assertFalse(Object.prototype.isPrototypeOf(p4))
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001575 assertTrue(Object.prototype.isPrototypeOf(o2))
1576 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o1))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001577 assertFalse(Object.prototype.isPrototypeOf.call(Object.prototype, p1))
1578 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p2))
1579 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p3))
1580 assertFalse(Object.prototype.isPrototypeOf.call(Object.prototype, p4))
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001581 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o2))
1582 assertFalse(Object.prototype.isPrototypeOf.call(o1, o1))
1583 assertFalse(Object.prototype.isPrototypeOf.call(o1, p1))
1584 assertTrue(Object.prototype.isPrototypeOf.call(o1, p2))
1585 assertTrue(Object.prototype.isPrototypeOf.call(o1, p3))
1586 assertFalse(Object.prototype.isPrototypeOf.call(o1, p4))
1587 assertTrue(Object.prototype.isPrototypeOf.call(o1, o2))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001588 assertFalse(Object.prototype.isPrototypeOf.call(p1, p1))
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001589 assertFalse(Object.prototype.isPrototypeOf.call(p1, o1))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001590 assertFalse(Object.prototype.isPrototypeOf.call(p1, p2))
1591 assertFalse(Object.prototype.isPrototypeOf.call(p1, p3))
1592 assertFalse(Object.prototype.isPrototypeOf.call(p1, p4))
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001593 assertFalse(Object.prototype.isPrototypeOf.call(p1, o2))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001594 assertFalse(Object.prototype.isPrototypeOf.call(p2, p1))
1595 assertFalse(Object.prototype.isPrototypeOf.call(p2, p2))
1596 assertTrue(Object.prototype.isPrototypeOf.call(p2, p3))
1597 assertFalse(Object.prototype.isPrototypeOf.call(p2, p4))
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001598 assertTrue(Object.prototype.isPrototypeOf.call(p2, o2))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001599 assertFalse(Object.prototype.isPrototypeOf.call(p3, p2))
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001600 assertTrue(Object.prototype.isPrototypeOf.call(p3, o2))
1601 assertFalse(Object.prototype.isPrototypeOf.call(o2, o1))
1602 assertFalse(Object.prototype.isPrototypeOf.call(o2, p1))
1603 assertFalse(Object.prototype.isPrototypeOf.call(o2, p2))
1604 assertFalse(Object.prototype.isPrototypeOf.call(o2, p3))
1605 assertFalse(Object.prototype.isPrototypeOf.call(o2, p4))
1606 assertFalse(Object.prototype.isPrototypeOf.call(o2, o2))
Ben Murdoch589d6972011-11-30 16:04:58 +00001607
1608 var f = Proxy.createFunction({}, function() {})
1609 assertSame(Object.getPrototypeOf(f), Function.prototype)
1610 assertTrue(Object.prototype.isPrototypeOf(f))
1611 assertTrue(Object.prototype.isPrototypeOf.call(Function.prototype, f))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001612}
1613
1614TestPrototype()
1615
1616
1617
1618// Property names (Object.getOwnPropertyNames, Object.keys).
1619
1620function TestPropertyNames(names, handler) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001621 TestWithProxies(TestPropertyNames2, handler, names)
Ben Murdoch589d6972011-11-30 16:04:58 +00001622}
1623
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001624function TestPropertyNames2(create, handler, names) {
1625 var p = create(handler)
1626 assertArrayEquals(names, Object.getOwnPropertyNames(p))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001627}
1628
1629TestPropertyNames([], {
1630 getOwnPropertyNames: function() { return [] }
1631})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001632
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001633TestPropertyNames(["a", "zz", " ", "0"], {
1634 getOwnPropertyNames: function() { return ["a", "zz", " ", 0] }
1635})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001636
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001637TestPropertyNames(["throw", "function "], {
1638 getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
1639 getOwnPropertyNames2: function() { return ["throw", "function "] }
1640})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001641
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001642TestPropertyNames(["[object Object]"], {
1643 get getOwnPropertyNames() {
1644 return function() { return [{}] }
1645 }
1646})
1647
1648
Ben Murdoch589d6972011-11-30 16:04:58 +00001649function TestPropertyNamesThrow(handler) {
1650 TestWithProxies(TestPropertyNamesThrow2, handler)
1651}
1652
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001653function TestPropertyNamesThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001654 var p = create(handler)
1655 assertThrows(function(){ Object.getOwnPropertyNames(p) }, "myexn")
1656}
1657
1658TestPropertyNamesThrow({
1659 getOwnPropertyNames: function() { throw "myexn" }
1660})
1661
1662TestPropertyNamesThrow({
1663 getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
1664 getOwnPropertyNames2: function() { throw "myexn" }
1665})
1666
1667
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001668function TestKeys(names, handler) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001669 TestWithProxies(TestKeys2, handler, names)
Ben Murdoch589d6972011-11-30 16:04:58 +00001670}
1671
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001672function TestKeys2(create, handler, names) {
1673 var p = create(handler)
1674 assertArrayEquals(names, Object.keys(p))
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001675}
1676
1677TestKeys([], {
1678 keys: function() { return [] }
1679})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001680
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001681TestKeys(["a", "zz", " ", "0"], {
1682 keys: function() { return ["a", "zz", " ", 0] }
1683})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001684
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001685TestKeys(["throw", "function "], {
1686 keys: function() { return this.keys2() },
1687 keys2: function() { return ["throw", "function "] }
1688})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001689
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001690TestKeys(["[object Object]"], {
1691 get keys() {
1692 return function() { return [{}] }
1693 }
1694})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001695
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001696TestKeys(["a", "0"], {
1697 getOwnPropertyNames: function() { return ["a", 23, "zz", "", 0] },
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001698 getOwnPropertyDescriptor: function(k) {
1699 return k == "" ? undefined : {enumerable: k.length == 1}
1700 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001701})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001702
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001703TestKeys(["23", "zz", ""], {
1704 getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
1705 getOwnPropertyNames2: function() { return ["a", 23, "zz", "", 0] },
1706 getOwnPropertyDescriptor: function(k) {
1707 return this.getOwnPropertyDescriptor2(k)
1708 },
1709 getOwnPropertyDescriptor2: function(k) { return {enumerable: k.length != 1} }
1710})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001711
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001712TestKeys(["a", "b", "c", "5"], {
1713 get getOwnPropertyNames() {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001714 return function() { return ["0", 4, "a", "b", "c", 5, "ety"] }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001715 },
1716 get getOwnPropertyDescriptor() {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001717 return function(k) {
1718 return k == "ety" ? undefined : {enumerable: k >= "44"}
1719 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001720 }
1721})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001722
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001723TestKeys([], {
1724 get getOwnPropertyNames() {
1725 return function() { return ["a", "b", "c"] }
1726 },
1727 getOwnPropertyDescriptor: function(k) { return {} }
1728})
1729
1730
Ben Murdoch589d6972011-11-30 16:04:58 +00001731function TestKeysThrow(handler) {
1732 TestWithProxies(TestKeysThrow2, handler)
1733}
1734
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001735function TestKeysThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001736 var p = create(handler)
1737 assertThrows(function(){ Object.keys(p) }, "myexn")
1738}
1739
1740TestKeysThrow({
1741 keys: function() { throw "myexn" }
1742})
1743
1744TestKeysThrow({
1745 keys: function() { return this.keys2() },
1746 keys2: function() { throw "myexn" }
1747})
1748
1749TestKeysThrow({
1750 getOwnPropertyNames: function() { throw "myexn" },
1751 getOwnPropertyDescriptor: function(k) { return true }
1752})
1753
1754TestKeysThrow({
1755 getOwnPropertyNames: function() { return [1, 2] },
1756 getOwnPropertyDescriptor: function(k) { throw "myexn" }
1757})
1758
1759TestKeysThrow({
1760 getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
1761 getOwnPropertyNames2: function() { throw "myexn" },
1762})
1763
1764TestKeysThrow({
1765 getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
1766 getOwnPropertyNames2: function() { return [1, 2] },
1767 getOwnPropertyDescriptor: function(k) {
1768 return this.getOwnPropertyDescriptor2(k)
1769 },
1770 getOwnPropertyDescriptor2: function(k) { throw "myexn" }
1771})
1772
1773TestKeysThrow({
1774 get getOwnPropertyNames() { throw "myexn" }
1775})
1776
1777TestKeysThrow({
1778 get getOwnPropertyNames() {
1779 return function() { throw "myexn" }
1780 },
1781})
1782
1783TestKeysThrow([], {
1784 get getOwnPropertyNames() {
1785 return function() { return [1, 2] }
1786 },
1787 getOwnPropertyDescriptor: function(k) { throw "myexn" }
1788})
1789
1790
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001791
1792// Fixing (Object.freeze, Object.seal, Object.preventExtensions,
1793// Object.isFrozen, Object.isSealed, Object.isExtensible)
1794
1795function TestFix(names, handler) {
1796 var proto = {p: 77}
1797 var assertFixing = function(o, s, f, e) {
1798 assertEquals(s, Object.isSealed(o))
1799 assertEquals(f, Object.isFrozen(o))
1800 assertEquals(e, Object.isExtensible(o))
1801 }
1802
Ben Murdoch589d6972011-11-30 16:04:58 +00001803 var p1 = Proxy.create(handler, proto)
1804 assertFixing(p1, false, false, true)
1805 Object.seal(p1)
1806 assertFixing(p1, true, names.length === 0, false)
1807 assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p1).sort())
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001808 assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(),
Ben Murdoch589d6972011-11-30 16:04:58 +00001809 Object.keys(p1).sort())
1810 assertEquals(proto, Object.getPrototypeOf(p1))
1811 assertEquals(77, p1.p)
1812 for (var n in p1) {
1813 var desc = Object.getOwnPropertyDescriptor(p1, n)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001814 if (desc !== undefined) assertFalse(desc.configurable)
1815 }
1816
Ben Murdoch589d6972011-11-30 16:04:58 +00001817 var p2 = Proxy.create(handler, proto)
1818 assertFixing(p2, false, false, true)
1819 Object.freeze(p2)
1820 assertFixing(p2, true, true, false)
1821 assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p2).sort())
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001822 assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(),
Ben Murdoch589d6972011-11-30 16:04:58 +00001823 Object.keys(p2).sort())
1824 assertEquals(proto, Object.getPrototypeOf(p2))
1825 assertEquals(77, p2.p)
1826 for (var n in p2) {
1827 var desc = Object.getOwnPropertyDescriptor(p2, n)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001828 if (desc !== undefined) assertFalse(desc.writable)
1829 if (desc !== undefined) assertFalse(desc.configurable)
1830 }
1831
Ben Murdoch589d6972011-11-30 16:04:58 +00001832 var p3 = Proxy.create(handler, proto)
1833 assertFixing(p3, false, false, true)
1834 Object.preventExtensions(p3)
1835 assertFixing(p3, names.length === 0, names.length === 0, false)
1836 assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p3).sort())
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001837 assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(),
Ben Murdoch589d6972011-11-30 16:04:58 +00001838 Object.keys(p3).sort())
1839 assertEquals(proto, Object.getPrototypeOf(p3))
1840 assertEquals(77, p3.p)
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001841
1842 var p = Proxy.create(handler, proto)
1843 var o = Object.create(p)
1844 assertFixing(p, false, false, true)
1845 assertFixing(o, false, false, true)
1846 Object.freeze(o)
1847 assertFixing(p, false, false, true)
1848 assertFixing(o, true, true, false)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001849}
1850
1851TestFix([], {
1852 fix: function() { return {} }
1853})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001854
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001855TestFix(["a", "b", "c", "3", "zz"], {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001856 fix: function() {
1857 return {
1858 a: {value: "a", writable: true, configurable: false, enumerable: true},
1859 b: {value: 33, writable: false, configurable: false, enumerable: true},
1860 c: {value: 0, writable: true, configurable: true, enumerable: true},
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001861 '3': {value: true, writable: false, configurable: true, enumerable: true},
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001862 zz: {value: 0, enumerable: false}
1863 }
1864 }
1865})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001866
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001867TestFix(["a"], {
1868 fix: function() { return this.fix2() },
1869 fix2: function() {
1870 return {a: {value: 4, writable: true, configurable: true, enumerable: true}}
1871 }
1872})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001873
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001874TestFix(["b"], {
1875 get fix() {
1876 return function() {
1877 return {b: {configurable: true, writable: true, enumerable: true}}
1878 }
1879 }
1880})
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001881
1882
Ben Murdoch589d6972011-11-30 16:04:58 +00001883function TestFixFunction(fix) {
1884 var f1 = Proxy.createFunction({
1885 fix: function() { return {} }
1886 }, function() {})
1887 fix(f1)
1888 assertEquals(0, f1.length)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001889
Ben Murdoch589d6972011-11-30 16:04:58 +00001890 var f2 = Proxy.createFunction({
1891 fix: function() { return {length: {value: 3}} }
1892 }, function() {})
1893 fix(f2)
1894 assertEquals(3, f2.length)
1895
1896 var f3 = Proxy.createFunction({
1897 fix: function() { return {length: {value: "huh"}} }
1898 }, function() {})
1899 fix(f3)
1900 assertEquals(0, f1.length)
1901}
1902
1903TestFixFunction(Object.seal)
1904TestFixFunction(Object.freeze)
1905TestFixFunction(Object.preventExtensions)
1906
1907
1908function TestFixThrow(handler) {
1909 TestWithProxies(TestFixThrow2, handler)
1910}
1911
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001912function TestFixThrow2(create, handler) {
1913 var p = create(handler, {})
Ben Murdoch589d6972011-11-30 16:04:58 +00001914 assertThrows(function(){ Object.seal(p) }, "myexn")
1915 assertThrows(function(){ Object.freeze(p) }, "myexn")
1916 assertThrows(function(){ Object.preventExtensions(p) }, "myexn")
1917}
1918
1919TestFixThrow({
1920 fix: function() { throw "myexn" }
1921})
1922
1923TestFixThrow({
1924 fix: function() { return this.fix2() },
1925 fix2: function() { throw "myexn" }
1926})
1927
1928TestFixThrow({
1929 get fix() { throw "myexn" }
1930})
1931
1932TestFixThrow({
1933 get fix() {
1934 return function() { throw "myexn" }
1935 }
1936})
1937
1938
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001939// Freeze a proxy in the middle of operations on it.
1940// TODO(rossberg): actual behaviour not specified consistently at the moment,
1941// just make sure that we do not crash.
1942function TestReentrantFix(f) {
1943 TestWithProxies(f, Object.freeze)
1944 TestWithProxies(f, Object.seal)
1945 TestWithProxies(f, Object.preventExtensions)
1946}
1947
1948TestReentrantFix(function(create, freeze) {
1949 var handler = {
1950 get get() { freeze(p); return undefined },
1951 fix: function() { return {} }
1952 }
1953 var p = create(handler)
1954 // Freeze while getting get trap.
1955 try { p.x } catch (e) { assertInstanceof(e, Error) }
1956})
1957
1958TestReentrantFix(function(create, freeze) {
1959 var handler = {
1960 get: function() { freeze(p); return 3 },
1961 fix: function() { return {} }
1962 }
1963 var p = create(handler)
1964 // Freeze while executing get trap.
1965 try { p.x } catch (e) { assertInstanceof(e, Error) }
1966})
1967
1968TestReentrantFix(function(create, freeze) {
1969 var handler = {
1970 getPropertyDescriptor: function() { freeze(p); return undefined },
1971 fix: function() { return {} }
1972 }
1973 var p = create(handler)
1974 // Freeze while executing default get trap.
1975 try { p.x } catch (e) { assertInstanceof(e, Error) }
1976})
1977
1978TestReentrantFix(function(create, freeze) {
1979 var handler = {
1980 getPropertyDescriptor: function() { freeze(p); return {get: function(){}} },
1981 fix: function() { return {} }
1982 }
1983 var p = create(handler)
1984 var o = Object.create(p)
1985 // Freeze while getting a property from prototype.
1986 try { o.x } catch (e) { assertInstanceof(e, Error) }
1987})
1988
1989TestReentrantFix(function(create, freeze) {
1990 var handler = {
1991 get set() { freeze(p); return undefined },
1992 fix: function() { return {} }
1993 }
1994 var p = create(handler)
1995 // Freeze while getting set trap.
1996 try { p.x = 4 } catch (e) { assertInstanceof(e, Error) }
1997})
1998
1999TestReentrantFix(function(create, freeze) {
2000 var handler = {
2001 set: function() { freeze(p); return true },
2002 fix: function() { return {} }
2003 }
2004 var p = create(handler)
2005 // Freeze while executing set trap.
2006 try { p.x = 4 } catch (e) { assertInstanceof(e, Error) }
2007})
2008
2009TestReentrantFix(function(create, freeze) {
2010 var handler = {
2011 getOwnPropertyDescriptor: function() { freeze(p); return undefined },
2012 fix: function() { return {} }
2013 }
2014 var p = create(handler)
2015 // Freeze while executing default set trap.
2016 try { p.x } catch (e) { assertInstanceof(e, Error) }
2017})
2018
2019TestReentrantFix(function(create, freeze) {
2020 var handler = {
2021 getPropertyDescriptor: function() { freeze(p); return {set: function(){}} },
2022 fix: function() { return {} }
2023 }
2024 var p = create(handler)
2025 var o = Object.create(p)
2026 // Freeze while setting a property in prototype, dropping the property!
2027 try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
2028})
2029
2030TestReentrantFix(function(create, freeze) {
2031 var handler = {
2032 getPropertyDescriptor: function() { freeze(p); return {set: function(){}} },
2033 fix: function() { return {x: {get: function(){}}} }
2034 }
2035 var p = create(handler)
2036 var o = Object.create(p)
2037 // Freeze while setting a property in prototype, making it read-only!
2038 try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
2039})
2040
2041TestReentrantFix(function(create, freeze) {
2042 var handler = {
2043 get fix() { freeze(p); return function(){} }
2044 }
2045 var p = create(handler)
2046 // Freeze while getting fix trap.
2047 try { Object.freeze(p) } catch (e) { assertInstanceof(e, Error) }
2048 p = create(handler)
2049 try { Object.seal(p) } catch (e) { assertInstanceof(e, Error) }
2050 p = create(handler)
2051 try { Object.preventExtensions(p) } catch (e) { assertInstanceof(e, Error) }
2052})
2053
2054TestReentrantFix(function(create, freeze) {
2055 var handler = {
2056 fix: function() { freeze(p); return {} }
2057 }
2058 var p = create(handler)
2059 // Freeze while executing fix trap.
2060 try { Object.freeze(p) } catch (e) { assertInstanceof(e, Error) }
2061 p = create(handler)
2062 try { Object.seal(p) } catch (e) { assertInstanceof(e, Error) }
2063 p = create(handler)
2064 try { Object.preventExtensions(p) } catch (e) { assertInstanceof(e, Error) }
2065})
2066
2067
Ben Murdoch589d6972011-11-30 16:04:58 +00002068
2069// String conversion (Object.prototype.toString,
2070// Object.prototype.toLocaleString,
2071// Function.prototype.toString)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002072
2073var key
Ben Murdoch589d6972011-11-30 16:04:58 +00002074
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002075function TestToString(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00002076 var p = Proxy.create(handler)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002077 key = ""
Ben Murdoch589d6972011-11-30 16:04:58 +00002078 assertEquals("[object Object]", Object.prototype.toString.call(p))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002079 assertEquals("", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00002080 assertEquals("my_proxy", Object.prototype.toLocaleString.call(p))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002081 assertEquals("toString", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00002082
2083 var f = Proxy.createFunction(handler, function() {})
2084 key = ""
2085 assertEquals("[object Function]", Object.prototype.toString.call(f))
2086 assertEquals("", key)
2087 assertEquals("my_proxy", Object.prototype.toLocaleString.call(f))
2088 assertEquals("toString", key)
2089 assertDoesNotThrow(function(){ Function.prototype.toString.call(f) })
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002090
2091 var o = Object.create(p)
2092 key = ""
2093 assertEquals("[object Object]", Object.prototype.toString.call(o))
2094 assertEquals("", key)
2095 assertEquals("my_proxy", Object.prototype.toLocaleString.call(o))
2096 assertEquals("toString", key)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002097}
2098
2099TestToString({
2100 get: function(r, k) { key = k; return function() { return "my_proxy" } }
2101})
2102
2103TestToString({
2104 get: function(r, k) { return this.get2(r, k) },
2105 get2: function(r, k) { key = k; return function() { return "my_proxy" } }
2106})
2107
2108TestToString(Proxy.create({
2109 get: function(pr, pk) {
2110 return function(r, k) { key = k; return function() { return "my_proxy" } }
2111 }
2112}))
2113
2114
Ben Murdoch589d6972011-11-30 16:04:58 +00002115function TestToStringThrow(handler) {
2116 var p = Proxy.create(handler)
2117 assertEquals("[object Object]", Object.prototype.toString.call(p))
2118 assertThrows(function(){ Object.prototype.toLocaleString.call(p) }, "myexn")
2119
2120 var f = Proxy.createFunction(handler, function() {})
2121 assertEquals("[object Function]", Object.prototype.toString.call(f))
2122 assertThrows(function(){ Object.prototype.toLocaleString.call(f) }, "myexn")
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002123
2124 var o = Object.create(p)
2125 assertEquals("[object Object]", Object.prototype.toString.call(o))
2126 assertThrows(function(){ Object.prototype.toLocaleString.call(o) }, "myexn")
Ben Murdoch589d6972011-11-30 16:04:58 +00002127}
2128
2129TestToStringThrow({
2130 get: function(r, k) { throw "myexn" }
2131})
2132
2133TestToStringThrow({
2134 get: function(r, k) { return function() { throw "myexn" } }
2135})
2136
2137TestToStringThrow({
2138 get: function(r, k) { return this.get2(r, k) },
2139 get2: function(r, k) { throw "myexn" }
2140})
2141
2142TestToStringThrow(Proxy.create({
2143 get: function(pr, pk) { throw "myexn" }
2144}))
2145
2146TestToStringThrow(Proxy.create({
2147 get: function(pr, pk) {
2148 return function(r, k) { throw "myexn" }
2149 }
2150}))
2151
2152
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002153
2154// Value conversion (Object.prototype.toValue)
2155
2156function TestValueOf(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00002157 TestWithProxies(TestValueOf2, handler)
2158}
2159
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002160function TestValueOf2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00002161 var p = create(handler)
2162 assertSame(p, Object.prototype.valueOf.call(p))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002163}
2164
2165TestValueOf({})
2166
2167
2168
2169// Enumerability (Object.prototype.propertyIsEnumerable)
2170
2171var key
Ben Murdoch589d6972011-11-30 16:04:58 +00002172
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002173function TestIsEnumerable(handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00002174 TestWithProxies(TestIsEnumerable2, handler)
2175}
2176
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002177function TestIsEnumerable2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00002178 var p = create(handler)
2179 assertTrue(Object.prototype.propertyIsEnumerable.call(p, "a"))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002180 assertEquals("a", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00002181 assertTrue(Object.prototype.propertyIsEnumerable.call(p, 2))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002182 assertEquals("2", key)
Ben Murdoch589d6972011-11-30 16:04:58 +00002183 assertFalse(Object.prototype.propertyIsEnumerable.call(p, "z"))
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002184 assertEquals("z", key)
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002185
2186 var o = Object.create(p)
2187 key = ""
2188 assertFalse(Object.prototype.propertyIsEnumerable.call(o, "a"))
2189 assertEquals("", key) // trap not invoked
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002190}
2191
2192TestIsEnumerable({
2193 getOwnPropertyDescriptor: function(k) {
2194 key = k; return {enumerable: k < "z", configurable: true}
2195 },
2196})
2197
2198TestIsEnumerable({
2199 getOwnPropertyDescriptor: function(k) {
2200 return this.getOwnPropertyDescriptor2(k)
2201 },
2202 getOwnPropertyDescriptor2: function(k) {
2203 key = k; return {enumerable: k < "z", configurable: true}
2204 },
2205})
2206
2207TestIsEnumerable({
2208 getOwnPropertyDescriptor: function(k) {
2209 key = k; return {get enumerable() { return k < "z" }, configurable: true}
2210 },
2211})
2212
2213TestIsEnumerable(Proxy.create({
2214 get: function(pr, pk) {
2215 return function(k) {
2216 key = k; return {enumerable: k < "z", configurable: true}
2217 }
2218 }
2219}))
Ben Murdoch589d6972011-11-30 16:04:58 +00002220
2221
2222function TestIsEnumerableThrow(handler) {
2223 TestWithProxies(TestIsEnumerableThrow2, handler)
2224}
2225
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002226function TestIsEnumerableThrow2(create, handler) {
Ben Murdoch589d6972011-11-30 16:04:58 +00002227 var p = create(handler)
2228 assertThrows(function(){ Object.prototype.propertyIsEnumerable.call(p, "a") },
2229 "myexn")
2230 assertThrows(function(){ Object.prototype.propertyIsEnumerable.call(p, 11) },
2231 "myexn")
2232}
2233
2234TestIsEnumerableThrow({
2235 getOwnPropertyDescriptor: function(k) { throw "myexn" }
2236})
2237
2238TestIsEnumerableThrow({
2239 getOwnPropertyDescriptor: function(k) {
2240 return this.getOwnPropertyDescriptor2(k)
2241 },
2242 getOwnPropertyDescriptor2: function(k) { throw "myexn" }
2243})
2244
2245TestIsEnumerableThrow({
2246 getOwnPropertyDescriptor: function(k) {
2247 return {get enumerable() { throw "myexn" }, configurable: true}
2248 },
2249})
2250
2251TestIsEnumerableThrow(Proxy.create({
2252 get: function(pr, pk) { throw "myexn" }
2253}))
2254
2255TestIsEnumerableThrow(Proxy.create({
2256 get: function(pr, pk) {
2257 return function(k) { throw "myexn" }
2258 }
2259}))
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002260
2261
2262
2263// Constructor functions with proxy prototypes.
2264
2265function TestConstructorWithProxyPrototype() {
2266 TestWithProxies(TestConstructorWithProxyPrototype2, {})
2267}
2268
2269function TestConstructorWithProxyPrototype2(create, handler) {
2270 function C() {};
2271 C.prototype = create(handler);
2272
2273 var o = new C;
2274 assertSame(C.prototype, o.__proto__);
2275 assertSame(C.prototype, Object.getPrototypeOf(o));
2276}
2277
2278TestConstructorWithProxyPrototype();