OLD | NEW |
1 // Flags: --harmony-proxies | |
2 | |
3 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 the V8 project authors. All rights reserved. |
4 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
6 // met: | 4 // met: |
7 // | 5 // |
8 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
11 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
12 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
13 // with the distribution. | 11 // with the distribution. |
14 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
15 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
16 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
17 // | 15 // |
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 27 |
| 28 // Flags: --harmony-proxies |
| 29 |
30 | 30 |
31 // TODO(rossberg): test exception cases. | 31 // TODO(rossberg): test exception cases. |
| 32 // TODO(rossberg): test proxies as prototypes. |
| 33 // TODO(rossberg): for-in for proxies not implemented. |
| 34 // TODO(rossberg): function proxies as constructors not implemented. |
| 35 |
| 36 |
| 37 // Helper. |
| 38 |
| 39 function TestWithProxies(test, handler) { |
| 40 test(handler, Proxy.create) |
| 41 test(handler, function(h) {return Proxy.createFunction(h, function() {})}) |
| 42 } |
32 | 43 |
33 | 44 |
34 // Getters. | 45 // Getters. |
35 | 46 |
36 function TestGet(handler) { | 47 function TestGet(handler) { |
37 var o = Proxy.create(handler) | 48 TestWithProxies(TestGet2, handler) |
| 49 } |
| 50 |
| 51 function TestGet2(handler, create) { |
| 52 var o = create(handler) |
38 assertEquals(42, o.a) | 53 assertEquals(42, o.a) |
39 assertEquals(42, o["b"]) | 54 assertEquals(42, o["b"]) |
40 } | 55 } |
41 | 56 |
42 TestGet({ | 57 TestGet({ |
43 get: function(r, k) { return 42 } | 58 get: function(r, k) { return 42 } |
44 }) | 59 }) |
45 | 60 |
46 TestGet({ | 61 TestGet({ |
47 get: function(r, k) { return this.get2(r, k) }, | 62 get: function(r, k) { return this.get2(r, k) }, |
(...skipping 21 matching lines...) Expand all Loading... |
69 }) | 84 }) |
70 | 85 |
71 TestGet(Proxy.create({ | 86 TestGet(Proxy.create({ |
72 get: function(pr, pk) { | 87 get: function(pr, pk) { |
73 return function(r, k) { return 42 } | 88 return function(r, k) { return 42 } |
74 } | 89 } |
75 })) | 90 })) |
76 | 91 |
77 | 92 |
78 function TestGetCall(handler) { | 93 function TestGetCall(handler) { |
79 var p = Proxy.create(handler) | 94 TestWithProxies(TestGetCall2, handler) |
| 95 } |
| 96 |
| 97 function TestGetCall2(handler, create) { |
| 98 var p = create(handler) |
80 assertEquals(55, p.f()) | 99 assertEquals(55, p.f()) |
81 assertEquals(55, p.f("unused", "arguments")) | 100 assertEquals(55, p.f("unused", "arguments")) |
82 assertEquals(55, p.f.call(p)) | 101 assertEquals(55, p.f.call(p)) |
83 assertEquals(55, p.withargs(45, 5)) | 102 assertEquals(55, p.withargs(45, 5)) |
84 assertEquals(55, p.withargs.call(p, 11, 22)) | 103 assertEquals(55, p.withargs.call(p, 11, 22)) |
85 assertEquals("6655", "66" + p) // calls p.toString | 104 assertEquals("6655", "66" + p) // calls p.toString |
86 } | 105 } |
87 | 106 |
88 TestGetCall({ | 107 TestGetCall({ |
89 get: function(r, k) { return function() { return 55 } } | 108 get: function(r, k) { return function() { return 55 } } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 return function(r, k) { return function() { return 55 } } | 156 return function(r, k) { return function() { return 55 } } |
138 } | 157 } |
139 })) | 158 })) |
140 | 159 |
141 | 160 |
142 | 161 |
143 // Setters. | 162 // Setters. |
144 | 163 |
145 var key | 164 var key |
146 var val | 165 var val |
147 function TestSet(handler) { | 166 |
148 var o = Proxy.create(handler) | 167 function TestSet(handler, create) { |
| 168 TestWithProxies(TestSet2, handler) |
| 169 } |
| 170 |
| 171 function TestSet2(handler, create) { |
| 172 var o = create(handler) |
149 assertEquals(42, o.a = 42) | 173 assertEquals(42, o.a = 42) |
150 assertEquals("a", key) | 174 assertEquals("a", key) |
151 assertEquals(42, val) | 175 assertEquals(42, val) |
152 assertEquals(43, o["b"] = 43) | 176 assertEquals(43, o["b"] = 43) |
153 assertEquals("b", key) | 177 assertEquals("b", key) |
154 assertEquals(43, val) | 178 assertEquals(43, val) |
155 } | 179 } |
156 | 180 |
157 TestSet({ | 181 TestSet({ |
158 set: function(r, k, v) { key = k; val = v; return true } | 182 set: function(r, k, v) { key = k; val = v; return true } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 return function(r, k, v) { key = k; val = v; return true } | 246 return function(r, k, v) { key = k; val = v; return true } |
223 } | 247 } |
224 })) | 248 })) |
225 | 249 |
226 | 250 |
227 | 251 |
228 // Property definition (Object.defineProperty and Object.defineProperties). | 252 // Property definition (Object.defineProperty and Object.defineProperties). |
229 | 253 |
230 var key | 254 var key |
231 var desc | 255 var desc |
| 256 |
232 function TestDefine(handler) { | 257 function TestDefine(handler) { |
233 var o = Proxy.create(handler) | 258 TestWithProxies(TestDefine2, handler) |
| 259 } |
| 260 |
| 261 function TestDefine2(handler, create) { |
| 262 var o = create(handler) |
234 assertEquals(o, Object.defineProperty(o, "a", {value: 44})) | 263 assertEquals(o, Object.defineProperty(o, "a", {value: 44})) |
235 assertEquals("a", key) | 264 assertEquals("a", key) |
236 assertEquals(1, Object.getOwnPropertyNames(desc).length) | 265 assertEquals(1, Object.getOwnPropertyNames(desc).length) |
237 assertEquals(44, desc.value) | 266 assertEquals(44, desc.value) |
238 | 267 |
239 assertEquals(o, Object.defineProperty(o, "b", {value: 45, writable: false})) | 268 assertEquals(o, Object.defineProperty(o, "b", {value: 45, writable: false})) |
240 assertEquals("b", key) | 269 assertEquals("b", key) |
241 assertEquals(2, Object.getOwnPropertyNames(desc).length) | 270 assertEquals(2, Object.getOwnPropertyNames(desc).length) |
242 assertEquals(45, desc.value) | 271 assertEquals(45, desc.value) |
243 assertEquals(false, desc.writable) | 272 assertEquals(false, desc.writable) |
(...skipping 18 matching lines...) Expand all Loading... |
262 | 291 |
263 assertEquals(o, Object.defineProperty(o, "e", {get: function(){ return 5 }})) | 292 assertEquals(o, Object.defineProperty(o, "e", {get: function(){ return 5 }})) |
264 assertEquals("e", key) | 293 assertEquals("e", key) |
265 assertEquals(1, Object.getOwnPropertyNames(desc).length) | 294 assertEquals(1, Object.getOwnPropertyNames(desc).length) |
266 assertEquals(5, desc.get()) | 295 assertEquals(5, desc.get()) |
267 | 296 |
268 assertEquals(o, Object.defineProperty(o, "zzz", {})) | 297 assertEquals(o, Object.defineProperty(o, "zzz", {})) |
269 assertEquals("zzz", key) | 298 assertEquals("zzz", key) |
270 assertEquals(0, Object.getOwnPropertyNames(desc).length) | 299 assertEquals(0, Object.getOwnPropertyNames(desc).length) |
271 | 300 |
272 // TODO(rossberg): This test requires [s in proxy] to be implemented first. | 301 // TODO(rossberg): This test requires for-in on proxies. |
273 // var d = Proxy.create({ | 302 // var d = create({ |
274 // get: function(r, k) { return (k === "value") ? 77 : void 0 }, | 303 // get: function(r, k) { return (k === "value") ? 77 : void 0 }, |
275 // getOwnPropertyNames: function() { return ["value"] } | 304 // getOwnPropertyNames: function() { return ["value"] } |
276 // }) | 305 // }) |
277 // assertEquals(1, Object.getOwnPropertyNames(d).length) | 306 // assertEquals(1, Object.getOwnPropertyNames(d).length) |
278 // assertEquals(77, d.value) | 307 // assertEquals(77, d.value) |
279 // assertEquals(o, Object.defineProperty(o, "p", d)) | 308 // assertEquals(o, Object.defineProperty(o, "p", d)) |
280 // assertEquals("p", key) | 309 // assertEquals("p", key) |
281 // assertEquals(1, Object.getOwnPropertyNames(desc).length) | 310 // assertEquals(1, Object.getOwnPropertyNames(desc).length) |
282 // assertEquals(77, desc.value) | 311 // assertEquals(77, desc.value) |
283 | 312 |
(...skipping 25 matching lines...) Expand all Loading... |
309 get: function(pr, pk) { | 338 get: function(pr, pk) { |
310 return function(k, d) { key = k; desc = d; return true } | 339 return function(k, d) { key = k; desc = d; return true } |
311 } | 340 } |
312 })) | 341 })) |
313 | 342 |
314 | 343 |
315 | 344 |
316 // Property deletion (delete). | 345 // Property deletion (delete). |
317 | 346 |
318 var key | 347 var key |
| 348 |
319 function TestDelete(handler) { | 349 function TestDelete(handler) { |
320 var o = Proxy.create(handler) | 350 TestWithProxies(TestDelete2, handler) |
| 351 } |
| 352 |
| 353 function TestDelete2(handler, create) { |
| 354 var o = create(handler) |
321 assertEquals(true, delete o.a) | 355 assertEquals(true, delete o.a) |
322 assertEquals("a", key) | 356 assertEquals("a", key) |
323 assertEquals(true, delete o["b"]) | 357 assertEquals(true, delete o["b"]) |
324 assertEquals("b", key) | 358 assertEquals("b", key) |
325 | 359 |
326 assertEquals(false, delete o.z1) | 360 assertEquals(false, delete o.z1) |
327 assertEquals("z1", key) | 361 assertEquals("z1", key) |
328 assertEquals(false, delete o["z2"]) | 362 assertEquals(false, delete o["z2"]) |
329 assertEquals("z2", key); | 363 assertEquals("z2", key); |
330 | 364 |
(...skipping 24 matching lines...) Expand all Loading... |
355 get: function(pr, pk) { | 389 get: function(pr, pk) { |
356 return function(k) { key = k; return k < "z" } | 390 return function(k) { key = k; return k < "z" } |
357 } | 391 } |
358 })) | 392 })) |
359 | 393 |
360 | 394 |
361 | 395 |
362 // Property descriptors (Object.getOwnPropertyDescriptor). | 396 // Property descriptors (Object.getOwnPropertyDescriptor). |
363 | 397 |
364 function TestDescriptor(handler) { | 398 function TestDescriptor(handler) { |
365 var o = Proxy.create(handler) | 399 TestWithProxies(TestDescriptor2, handler) |
| 400 } |
| 401 |
| 402 function TestDescriptor2(handler, create) { |
| 403 var o = create(handler) |
366 var descs = [ | 404 var descs = [ |
367 {configurable: true}, | 405 {configurable: true}, |
368 {value: 34, enumerable: true, configurable: true}, | 406 {value: 34, enumerable: true, configurable: true}, |
369 {value: 3, writable: false, mine: "eyes", configurable: true}, | 407 {value: 3, writable: false, mine: "eyes", configurable: true}, |
370 {get value() { return 20 }, get configurable() { return true }}, | 408 {get value() { return 20 }, get configurable() { return true }}, |
371 {get: function() { "get" }, set: function() { "set" }, configurable: true} | 409 {get: function() { "get" }, set: function() { "set" }, configurable: true} |
372 ] | 410 ] |
373 for (var i = 0; i < descs.length; ++i) { | 411 for (var i = 0; i < descs.length; ++i) { |
374 assertEquals(o, Object.defineProperty(o, i, descs[i])) | 412 assertEquals(o, Object.defineProperty(o, i, descs[i])) |
375 var desc = Object.getOwnPropertyDescriptor(o, i) | 413 var desc = Object.getOwnPropertyDescriptor(o, i) |
376 for (p in descs[i]) { | 414 for (p in descs[i]) { |
377 // TODO(rossberg): Ignore user attributes as long as the spec isn't | 415 // TODO(rossberg): Ignore user attributes as long as the spec isn't |
378 // fixed suitably. | 416 // fixed suitably. |
379 if (p != "mine") assertEquals(descs[i][p], desc[p]) | 417 if (p != "mine") assertEquals(descs[i][p], desc[p]) |
380 } | 418 } |
381 assertEquals(undefined, Object.getOwnPropertyDescriptor(o, "absent")) | 419 assertEquals(undefined, Object.getOwnPropertyDescriptor(o, "absent")) |
382 } | 420 } |
383 } | 421 } |
384 | 422 |
385 | |
386 TestDescriptor({ | 423 TestDescriptor({ |
387 defineProperty: function(k, d) { this["__" + k] = d; return true }, | 424 defineProperty: function(k, d) { this["__" + k] = d; return true }, |
388 getOwnPropertyDescriptor: function(k) { return this["__" + k] } | 425 getOwnPropertyDescriptor: function(k) { return this["__" + k] } |
389 }) | 426 }) |
390 | 427 |
391 TestDescriptor({ | 428 TestDescriptor({ |
392 defineProperty: function(k, d) { this["__" + k] = d; return true }, | 429 defineProperty: function(k, d) { this["__" + k] = d; return true }, |
393 getOwnPropertyDescriptor: function(k) { | 430 getOwnPropertyDescriptor: function(k) { |
394 return this.getOwnPropertyDescriptor2(k) | 431 return this.getOwnPropertyDescriptor2(k) |
395 }, | 432 }, |
396 getOwnPropertyDescriptor2: function(k) { return this["__" + k] } | 433 getOwnPropertyDescriptor2: function(k) { return this["__" + k] } |
397 }) | 434 }) |
398 | 435 |
399 | 436 |
400 | 437 |
401 // Comparison. | 438 // Comparison. |
402 | 439 |
403 function TestComparison(eq) { | 440 function TestComparison(eq) { |
404 var o1 = Proxy.create({}) | 441 TestWithProxies(TestComparison2, eq) |
405 var o2 = Proxy.create({}) | 442 } |
| 443 |
| 444 function TestComparison2(eq, create) { |
| 445 var o1 = create({}) |
| 446 var o2 = create({}) |
406 | 447 |
407 assertTrue(eq(o1, o1)) | 448 assertTrue(eq(o1, o1)) |
408 assertTrue(eq(o2, o2)) | 449 assertTrue(eq(o2, o2)) |
409 assertTrue(!eq(o1, o2)) | 450 assertTrue(!eq(o1, o2)) |
410 assertTrue(!eq(o1, {})) | 451 assertTrue(!eq(o1, {})) |
411 assertTrue(!eq({}, o2)) | 452 assertTrue(!eq({}, o2)) |
412 assertTrue(!eq({}, {})) | 453 assertTrue(!eq({}, {})) |
413 } | 454 } |
414 | 455 |
415 TestComparison(function(o1, o2) { return o1 == o2 }) | 456 TestComparison(function(o1, o2) { return o1 == o2 }) |
416 TestComparison(function(o1, o2) { return o1 === o2 }) | 457 TestComparison(function(o1, o2) { return o1 === o2 }) |
417 TestComparison(function(o1, o2) { return !(o1 != o2) }) | 458 TestComparison(function(o1, o2) { return !(o1 != o2) }) |
418 TestComparison(function(o1, o2) { return !(o1 !== o2) }) | 459 TestComparison(function(o1, o2) { return !(o1 !== o2) }) |
419 | 460 |
420 | 461 |
421 | 462 |
422 // Type. | 463 // Type (typeof). |
423 | 464 |
424 assertEquals("object", typeof Proxy.create({})) | 465 function TestTypeof() { |
425 assertTrue(typeof Proxy.create({}) == "object") | 466 assertEquals("object", typeof Proxy.create({})) |
426 assertTrue("object" == typeof Proxy.create({})) | 467 assertTrue(typeof Proxy.create({}) == "object") |
| 468 assertTrue("object" == typeof Proxy.create({})) |
427 | 469 |
428 // No function proxies yet. | 470 assertEquals("function", typeof Proxy.createFunction({}, function() {})) |
| 471 assertTrue(typeof Proxy.createFunction({}, function() {}) == "function") |
| 472 assertTrue("function" == typeof Proxy.createFunction({}, function() {})) |
| 473 } |
| 474 |
| 475 TestTypeof() |
429 | 476 |
430 | 477 |
431 | 478 |
432 // Membership test (in). | 479 // Membership test (in). |
433 | 480 |
434 var key | 481 var key |
| 482 |
435 function TestIn(handler) { | 483 function TestIn(handler) { |
436 var o = Proxy.create(handler) | 484 TestWithProxies(TestIn2, handler) |
| 485 } |
| 486 |
| 487 function TestIn2(handler, create) { |
| 488 var o = create(handler) |
437 assertTrue("a" in o) | 489 assertTrue("a" in o) |
438 assertEquals("a", key) | 490 assertEquals("a", key) |
439 assertTrue(99 in o) | 491 assertTrue(99 in o) |
440 assertEquals("99", key) | 492 assertEquals("99", key) |
441 assertFalse("z" in o) | 493 assertFalse("z" in o) |
442 assertEquals("z", key) | 494 assertEquals("z", key) |
443 | 495 |
444 if ("b" in o) { | 496 if ("b" in o) { |
445 } else { | 497 } else { |
446 assertTrue(false) | 498 assertTrue(false) |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 get: function(pr, pk) { | 555 get: function(pr, pk) { |
504 return function(k) { key = k; return k < "z" } | 556 return function(k) { key = k; return k < "z" } |
505 } | 557 } |
506 })) | 558 })) |
507 | 559 |
508 | 560 |
509 | 561 |
510 // Own Properties (Object.prototype.hasOwnProperty). | 562 // Own Properties (Object.prototype.hasOwnProperty). |
511 | 563 |
512 var key | 564 var key |
| 565 |
513 function TestHasOwn(handler) { | 566 function TestHasOwn(handler) { |
514 var o = Proxy.create(handler) | 567 TestWithProxies(TestHasOwn2, handler) |
| 568 } |
| 569 |
| 570 function TestHasOwn2(handler, create) { |
| 571 var o = create(handler) |
515 assertTrue(Object.prototype.hasOwnProperty.call(o, "a")) | 572 assertTrue(Object.prototype.hasOwnProperty.call(o, "a")) |
516 assertEquals("a", key) | 573 assertEquals("a", key) |
517 assertTrue(Object.prototype.hasOwnProperty.call(o, 99)) | 574 assertTrue(Object.prototype.hasOwnProperty.call(o, 99)) |
518 assertEquals("99", key) | 575 assertEquals("99", key) |
519 assertFalse(Object.prototype.hasOwnProperty.call(o, "z")) | 576 assertFalse(Object.prototype.hasOwnProperty.call(o, "z")) |
520 assertEquals("z", key) | 577 assertEquals("z", key) |
521 } | 578 } |
522 | 579 |
523 TestHasOwn({ | 580 TestHasOwn({ |
524 hasOwn: function(k) { key = k; return k < "z" } | 581 hasOwn: function(k) { key = k; return k < "z" } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 | 623 |
567 | 624 |
568 // Instanceof (instanceof) | 625 // Instanceof (instanceof) |
569 | 626 |
570 function TestInstanceof() { | 627 function TestInstanceof() { |
571 var o = {} | 628 var o = {} |
572 var p1 = Proxy.create({}) | 629 var p1 = Proxy.create({}) |
573 var p2 = Proxy.create({}, o) | 630 var p2 = Proxy.create({}, o) |
574 var p3 = Proxy.create({}, p2) | 631 var p3 = Proxy.create({}, p2) |
575 | 632 |
576 var f = function() {} | 633 var f0 = function() {} |
577 f.prototype = o | 634 f0.prototype = o |
578 var f1 = function() {} | 635 var f1 = function() {} |
579 f1.prototype = p1 | 636 f1.prototype = p1 |
580 var f2 = function() {} | 637 var f2 = function() {} |
581 f2.prototype = p2 | 638 f2.prototype = p2 |
582 | 639 |
583 assertTrue(o instanceof Object) | 640 assertTrue(o instanceof Object) |
584 assertFalse(o instanceof f) | 641 assertFalse(o instanceof f0) |
585 assertFalse(o instanceof f1) | 642 assertFalse(o instanceof f1) |
586 assertFalse(o instanceof f2) | 643 assertFalse(o instanceof f2) |
587 assertFalse(p1 instanceof Object) | 644 assertFalse(p1 instanceof Object) |
588 assertFalse(p1 instanceof f) | 645 assertFalse(p1 instanceof f0) |
589 assertFalse(p1 instanceof f1) | 646 assertFalse(p1 instanceof f1) |
590 assertFalse(p1 instanceof f2) | 647 assertFalse(p1 instanceof f2) |
591 assertTrue(p2 instanceof Object) | 648 assertTrue(p2 instanceof Object) |
592 assertTrue(p2 instanceof f) | 649 assertTrue(p2 instanceof f0) |
593 assertFalse(p2 instanceof f1) | 650 assertFalse(p2 instanceof f1) |
594 assertFalse(p2 instanceof f2) | 651 assertFalse(p2 instanceof f2) |
595 assertTrue(p3 instanceof Object) | 652 assertTrue(p3 instanceof Object) |
596 assertTrue(p3 instanceof f) | 653 assertTrue(p3 instanceof f0) |
597 assertFalse(p3 instanceof f1) | 654 assertFalse(p3 instanceof f1) |
598 assertTrue(p3 instanceof f2) | 655 assertTrue(p3 instanceof f2) |
| 656 |
| 657 var f = Proxy.createFunction({}, function() {}) |
| 658 assertTrue(f instanceof Function) |
599 } | 659 } |
600 | 660 |
601 TestInstanceof() | 661 TestInstanceof() |
602 | 662 |
603 | 663 |
604 | 664 |
605 // Prototype (Object.getPrototypeOf, Object.prototype.isPrototypeOf). | 665 // Prototype (Object.getPrototypeOf, Object.prototype.isPrototypeOf). |
606 | 666 |
607 function TestPrototype() { | 667 function TestPrototype() { |
608 var o = {} | 668 var o = {} |
(...skipping 26 matching lines...) Expand all Loading... |
635 assertFalse(Object.prototype.isPrototypeOf.call(p1, p1)) | 695 assertFalse(Object.prototype.isPrototypeOf.call(p1, p1)) |
636 assertFalse(Object.prototype.isPrototypeOf.call(p1, o)) | 696 assertFalse(Object.prototype.isPrototypeOf.call(p1, o)) |
637 assertFalse(Object.prototype.isPrototypeOf.call(p1, p2)) | 697 assertFalse(Object.prototype.isPrototypeOf.call(p1, p2)) |
638 assertFalse(Object.prototype.isPrototypeOf.call(p1, p3)) | 698 assertFalse(Object.prototype.isPrototypeOf.call(p1, p3)) |
639 assertFalse(Object.prototype.isPrototypeOf.call(p1, p4)) | 699 assertFalse(Object.prototype.isPrototypeOf.call(p1, p4)) |
640 assertFalse(Object.prototype.isPrototypeOf.call(p2, p1)) | 700 assertFalse(Object.prototype.isPrototypeOf.call(p2, p1)) |
641 assertFalse(Object.prototype.isPrototypeOf.call(p2, p2)) | 701 assertFalse(Object.prototype.isPrototypeOf.call(p2, p2)) |
642 assertTrue(Object.prototype.isPrototypeOf.call(p2, p3)) | 702 assertTrue(Object.prototype.isPrototypeOf.call(p2, p3)) |
643 assertFalse(Object.prototype.isPrototypeOf.call(p2, p4)) | 703 assertFalse(Object.prototype.isPrototypeOf.call(p2, p4)) |
644 assertFalse(Object.prototype.isPrototypeOf.call(p3, p2)) | 704 assertFalse(Object.prototype.isPrototypeOf.call(p3, p2)) |
| 705 |
| 706 var f = Proxy.createFunction({}, function() {}) |
| 707 assertSame(Object.getPrototypeOf(f), Function.prototype) |
| 708 assertTrue(Object.prototype.isPrototypeOf(f)) |
| 709 assertTrue(Object.prototype.isPrototypeOf.call(Function.prototype, f)) |
645 } | 710 } |
646 | 711 |
647 TestPrototype() | 712 TestPrototype() |
648 | 713 |
649 | 714 |
650 | 715 |
651 // Property names (Object.getOwnPropertyNames, Object.keys). | 716 // Property names (Object.getOwnPropertyNames, Object.keys). |
652 | 717 |
653 function TestPropertyNames(names, handler) { | 718 function TestPropertyNames(names, handler) { |
654 var p = Proxy.create(handler) | 719 TestWithProxies(TestPropertyNames2, [names, handler]) |
655 assertArrayEquals(names, Object.getOwnPropertyNames(p)) | 720 } |
| 721 |
| 722 function TestPropertyNames2(names_handler, create) { |
| 723 var p = create(names_handler[1]) |
| 724 assertArrayEquals(names_handler[0], Object.getOwnPropertyNames(p)) |
656 } | 725 } |
657 | 726 |
658 TestPropertyNames([], { | 727 TestPropertyNames([], { |
659 getOwnPropertyNames: function() { return [] } | 728 getOwnPropertyNames: function() { return [] } |
660 }) | 729 }) |
661 | 730 |
662 TestPropertyNames(["a", "zz", " ", "0"], { | 731 TestPropertyNames(["a", "zz", " ", "0"], { |
663 getOwnPropertyNames: function() { return ["a", "zz", " ", 0] } | 732 getOwnPropertyNames: function() { return ["a", "zz", " ", 0] } |
664 }) | 733 }) |
665 | 734 |
666 TestPropertyNames(["throw", "function "], { | 735 TestPropertyNames(["throw", "function "], { |
667 getOwnPropertyNames: function() { return this.getOwnPropertyNames2() }, | 736 getOwnPropertyNames: function() { return this.getOwnPropertyNames2() }, |
668 getOwnPropertyNames2: function() { return ["throw", "function "] } | 737 getOwnPropertyNames2: function() { return ["throw", "function "] } |
669 }) | 738 }) |
670 | 739 |
671 TestPropertyNames(["[object Object]"], { | 740 TestPropertyNames(["[object Object]"], { |
672 get getOwnPropertyNames() { | 741 get getOwnPropertyNames() { |
673 return function() { return [{}] } | 742 return function() { return [{}] } |
674 } | 743 } |
675 }) | 744 }) |
676 | 745 |
677 | 746 |
678 function TestKeys(names, handler) { | 747 function TestKeys(names, handler) { |
679 var p = Proxy.create(handler) | 748 TestWithProxies(TestKeys2, [names, handler]) |
680 assertArrayEquals(names, Object.keys(p)) | 749 } |
| 750 |
| 751 function TestKeys2(names_handler, create) { |
| 752 var p = create(names_handler[1]) |
| 753 assertArrayEquals(names_handler[0], Object.keys(p)) |
681 } | 754 } |
682 | 755 |
683 TestKeys([], { | 756 TestKeys([], { |
684 keys: function() { return [] } | 757 keys: function() { return [] } |
685 }) | 758 }) |
686 | 759 |
687 TestKeys(["a", "zz", " ", "0"], { | 760 TestKeys(["a", "zz", " ", "0"], { |
688 keys: function() { return ["a", "zz", " ", 0] } | 761 keys: function() { return ["a", "zz", " ", 0] } |
689 }) | 762 }) |
690 | 763 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 | 880 |
808 TestFix(["b"], { | 881 TestFix(["b"], { |
809 get fix() { | 882 get fix() { |
810 return function() { | 883 return function() { |
811 return {b: {configurable: true, writable: true, enumerable: true}} | 884 return {b: {configurable: true, writable: true, enumerable: true}} |
812 } | 885 } |
813 } | 886 } |
814 }) | 887 }) |
815 | 888 |
816 | 889 |
| 890 function TestFixFunction(fix) { |
| 891 var f1 = Proxy.createFunction({ |
| 892 fix: function() { return {} } |
| 893 }, function() {}) |
| 894 fix(f1) |
| 895 assertEquals(0, f1.length) |
817 | 896 |
818 // String conversion (Object.prototype.toString, Object.prototype.toLocaleString
) | 897 var f2 = Proxy.createFunction({ |
| 898 fix: function() { return {length: {value: 3}} } |
| 899 }, function() {}) |
| 900 fix(f2) |
| 901 assertEquals(3, f2.length) |
| 902 |
| 903 var f3 = Proxy.createFunction({ |
| 904 fix: function() { return {length: {value: "huh"}} } |
| 905 }, function() {}) |
| 906 fix(f3) |
| 907 assertEquals(0, f1.length) |
| 908 } |
| 909 |
| 910 TestFixFunction(Object.seal) |
| 911 TestFixFunction(Object.freeze) |
| 912 TestFixFunction(Object.preventExtensions) |
| 913 |
| 914 |
| 915 |
| 916 // String conversion (Object.prototype.toString, |
| 917 // Object.prototype.toLocaleString, |
| 918 // Function.prototype.toString) |
819 | 919 |
820 var key | 920 var key |
| 921 |
821 function TestToString(handler) { | 922 function TestToString(handler) { |
822 var o = Proxy.create(handler) | 923 var o = Proxy.create(handler) |
823 key = "" | 924 key = "" |
824 assertEquals("[object Object]", Object.prototype.toString.call(o)) | 925 assertEquals("[object Object]", Object.prototype.toString.call(o)) |
825 assertEquals("", key) | 926 assertEquals("", key) |
826 assertEquals("my_proxy", Object.prototype.toLocaleString.call(o)) | 927 assertEquals("my_proxy", Object.prototype.toLocaleString.call(o)) |
827 assertEquals("toString", key) | 928 assertEquals("toString", key) |
| 929 |
| 930 var f = Proxy.createFunction(handler, function() {}) |
| 931 key = "" |
| 932 assertEquals("[object Function]", Object.prototype.toString.call(f)) |
| 933 assertEquals("", key) |
| 934 assertEquals("my_proxy", Object.prototype.toLocaleString.call(o)) |
| 935 assertEquals("toString", key) |
| 936 assertDoesNotThrow(function(){ Function.prototype.toString.call(f) }) |
828 } | 937 } |
829 | 938 |
830 TestToString({ | 939 TestToString({ |
831 get: function(r, k) { key = k; return function() { return "my_proxy" } } | 940 get: function(r, k) { key = k; return function() { return "my_proxy" } } |
832 }) | 941 }) |
833 | 942 |
834 TestToString({ | 943 TestToString({ |
835 get: function(r, k) { return this.get2(r, k) }, | 944 get: function(r, k) { return this.get2(r, k) }, |
836 get2: function(r, k) { key = k; return function() { return "my_proxy" } } | 945 get2: function(r, k) { key = k; return function() { return "my_proxy" } } |
837 }) | 946 }) |
838 | 947 |
839 TestToString(Proxy.create({ | 948 TestToString(Proxy.create({ |
840 get: function(pr, pk) { | 949 get: function(pr, pk) { |
841 return function(r, k) { key = k; return function() { return "my_proxy" } } | 950 return function(r, k) { key = k; return function() { return "my_proxy" } } |
842 } | 951 } |
843 })) | 952 })) |
844 | 953 |
845 | 954 |
846 | 955 |
847 // Value conversion (Object.prototype.toValue) | 956 // Value conversion (Object.prototype.toValue) |
848 | 957 |
849 function TestValueOf(handler) { | 958 function TestValueOf(handler) { |
850 var o = Proxy.create(handler) | 959 TestWithProxies(TestValueOf2, handler) |
| 960 } |
| 961 |
| 962 function TestValueOf2(handler, create) { |
| 963 var o = create(handler) |
851 assertSame(o, Object.prototype.valueOf.call(o)) | 964 assertSame(o, Object.prototype.valueOf.call(o)) |
852 } | 965 } |
853 | 966 |
854 TestValueOf({}) | 967 TestValueOf({}) |
855 | 968 |
856 | 969 |
857 | 970 |
858 // Enumerability (Object.prototype.propertyIsEnumerable) | 971 // Enumerability (Object.prototype.propertyIsEnumerable) |
859 | 972 |
860 var key | 973 var key |
| 974 |
861 function TestIsEnumerable(handler) { | 975 function TestIsEnumerable(handler) { |
862 var o = Proxy.create(handler) | 976 TestWithProxies(TestIsEnumerable2, handler) |
| 977 } |
| 978 |
| 979 function TestIsEnumerable2(handler, create) { |
| 980 var o = create(handler) |
863 assertTrue(Object.prototype.propertyIsEnumerable.call(o, "a")) | 981 assertTrue(Object.prototype.propertyIsEnumerable.call(o, "a")) |
864 assertEquals("a", key) | 982 assertEquals("a", key) |
865 assertTrue(Object.prototype.propertyIsEnumerable.call(o, 2)) | 983 assertTrue(Object.prototype.propertyIsEnumerable.call(o, 2)) |
866 assertEquals("2", key) | 984 assertEquals("2", key) |
867 assertFalse(Object.prototype.propertyIsEnumerable.call(o, "z")) | 985 assertFalse(Object.prototype.propertyIsEnumerable.call(o, "z")) |
868 assertEquals("z", key) | 986 assertEquals("z", key) |
869 } | 987 } |
870 | 988 |
871 TestIsEnumerable({ | 989 TestIsEnumerable({ |
872 getOwnPropertyDescriptor: function(k) { | 990 getOwnPropertyDescriptor: function(k) { |
(...skipping 16 matching lines...) Expand all Loading... |
889 }, | 1007 }, |
890 }) | 1008 }) |
891 | 1009 |
892 TestIsEnumerable(Proxy.create({ | 1010 TestIsEnumerable(Proxy.create({ |
893 get: function(pr, pk) { | 1011 get: function(pr, pk) { |
894 return function(k) { | 1012 return function(k) { |
895 key = k; return {enumerable: k < "z", configurable: true} | 1013 key = k; return {enumerable: k < "z", configurable: true} |
896 } | 1014 } |
897 } | 1015 } |
898 })) | 1016 })) |
| 1017 |
| 1018 |
| 1019 |
| 1020 // Calling (call, Function.prototype.call, Function.prototype.apply, |
| 1021 // Function.prototype.bind). |
| 1022 |
| 1023 var global = this |
| 1024 var receiver |
| 1025 |
| 1026 function TestCall(isStrict, callTrap) { |
| 1027 assertEquals(42, callTrap(5, 37)) |
| 1028 // TODO(rossberg): unrelated bug: this does not succeed for optimized code. |
| 1029 // assertEquals(isStrict ? undefined : global, receiver) |
| 1030 |
| 1031 var f = Proxy.createFunction({fix: function() { return {} }}, callTrap) |
| 1032 |
| 1033 receiver = 333 |
| 1034 assertEquals(42, f(11, 31)) |
| 1035 assertEquals(isStrict ? undefined : global, receiver) |
| 1036 var o = {} |
| 1037 assertEquals(42, Function.prototype.call.call(f, o, 20, 22)) |
| 1038 assertEquals(o, receiver) |
| 1039 assertEquals(43, Function.prototype.call.call(f, null, 20, 23)) |
| 1040 assertEquals(isStrict ? null : global, receiver) |
| 1041 assertEquals(44, Function.prototype.call.call(f, 2, 21, 23)) |
| 1042 assertEquals(2, receiver.valueOf()) |
| 1043 receiver = 333 |
| 1044 assertEquals(32, Function.prototype.apply.call(f, o, [17, 15])) |
| 1045 assertEquals(o, receiver) |
| 1046 var ff = Function.prototype.bind.call(f, o, 12) |
| 1047 receiver = 333 |
| 1048 assertEquals(42, ff(30)) |
| 1049 assertEquals(o, receiver) |
| 1050 receiver = 333 |
| 1051 assertEquals(32, Function.prototype.apply.call(ff, {}, [20])) |
| 1052 assertEquals(o, receiver) |
| 1053 |
| 1054 Object.freeze(f) |
| 1055 |
| 1056 receiver = 333 |
| 1057 assertEquals(42, f(11, 31)) |
| 1058 // TODO(rossberg): unrelated bug: this does not succeed for optimized code. |
| 1059 // assertEquals(isStrict ? undefined : global, receiver) |
| 1060 receiver = 333 |
| 1061 assertEquals(42, Function.prototype.call.call(f, o, 20, 22)) |
| 1062 assertEquals(o, receiver) |
| 1063 receiver = 333 |
| 1064 assertEquals(32, Function.prototype.apply.call(f, o, [17, 15])) |
| 1065 assertEquals(o, receiver) |
| 1066 receiver = 333 |
| 1067 assertEquals(42, ff(30)) |
| 1068 assertEquals(o, receiver) |
| 1069 receiver = 333 |
| 1070 assertEquals(32, Function.prototype.apply.call(ff, {}, [20])) |
| 1071 assertEquals(o, receiver) |
| 1072 } |
| 1073 |
| 1074 TestCall(false, function(x, y) { |
| 1075 receiver = this; return x + y |
| 1076 }) |
| 1077 |
| 1078 TestCall(true, function(x, y) { |
| 1079 "use strict"; |
| 1080 receiver = this; return x + y |
| 1081 }) |
| 1082 |
| 1083 TestCall(false, Proxy.createFunction({}, function(x, y) { |
| 1084 receiver = this; return x + y |
| 1085 })) |
| 1086 |
| 1087 TestCall(true, Proxy.createFunction({}, function(x, y) { |
| 1088 "use strict"; |
| 1089 receiver = this; return x + y |
| 1090 })) |
| 1091 |
| 1092 var p = Proxy.createFunction({fix: function() {return {}}}, function(x, y) { |
| 1093 receiver = this; return x + y |
| 1094 }) |
| 1095 TestCall(false, p) |
| 1096 Object.freeze(p) |
| 1097 TestCall(false, p) |
OLD | NEW |