1// Copyright 2011 the V8 project authors. All rights reserved. 2// 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 28// We change the stack size for the ARM64 simulator because at one point this 29// test enters an infinite recursion which goes through the runtime and we 30// overflow the system stack before the simulator stack. 31 32// Flags: --sim-stack-size=500 --allow-natives-syntax 33 34 35// Helper. 36 37function TestWithProxies(test, x, y, z) { 38 // Separate function for nicer stack traces. 39 TestWithObjectProxy(test, x, y, z); 40 TestWithFunctionProxy(test, x, y, z); 41} 42 43function TestWithObjectProxy(test, x, y, z) { 44 test((handler) => { return new Proxy({}, handler) }, x, y, z) 45 46} 47 48function TestWithFunctionProxy(test, x, y, z) { 49 test((handler) => { return new Proxy(() => {}, handler) }, x, y, z) 50} 51 52// --------------------------------------------------------------------------- 53// Getting property descriptors (Object.getOwnPropertyDescriptor). 54 55var key 56 57function TestGetOwnProperty(handler) { 58 TestWithProxies(TestGetOwnProperty2, handler) 59} 60 61function TestGetOwnProperty2(create, handler) { 62 var p = create(handler) 63 assertEquals(42, Object.getOwnPropertyDescriptor(p, "a").value) 64 assertEquals("a", key) 65 assertEquals(42, Object.getOwnPropertyDescriptor(p, 99).value) 66 assertEquals("99", key) 67} 68 69TestGetOwnProperty({ 70 getOwnPropertyDescriptor(target, k) { 71 key = k 72 return {value: 42, configurable: true} 73 } 74}) 75 76TestGetOwnProperty({ 77 getOwnPropertyDescriptor(target, k) { 78 return this.getOwnPropertyDescriptor2(k) 79 }, 80 getOwnPropertyDescriptor2(k) { 81 key = k 82 return {value: 42, configurable: true} 83 } 84}) 85 86TestGetOwnProperty({ 87 getOwnPropertyDescriptor(target, k) { 88 key = k 89 return {get value() { return 42 }, get configurable() { return true }} 90 } 91}) 92 93TestGetOwnProperty(new Proxy({}, { 94 get(target, pk, receiver) { 95 return function(t, k) { key = k; return {value: 42, configurable: true} } 96 } 97})) 98 99 100// --------------------------------------------------------------------------- 101function TestGetOwnPropertyThrow(handler) { 102 TestWithProxies(TestGetOwnPropertyThrow2, handler) 103} 104 105function TestGetOwnPropertyThrow2(create, handler) { 106 var p = create(handler) 107 assertThrowsEquals(() => Object.getOwnPropertyDescriptor(p, "a"), "myexn") 108 assertThrowsEquals(() => Object.getOwnPropertyDescriptor(p, 77), "myexn") 109} 110 111TestGetOwnPropertyThrow({ 112 getOwnPropertyDescriptor: function(k) { throw "myexn" } 113}) 114 115TestGetOwnPropertyThrow({ 116 getOwnPropertyDescriptor: function(k) { 117 return this.getOwnPropertyDescriptor2(k) 118 }, 119 getOwnPropertyDescriptor2: function(k) { throw "myexn" } 120}) 121 122TestGetOwnPropertyThrow({ 123 getOwnPropertyDescriptor: function(k) { 124 return {get value() { throw "myexn" }} 125 } 126}) 127 128TestGetOwnPropertyThrow(new Proxy({}, { 129 get: function(pr, pk) { 130 return function(k) { throw "myexn" } 131 } 132})) 133 134 135// --------------------------------------------------------------------------- 136// Getters (dot, brackets). 137 138var key 139 140function TestGet(handler) { 141 TestWithProxies(TestGet2, handler) 142} 143 144function TestGet2(create, handler) { 145 var p = create(handler) 146 assertEquals(42, p.a) 147 assertEquals("a", key) 148 assertEquals(42, p["b"]) 149 assertEquals("b", key) 150 assertEquals(42, p[99]) 151 assertEquals("99", key) 152 assertEquals(42, (function(n) { return p[n] })("c")) 153 assertEquals("c", key) 154 assertEquals(42, (function(n) { return p[n] })(101)) 155 assertEquals("101", key) 156 157 var o = Object.create(p, {x: {value: 88}}) 158 assertEquals(42, o.a) 159 assertEquals("a", key) 160 assertEquals(42, o["b"]) 161 assertEquals("b", key) 162 assertEquals(42, o[99]) 163 assertEquals("99", key) 164 assertEquals(88, o.x) 165 assertEquals(88, o["x"]) 166 assertEquals(42, (function(n) { return o[n] })("c")) 167 assertEquals("c", key) 168 assertEquals(42, (function(n) { return o[n] })(101)) 169 assertEquals("101", key) 170 assertEquals(88, (function(n) { return o[n] })("x")) 171} 172 173TestGet({ 174 get(t, k, r) { key = k; return 42 } 175}) 176 177TestGet({ 178 get(t, k, r) { return this.get2(r, k) }, 179 get2(r, k) { key = k; return 42 } 180}) 181 182TestGet(new Proxy({}, { 183 get(pt, pk, pr) { 184 return function(t, k, r) { key = k; return 42 } 185 } 186})) 187 188 189// --------------------------------------------------------------------------- 190function TestGetCall(handler) { 191 TestWithProxies(TestGetCall2, handler) 192} 193 194function TestGetCall2(create, handler) { 195 var p = create(handler) 196 assertEquals(55, p.f()) 197 assertEquals(55, p["f"]()) 198 assertEquals(55, p.f("unused", "arguments")) 199 assertEquals(55, p.f.call(p)) 200 assertEquals(55, p["f"].call(p)) 201 assertEquals(55, p[101].call(p)) 202 assertEquals(55, p.withargs(45, 5)) 203 assertEquals(55, p.withargs.call(p, 11, 22)) 204 assertEquals(55, (function(n) { return p[n]() })("f")) 205 assertEquals(55, (function(n) { return p[n].call(p) })("f")) 206 assertEquals(55, (function(n) { return p[n](15, 20) })("withargs")) 207 assertEquals(55, (function(n) { return p[n].call(p, 13, 21) })("withargs")) 208 assertEquals("6655", "66" + p) // calls p.toString 209 210 var o = Object.create(p, {g: {value: function(x) { return x + 88 }}}) 211 assertEquals(55, o.f()) 212 assertEquals(55, o["f"]()) 213 assertEquals(55, o.f("unused", "arguments")) 214 assertEquals(55, o.f.call(o)) 215 assertEquals(55, o.f.call(p)) 216 assertEquals(55, o["f"].call(p)) 217 assertEquals(55, o[101].call(p)) 218 assertEquals(55, o.withargs(45, 5)) 219 assertEquals(55, o.withargs.call(p, 11, 22)) 220 assertEquals(90, o.g(2)) 221 assertEquals(91, o.g.call(o, 3)) 222 assertEquals(92, o.g.call(p, 4)) 223 assertEquals(55, (function(n) { return o[n]() })("f")) 224 assertEquals(55, (function(n) { return o[n].call(o) })("f")) 225 assertEquals(55, (function(n) { return o[n](15, 20) })("withargs")) 226 assertEquals(55, (function(n) { return o[n].call(o, 13, 21) })("withargs")) 227 assertEquals(93, (function(n) { return o[n](5) })("g")) 228 assertEquals(94, (function(n) { return o[n].call(o, 6) })("g")) 229 assertEquals(95, (function(n) { return o[n].call(p, 7) })("g")) 230 assertEquals("6655", "66" + o) // calls o.toString 231} 232 233TestGetCall({ 234 get(t, k, r) { return () => { return 55 } } 235}) 236 237TestGetCall({ 238 get(t, k, r) { return this.get2(t, k, r) }, 239 get2(t, k, r) { return () => { return 55 } } 240}) 241 242TestGetCall({ 243 get(t, k, r) { 244 if (k == "gg") { 245 return () => { return 55 } 246 } else if (k == "withargs") { 247 return (n, m) => { return n + m * 2 } 248 } else { 249 return () => { return r.gg() } 250 } 251 } 252}) 253 254TestGetCall(new Proxy({}, { 255 get(pt, pk, pr) { 256 return (t, k, r) => { return () => { return 55 } } 257 } 258})) 259 260 261// --------------------------------------------------------------------------- 262function TestGetThrow(handler) { 263 TestWithProxies(TestGetThrow2, handler) 264} 265 266function TestGetThrow2(create, handler) { 267 var p = create(handler) 268 assertThrowsEquals(function(){ p.a }, "myexn") 269 assertThrowsEquals(function(){ p["b"] }, "myexn") 270 assertThrowsEquals(function(){ p[3] }, "myexn") 271 assertThrowsEquals(function(){ (function(n) { p[n] })("c") }, "myexn") 272 assertThrowsEquals(function(){ (function(n) { p[n] })(99) }, "myexn") 273 274 var o = Object.create(p, {x: {value: 88}, '4': {value: 89}}) 275 assertThrowsEquals(function(){ o.a }, "myexn") 276 assertThrowsEquals(function(){ o["b"] }, "myexn") 277 assertThrowsEquals(function(){ o[3] }, "myexn") 278 assertThrowsEquals(function(){ (function(n) { o[n] })("c") }, "myexn") 279 assertThrowsEquals(function(){ (function(n) { o[n] })(99) }, "myexn") 280} 281 282TestGetThrow({ 283 get(r, k) { throw "myexn" } 284}) 285 286TestGetThrow({ 287 get(r, k) { return this.get2(r, k) }, 288 get2(r, k) { throw "myexn" } 289}) 290 291TestGetThrow(new Proxy({}, { 292 get(pr, pk) { throw "myexn" } 293})) 294 295TestGetThrow(new Proxy({}, { 296 get(pr, pk) { 297 return function(r, k) { throw "myexn" } 298 } 299})) 300 301 302// --------------------------------------------------------------------------- 303// Setters. 304 305var key 306var val 307 308function TestSet(handler) { 309 TestWithProxies(TestSet2, handler) 310} 311 312function TestSet2(create, handler) { 313 var p = create(handler) 314 assertEquals(42, p.a = 42) 315 assertEquals("a", key) 316 assertEquals(42, val) 317 assertEquals(43, p["b"] = 43) 318 assertEquals("b", key) 319 assertEquals(43, val) 320 assertEquals(44, p[77] = 44) 321 assertEquals("77", key) 322 assertEquals(44, val) 323 324 assertEquals(45, (function(n) { return p[n] = 45 })("c")) 325 assertEquals("c", key) 326 assertEquals(45, val) 327 assertEquals(46, (function(n) { return p[n] = 46 })(99)) 328 assertEquals("99", key) 329 assertEquals(46, val) 330 331 assertEquals(47, p["0"] = 47) 332 assertEquals("0", key) 333 assertEquals(47, val) 334} 335 336TestSet({ 337 set: function(r, k, v) { key = k; val = v; return true } 338}) 339 340TestSet({ 341 set: function(r, k, v) { return this.set2(r, k, v) }, 342 set2: function(r, k, v) { key = k; val = v; return true } 343}) 344 345TestSet(new Proxy({}, { 346 get(pk, pr) { 347 return (r, k, v) => { key = k; val = v; return true } 348 } 349})) 350 351 352// --------------------------------------------------------------------------- 353function TestSetThrow(handler) { 354 TestWithProxies(TestSetThrow2, handler) 355} 356 357function TestSetThrow2(create, handler) { 358 var p = create(handler) 359 assertThrowsEquals(function(){ p.a = 42 }, "myexn") 360 assertThrowsEquals(function(){ p["b"] = 42 }, "myexn") 361 assertThrowsEquals(function(){ p[22] = 42 }, "myexn") 362 assertThrowsEquals(function(){ (function(n) { p[n] = 45 })("c") }, "myexn") 363 assertThrowsEquals(function(){ (function(n) { p[n] = 46 })(99) }, "myexn") 364} 365 366TestSetThrow({ 367 set: function(r, k, v) { throw "myexn" } 368}) 369 370TestSetThrow({ 371 set: function(r, k, v) { return this.set2(r, k, v) }, 372 set2: function(r, k, v) { throw "myexn" } 373}) 374 375TestSetThrow({ 376 getOwnPropertyDescriptor: function(k) { throw "myexn" }, 377 defineProperty: function(k, desc) { key = k; val = desc.value } 378}) 379 380TestSetThrow({ 381 getOwnPropertyDescriptor: function(k) { 382 return {configurable: true, writable: true} 383 }, 384 defineProperty: function(k, desc) { throw "myexn" } 385}) 386 387TestSetThrow({ 388 getOwnPropertyDescriptor: function(k) { 389 return this.getOwnPropertyDescriptor2(k) 390 }, 391 getOwnPropertyDescriptor2: function(k) { throw "myexn" }, 392 defineProperty: function(k, desc) { this.defineProperty2(k, desc) }, 393 defineProperty2: function(k, desc) { key = k; val = desc.value } 394}) 395 396TestSetThrow({ 397 getOwnPropertyDescriptor: function(k) { 398 return this.getOwnPropertyDescriptor2(k) 399 }, 400 getOwnPropertyDescriptor2: function(k) { 401 return {configurable: true, writable: true} 402 }, 403 defineProperty: function(k, desc) { this.defineProperty2(k, desc) }, 404 defineProperty2: function(k, desc) { throw "myexn" } 405}) 406 407TestSetThrow({ 408 getOwnPropertyDescriptor: function(k) { throw "myexn" }, 409 defineProperty: function(k, desc) { key = k; val = desc.value } 410}) 411 412TestSetThrow({ 413 getOwnPropertyDescriptor: function(k) { 414 return { 415 get configurable() { return true }, 416 get writable() { return true } 417 } 418 }, 419 defineProperty: function(k, desc) { throw "myexn" } 420}) 421 422TestSetThrow({ 423 getOwnPropertyDescriptor: function(k) { throw "myexn" } 424}) 425 426TestSetThrow({ 427 getOwnPropertyDescriptor: function(k) { throw "myexn" }, 428 defineProperty: function(k, desc) { key = k; val = desc.value } 429}) 430 431TestSetThrow(new Proxy({}, { 432 get: function(pr, pk) { throw "myexn" } 433})) 434 435TestSetThrow(new Proxy({}, { 436 get: function(pr, pk) { 437 return function(r, k, v) { throw "myexn" } 438 } 439})) 440 441// --------------------------------------------------------------------------- 442 443// Evil proxy-induced side-effects shouldn't crash. 444TestWithProxies(function(create) { 445 var calls = 0 446 var handler = { 447 getPropertyDescriptor: function() { 448 ++calls 449 return (calls % 2 == 1) 450 ? {get: function() { return 5 }, configurable: true} 451 : {set: function() { return false }, configurable: true} 452 } 453 } 454 var p = create(handler) 455 var o = Object.create(p) 456 // Make proxy prototype property read-only after CanPut check. 457 try { o.x = 4 } catch (e) { assertInstanceof(e, Error) } 458}) 459 460TestWithProxies(function(create) { 461 var handler = { 462 getPropertyDescriptor: function() { 463 Object.defineProperty(o, "x", {get: function() { return 5 }}); 464 return {set: function() {}} 465 } 466 } 467 var p = create(handler) 468 var o = Object.create(p) 469 // Make object property read-only after CanPut check. 470 try { o.x = 4 } catch (e) { assertInstanceof(e, Error) } 471}) 472 473 474// --------------------------------------------------------------------------- 475// Property definition (Object.defineProperty and Object.defineProperties). 476 477var key 478var desc 479 480function TestDefine(handler) { 481 TestWithProxies(TestDefine2, handler) 482} 483 484function TestDefine2(create, handler) { 485 var p = create(handler) 486 assertEquals(p, Object.defineProperty(p, "a", {value: 44})) 487 assertEquals("a", key) 488 assertEquals(1, Object.getOwnPropertyNames(desc).length) 489 assertEquals(44, desc.value) 490 491 assertEquals(p, Object.defineProperty(p, "b", {value: 45, writable: false})) 492 assertEquals("b", key) 493 assertEquals(2, Object.getOwnPropertyNames(desc).length) 494 assertEquals(45, desc.value) 495 assertEquals(false, desc.writable) 496 497 assertEquals(p, Object.defineProperty(p, "c", {value: 46, enumerable: false})) 498 assertEquals("c", key) 499 assertEquals(2, Object.getOwnPropertyNames(desc).length) 500 assertEquals(46, desc.value) 501 assertEquals(false, desc.enumerable) 502 503 assertEquals(p, Object.defineProperty(p, 101, {value: 47, enumerable: false})) 504 assertEquals("101", key) 505 assertEquals(2, Object.getOwnPropertyNames(desc).length) 506 assertEquals(47, desc.value) 507 assertEquals(false, desc.enumerable) 508 509 var attributes = {configurable: true, mine: 66, minetoo: 23} 510 assertEquals(p, Object.defineProperty(p, "d", attributes)) 511 assertEquals("d", key); 512 // Modifying the attributes object after the fact should have no effect. 513 attributes.configurable = false 514 attributes.mine = 77 515 delete attributes.minetoo; 516 assertEquals(1, Object.getOwnPropertyNames(desc).length) 517 assertEquals(true, desc.configurable) 518 assertEquals(undefined, desc.mine) 519 assertEquals(undefined, desc.minetoo) 520 521 assertEquals(p, Object.defineProperty(p, "e", {get: function(){ return 5 }})) 522 assertEquals("e", key) 523 assertEquals(1, Object.getOwnPropertyNames(desc).length) 524 assertEquals(5, desc.get()) 525 526 assertEquals(p, Object.defineProperty(p, "zzz", {})) 527 assertEquals("zzz", key) 528 assertEquals(0, Object.getOwnPropertyNames(desc).length) 529 530 var props = { 531 '11': {}, 532 blub: {get: function() { return true }}, 533 '': {get value() { return 20 }}, 534 last: {value: 21, configurable: true, mine: "eyes"} 535 } 536 Object.defineProperty(props, "hidden", {value: "hidden", enumerable: false}) 537 assertEquals(p, Object.defineProperties(p, props)) 538 assertEquals("last", key) 539 assertEquals(2, Object.getOwnPropertyNames(desc).length) 540 assertEquals(21, desc.value) 541 assertEquals(true, desc.configurable) 542 assertEquals(undefined, desc.mine) // Arguably a bug in the spec... 543 544 var props = {bla: {get value() { throw "myexn" }}} 545 assertThrowsEquals(function(){ Object.defineProperties(p, props) }, "myexn") 546} 547 548TestDefine({ 549 defineProperty(t, k, d) { key = k; desc = d; return true } 550}) 551 552TestDefine({ 553 defineProperty(t, k, d) { return this.defineProperty2(k, d) }, 554 defineProperty2(k, d) { key = k; desc = d; return true } 555}) 556 557 558// --------------------------------------------------------------------------- 559function TestDefineThrow(handler) { 560 TestWithProxies(TestDefineThrow2, handler) 561} 562 563function TestDefineThrow2(create, handler) { 564 var p = create(handler) 565 assertThrowsEquals(() => Object.defineProperty(p, "a", {value: 44}), "myexn") 566 assertThrowsEquals(() => Object.defineProperty(p, 0, {value: 44}), "myexn") 567 568 var d1 = create({ 569 get: function(r, k) { throw "myexn" }, 570 getOwnPropertyNames: function() { return ["value"] } 571 }) 572 assertThrowsEquals(function(){ Object.defineProperty(p, "p", d1) }, "myexn") 573 var d2 = create({ 574 get: function(r, k) { return 77 }, 575 getOwnPropertyNames: function() { throw "myexn" } 576 }) 577 assertThrowsEquals(function(){ Object.defineProperty(p, "p", d2) }, "myexn") 578 579 var props = {bla: {get value() { throw "otherexn" }}} 580 assertThrowsEquals(() => Object.defineProperties(p, props), "otherexn") 581} 582 583TestDefineThrow({ 584 defineProperty: function(k, d) { throw "myexn" } 585}) 586 587TestDefineThrow({ 588 defineProperty: function(k, d) { return this.defineProperty2(k, d) }, 589 defineProperty2: function(k, d) { throw "myexn" } 590}) 591 592TestDefineThrow(new Proxy({}, { 593 get: function(pr, pk) { throw "myexn" } 594})) 595 596TestDefineThrow(new Proxy({}, { 597 get: function(pr, pk) { 598 return function(k, d) { throw "myexn" } 599 } 600})) 601 602 603 604// --------------------------------------------------------------------------- 605// Property deletion (delete). 606 607var key 608 609function TestDelete(handler) { 610 TestWithProxies(TestDelete2, handler) 611} 612 613function TestDelete2(create, handler) { 614 var p = create(handler) 615 assertEquals(true, delete p.a) 616 assertEquals("a", key) 617 assertEquals(true, delete p["b"]) 618 assertEquals("b", key) 619 assertEquals(true, delete p[1]) 620 assertEquals("1", key) 621 622 assertEquals(false, delete p.z1) 623 assertEquals("z1", key) 624 assertEquals(false, delete p["z2"]) 625 assertEquals("z2", key); 626 627 (function() { 628 "use strict" 629 assertEquals(true, delete p.c) 630 assertEquals("c", key) 631 assertEquals(true, delete p["d"]) 632 assertEquals("d", key) 633 assertEquals(true, delete p[2]) 634 assertEquals("2", key) 635 636 assertThrows(function(){ delete p.z3 }, TypeError) 637 assertEquals("z3", key) 638 assertThrows(function(){ delete p["z4"] }, TypeError) 639 assertEquals("z4", key) 640 })() 641} 642 643TestDelete({ 644 deleteProperty(target, k) { key = k; return k < "z" } 645}) 646 647TestDelete({ 648 deleteProperty(target, k) { return this.delete2(k) }, 649 delete2: function(k) { key = k; return k < "z" } 650}) 651 652TestDelete(new Proxy({}, { 653 get(pt, pk, pr) { 654 return (target, k) => { key = k; return k < "z" } 655 } 656})) 657 658 659// --------------------------------------------------------------------------- 660function TestDeleteThrow(handler) { 661 TestWithProxies(TestDeleteThrow2, handler) 662} 663 664function TestDeleteThrow2(create, handler) { 665 var p = create(handler) 666 assertThrowsEquals(function(){ delete p.a }, "myexn") 667 assertThrowsEquals(function(){ delete p["b"] }, "myexn"); 668 assertThrowsEquals(function(){ delete p[3] }, "myexn"); 669 670 (function() { 671 "use strict" 672 assertThrowsEquals(function(){ delete p.c }, "myexn") 673 assertThrowsEquals(function(){ delete p["d"] }, "myexn") 674 assertThrowsEquals(function(){ delete p[4] }, "myexn"); 675 })() 676} 677 678TestDeleteThrow({ 679 deleteProperty(t, k) { throw "myexn" } 680}) 681 682TestDeleteThrow({ 683 deleteProperty(t, k) { return this.delete2(k) }, 684 delete2(k) { throw "myexn" } 685}) 686 687TestDeleteThrow(new Proxy({}, { 688 get(pt, pk, pr) { throw "myexn" } 689})) 690 691TestDeleteThrow(new Proxy({}, { 692 get(pt, pk, pr) { 693 return (k) => { throw "myexn" } 694 } 695})) 696 697 698// --------------------------------------------------------------------------- 699// Property descriptors (Object.getOwnPropertyDescriptor). 700 701function TestDescriptor(handler) { 702 TestWithProxies(TestDescriptor2, handler) 703} 704 705function TestDescriptor2(create, handler) { 706 var p = create(handler) 707 var descs = [ 708 {configurable: true}, 709 {value: 34, enumerable: true, configurable: true}, 710 {value: 3, writable: false, mine: "eyes", configurable: true}, 711 {get value() { return 20 }, get configurable() { return true }}, 712 {get: function() { "get" }, set: function() { "set" }, configurable: true} 713 ] 714 for (var i = 0; i < descs.length; ++i) { 715 assertEquals(p, Object.defineProperty(p, i, descs[i])) 716 var desc = Object.getOwnPropertyDescriptor(p, i) 717 for (prop in descs[i]) { 718 // TODO(rossberg): Ignore user attributes as long as the spec isn't 719 // fixed suitably. 720 if (prop != "mine") assertEquals(descs[i][prop], desc[prop]) 721 } 722 assertEquals(undefined, Object.getOwnPropertyDescriptor(p, "absent")) 723 } 724} 725 726TestDescriptor({ 727 defineProperty(t, k, d) { this["__" + k] = d; return true }, 728 getOwnPropertyDescriptor(t, k) { return this["__" + k] } 729}) 730 731TestDescriptor({ 732 defineProperty(t, k, d) { this["__" + k] = d; return true }, 733 getOwnPropertyDescriptor(t, k) { 734 return this.getOwnPropertyDescriptor2(k) 735 }, 736 getOwnPropertyDescriptor2: function(k) { return this["__" + k] } 737}) 738 739 740// --------------------------------------------------------------------------- 741function TestDescriptorThrow(handler) { 742 TestWithProxies(TestDescriptorThrow2, handler) 743} 744 745function TestDescriptorThrow2(create, handler) { 746 var p = create(handler) 747 assertThrowsEquals(() => Object.getOwnPropertyDescriptor(p, "a"), "myexn") 748} 749 750TestDescriptorThrow({ 751 getOwnPropertyDescriptor: function(k) { throw "myexn" } 752}) 753 754TestDescriptorThrow({ 755 getOwnPropertyDescriptor: function(k) { 756 return this.getOwnPropertyDescriptor2(k) 757 }, 758 getOwnPropertyDescriptor2: function(k) { throw "myexn" } 759}) 760 761 762 763// --------------------------------------------------------------------------- 764// Comparison. 765 766function TestComparison(eq) { 767 TestWithProxies(TestComparison2, eq) 768} 769 770function TestComparison2(create, eq) { 771 var p1 = create({}) 772 var p2 = create({}) 773 774 assertTrue(eq(p1, p1)) 775 assertTrue(eq(p2, p2)) 776 assertTrue(!eq(p1, p2)) 777 assertTrue(!eq(p1, {})) 778 assertTrue(!eq({}, p2)) 779 assertTrue(!eq({}, {})) 780} 781 782TestComparison(function(o1, o2) { return o1 == o2 }) 783TestComparison(function(o1, o2) { return o1 === o2 }) 784TestComparison(function(o1, o2) { return !(o1 != o2) }) 785TestComparison(function(o1, o2) { return !(o1 !== o2) }) 786 787 788 789// Type (typeof). 790 791function TestTypeof() { 792 assertEquals("object", typeof new Proxy({},{})) 793 assertTrue(typeof new Proxy({}, {}) == "object") 794 assertTrue("object" == typeof new Proxy({},{})) 795 796 assertEquals("function", typeof new Proxy(function() {}, {})) 797 assertTrue(typeof new Proxy(function() {}, {}) == "function") 798 assertTrue("function" == typeof new Proxy(function() {},{})) 799} 800 801TestTypeof() 802 803 804 805// --------------------------------------------------------------------------- 806// Membership test (in). 807 808var key 809 810function TestIn(handler) { 811 TestWithProxies(TestIn2, handler) 812} 813 814function TestIn2(create, handler) { 815 var p = create(handler) 816 assertTrue("a" in p) 817 assertEquals("a", key) 818 assertTrue(99 in p) 819 assertEquals("99", key) 820 assertFalse("z" in p) 821 assertEquals("z", key) 822 823 assertEquals(2, ("a" in p) ? 2 : 0) 824 assertEquals(0, !("a" in p) ? 2 : 0) 825 assertEquals(0, ("zzz" in p) ? 2 : 0) 826 assertEquals(2, !("zzz" in p) ? 2 : 0) 827 828 // Test compilation in conditionals. 829 if ("b" in p) { 830 } else { 831 assertTrue(false) 832 } 833 assertEquals("b", key) 834 835 if ("zz" in p) { 836 assertTrue(false) 837 } 838 assertEquals("zz", key) 839 840 if (!("c" in p)) { 841 assertTrue(false) 842 } 843 assertEquals("c", key) 844 845 if (!("zzz" in p)) { 846 } else { 847 assertTrue(false) 848 } 849 assertEquals("zzz", key) 850} 851 852TestIn({ 853 has(t, k) { key = k; return k < "z" } 854}) 855 856TestIn({ 857 has(t, k) { return this.has2(k) }, 858 has2(k) { key = k; return k < "z" } 859}) 860 861TestIn(new Proxy({},{ 862 get(pt, pk, pr) { 863 return (t, k) => { key = k; return k < "z" } 864 } 865})) 866 867 868// --------------------------------------------------------------------------- 869function TestInThrow(handler) { 870 TestWithProxies(TestInThrow2, handler) 871} 872 873function TestInThrow2(create, handler) { 874 var p = create(handler) 875 assertThrowsEquals(function(){ return "a" in p }, "myexn") 876 assertThrowsEquals(function(){ return 99 in p }, "myexn") 877 assertThrowsEquals(function(){ return !("a" in p) }, "myexn") 878 assertThrowsEquals(function(){ return ("a" in p) ? 2 : 3 }, "myexn") 879 assertThrowsEquals(function(){ if ("b" in p) {} }, "myexn") 880 assertThrowsEquals(function(){ if (!("b" in p)) {} }, "myexn") 881 assertThrowsEquals(function(){ if ("zzz" in p) {} }, "myexn") 882} 883 884TestInThrow({ 885 has: function(k) { throw "myexn" } 886}) 887 888TestInThrow({ 889 has: function(k) { return this.has2(k) }, 890 has2: function(k) { throw "myexn" } 891}) 892 893TestInThrow(new Proxy({},{ 894 get: function(pr, pk) { throw "myexn" } 895})) 896 897TestInThrow(new Proxy({},{ 898 get: function(pr, pk) { 899 return function(k) { throw "myexn" } 900 } 901})) 902 903 904 905// --------------------------------------------------------------------------- 906// Own Properties (Object.prototype.hasOwnProperty). 907 908var key 909 910function TestHasOwn(handler) { 911 TestWithProxies(TestHasOwn2, handler) 912} 913 914function TestHasOwn2(create, handler) { 915 var p = create(handler) 916 assertTrue(Object.prototype.hasOwnProperty.call(p, "a")) 917 assertEquals("a", key) 918 assertTrue(Object.prototype.hasOwnProperty.call(p, 99)) 919 assertEquals("99", key) 920 assertFalse(Object.prototype.hasOwnProperty.call(p, "z")) 921 assertEquals("z", key) 922} 923 924TestHasOwn({ 925 getOwnPropertyDescriptor(t, k) { 926 key = k; if (k < "z") return {configurable: true} 927 }, 928 has() { assertUnreachable() } 929}) 930 931TestHasOwn({ 932 getOwnPropertyDescriptor(t, k) { return this.getOwnPropertyDescriptor2(k) }, 933 getOwnPropertyDescriptor2(k) { 934 key = k; if (k < "z") return {configurable: true} 935 } 936}) 937 938 939 940// --------------------------------------------------------------------------- 941function TestHasOwnThrow(handler) { 942 TestWithProxies(TestHasOwnThrow2, handler) 943} 944 945function TestHasOwnThrow2(create, handler) { 946 var p = create(handler) 947 assertThrowsEquals(function(){ Object.prototype.hasOwnProperty.call(p, "a")}, 948 "myexn") 949 assertThrowsEquals(function(){ Object.prototype.hasOwnProperty.call(p, 99)}, 950 "myexn") 951} 952 953TestHasOwnThrow({ 954 getOwnPropertyDescriptor(t, k) { throw "myexn" } 955}) 956 957TestHasOwnThrow({ 958 getOwnPropertyDescriptor(t, k) { return this.getOwnPropertyDescriptor2(k) }, 959 getOwnPropertyDescriptor2(k) { throw "myexn" } 960}); 961 962 963// --------------------------------------------------------------------------- 964// Instanceof (instanceof) 965 966(function TestProxyInstanceof() { 967 var o1 = {} 968 var p1 = new Proxy({}, {}) 969 var p2 = new Proxy(o1, {}) 970 var p3 = new Proxy(p2, {}) 971 var o2 = Object.create(p2) 972 973 var f0 = function() {} 974 f0.prototype = o1 975 var f1 = function() {} 976 f1.prototype = p1 977 var f2 = function() {} 978 f2.prototype = p2 979 var f3 = function() {} 980 f3.prototype = o2 981 982 assertTrue(o1 instanceof Object) 983 assertFalse(o1 instanceof f0) 984 assertFalse(o1 instanceof f1) 985 assertFalse(o1 instanceof f2) 986 assertFalse(o1 instanceof f3) 987 assertTrue(p1 instanceof Object) 988 assertFalse(p1 instanceof f0) 989 assertFalse(p1 instanceof f1) 990 assertFalse(p1 instanceof f2) 991 assertFalse(p1 instanceof f3) 992 assertTrue(p2 instanceof Object) 993 assertFalse(p2 instanceof f0) 994 assertFalse(p2 instanceof f1) 995 assertFalse(p2 instanceof f2) 996 assertFalse(p2 instanceof f3) 997 assertTrue(p3 instanceof Object) 998 assertFalse(p3 instanceof f0) 999 assertFalse(p3 instanceof f1) 1000 assertFalse(p3 instanceof f2) 1001 assertFalse(p3 instanceof f3) 1002 assertTrue(o2 instanceof Object) 1003 assertFalse(o2 instanceof f0) 1004 assertFalse(o2 instanceof f1) 1005 assertTrue(o2 instanceof f2) 1006 assertFalse(o2 instanceof f3) 1007 1008 var f = new Proxy(function() {}, {}) 1009 assertTrue(f instanceof Function) 1010})(); 1011 1012 1013(function TestInstanceofProxy() { 1014 var o0 = Object.create(null) 1015 var o1 = {} 1016 var o2 = Object.create(o0) 1017 var o3 = Object.create(o1) 1018 var o4 = Object.create(o2) 1019 var o5 = Object.create(o3) 1020 1021 function handler(o) { 1022 return { 1023 get: function(r, p) { 1024 // We want to test prototype lookup, so ensure the proxy 1025 // offers OrdinaryHasInstance behavior. 1026 if (p === Symbol.hasInstance) { 1027 return undefined; 1028 } 1029 return o; 1030 } 1031 } 1032 } 1033 1034 var f0 = new Proxy(function() {}, handler(o0)) 1035 var f1 = new Proxy(function() {}, handler(o1)) 1036 var f2 = new Proxy(function() {}, handler(o2)) 1037 var f3 = new Proxy(function() {}, handler(o3)) 1038 var f4 = new Proxy(function() {}, handler(o4)) 1039 var f5 = new Proxy(function() {}, handler(o4)) 1040 1041 assertFalse(null instanceof f0) 1042 assertFalse(o0 instanceof f0) 1043 assertFalse(o0 instanceof f1) 1044 assertFalse(o0 instanceof f2) 1045 assertFalse(o0 instanceof f3) 1046 assertFalse(o0 instanceof f4) 1047 assertFalse(o0 instanceof f5) 1048 assertFalse(o1 instanceof f0) 1049 assertFalse(o1 instanceof f1) 1050 assertFalse(o1 instanceof f2) 1051 assertFalse(o1 instanceof f3) 1052 assertFalse(o1 instanceof f4) 1053 assertFalse(o1 instanceof f5) 1054 assertTrue(o2 instanceof f0) 1055 assertFalse(o2 instanceof f1) 1056 assertFalse(o2 instanceof f2) 1057 assertFalse(o2 instanceof f3) 1058 assertFalse(o2 instanceof f4) 1059 assertFalse(o2 instanceof f5) 1060 assertFalse(o3 instanceof f0) 1061 assertTrue(o3 instanceof f1) 1062 assertFalse(o3 instanceof f2) 1063 assertFalse(o3 instanceof f3) 1064 assertFalse(o3 instanceof f4) 1065 assertFalse(o3 instanceof f5) 1066 assertTrue(o4 instanceof f0) 1067 assertFalse(o4 instanceof f1) 1068 assertTrue(o4 instanceof f2) 1069 assertFalse(o4 instanceof f3) 1070 assertFalse(o4 instanceof f4) 1071 assertFalse(o4 instanceof f5) 1072 assertFalse(o5 instanceof f0) 1073 assertTrue(o5 instanceof f1) 1074 assertFalse(o5 instanceof f2) 1075 assertTrue(o5 instanceof f3) 1076 assertFalse(o5 instanceof f4) 1077 assertFalse(o5 instanceof f5) 1078 1079 var f = new Proxy(function() {}, {}) 1080 var ff = new Proxy(function() {}, handler(Function)) 1081 assertTrue(f instanceof Function) 1082 assertFalse(f instanceof ff) 1083})(); 1084 1085 1086// --------------------------------------------------------------------------- 1087// Prototype (Object.getPrototypeOf, Object.prototype.isPrototypeOf). 1088 1089(function TestPrototype() { 1090 var o1 = {} 1091 var p1 = new Proxy({}, {}) 1092 var p2 = new Proxy(o1, {}) 1093 var p3 = new Proxy(p2, {}) 1094 var o2 = Object.create(p3) 1095 1096 assertSame(Object.getPrototypeOf(o1), Object.prototype) 1097 assertSame(Object.getPrototypeOf(p1), Object.prototype) 1098 assertSame(Object.getPrototypeOf(p2), Object.prototype) 1099 assertSame(Object.getPrototypeOf(p3), Object.prototype) 1100 assertSame(Object.getPrototypeOf(o2), p3) 1101 1102 assertTrue(Object.prototype.isPrototypeOf(o1)) 1103 assertTrue(Object.prototype.isPrototypeOf(p1)) 1104 assertTrue(Object.prototype.isPrototypeOf(p2)) 1105 assertTrue(Object.prototype.isPrototypeOf(p3)) 1106 assertTrue(Object.prototype.isPrototypeOf(o2)) 1107 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o1)) 1108 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p1)) 1109 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p2)) 1110 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p3)) 1111 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o2)) 1112 assertFalse(Object.prototype.isPrototypeOf.call(o1, o1)) 1113 assertFalse(Object.prototype.isPrototypeOf.call(o1, p1)) 1114 assertFalse(Object.prototype.isPrototypeOf.call(o1, p2)) 1115 assertFalse(Object.prototype.isPrototypeOf.call(o1, p3)) 1116 assertFalse(Object.prototype.isPrototypeOf.call(o1, o2)) 1117 assertFalse(Object.prototype.isPrototypeOf.call(p1, p1)) 1118 assertFalse(Object.prototype.isPrototypeOf.call(p1, o1)) 1119 assertFalse(Object.prototype.isPrototypeOf.call(p1, p2)) 1120 assertFalse(Object.prototype.isPrototypeOf.call(p1, p3)) 1121 assertFalse(Object.prototype.isPrototypeOf.call(p1, o2)) 1122 assertFalse(Object.prototype.isPrototypeOf.call(p2, p1)) 1123 assertFalse(Object.prototype.isPrototypeOf.call(p2, p2)) 1124 assertFalse(Object.prototype.isPrototypeOf.call(p2, p3)) 1125 assertFalse(Object.prototype.isPrototypeOf.call(p2, o2)) 1126 assertFalse(Object.prototype.isPrototypeOf.call(p3, p2)) 1127 assertTrue(Object.prototype.isPrototypeOf.call(p3, o2)) 1128 assertFalse(Object.prototype.isPrototypeOf.call(o2, o1)) 1129 assertFalse(Object.prototype.isPrototypeOf.call(o2, p1)) 1130 assertFalse(Object.prototype.isPrototypeOf.call(o2, p2)) 1131 assertFalse(Object.prototype.isPrototypeOf.call(o2, p3)) 1132 assertFalse(Object.prototype.isPrototypeOf.call(o2, o2)) 1133 1134 var f = new Proxy(function() {}, {}) 1135 assertSame(Object.getPrototypeOf(f), Function.prototype) 1136 assertTrue(Object.prototype.isPrototypeOf(f)) 1137 assertTrue(Object.prototype.isPrototypeOf.call(Function.prototype, f)) 1138})(); 1139 1140 1141// --------------------------------------------------------------------------- 1142function TestPropertyNamesThrow(handler) { 1143 TestWithProxies(TestPropertyNamesThrow2, handler) 1144} 1145 1146function TestPropertyNamesThrow2(create, handler) { 1147 var p = create(handler) 1148 assertThrowsEquals(function(){ Object.getOwnPropertyNames(p) }, "myexn") 1149} 1150 1151TestPropertyNamesThrow({ 1152 ownKeys() { throw "myexn" } 1153}) 1154 1155TestPropertyNamesThrow({ 1156 ownKeys() { return this.getOwnPropertyNames2() }, 1157 getOwnPropertyNames2() { throw "myexn" } 1158}) 1159 1160// --------------------------------------------------------------------------- 1161 1162function TestKeys(names, handler) { 1163 var p = new Proxy({}, handler); 1164 assertArrayEquals(names, Object.keys(p)) 1165} 1166 1167TestKeys([], { 1168 ownKeys() { return [] } 1169}) 1170 1171TestKeys([], { 1172 ownKeys() { return ["a", "zz", " ", "0", "toString"] } 1173}) 1174 1175TestKeys(["a", "zz", " ", "0", "toString"], { 1176 ownKeys() { return ["a", "zz", " ", "0", "toString"] }, 1177 getOwnPropertyDescriptor(t, p) { 1178 return {configurable: true, enumerable: true} 1179 } 1180}) 1181 1182TestKeys([], { 1183 ownKeys() { return this.keys2() }, 1184 keys2() { return ["throw", "function "] } 1185}) 1186 1187TestKeys(["throw", "function "], { 1188 ownKeys() { return this.keys2() }, 1189 keys2() { return ["throw", "function "] }, 1190 getOwnPropertyDescriptor(t, p) { 1191 return {configurable: true, enumerable: true} 1192 } 1193}) 1194 1195TestKeys(["a", "0"], { 1196 ownKeys() { return ["a", "23", "zz", "", "0"] }, 1197 getOwnPropertyDescriptor(t, k) { 1198 return k == "" ? 1199 undefined : 1200 { configurable: true, enumerable: k.length == 1} 1201 } 1202}) 1203 1204TestKeys(["23", "zz", ""], { 1205 ownKeys() { return this.getOwnPropertyNames2() }, 1206 getOwnPropertyNames2() { return ["a", "23", "zz", "", "0"] }, 1207 getOwnPropertyDescriptor(t, k) { 1208 return this.getOwnPropertyDescriptor2(k) 1209 }, 1210 getOwnPropertyDescriptor2(k) { 1211 return {configurable: true, enumerable: k.length != 1 } 1212 } 1213}) 1214 1215TestKeys([], { 1216 get ownKeys() { 1217 return function() { return ["a", "b", "c"] } 1218 }, 1219 getOwnPropertyDescriptor: function(k) { return {configurable: true} } 1220}) 1221 1222 1223// --------------------------------------------------------------------------- 1224function TestKeysThrow(handler) { 1225 TestWithProxies(TestKeysThrow2, handler) 1226} 1227 1228function TestKeysThrow2(create, handler) { 1229 var p = create(handler); 1230 assertThrowsEquals(function(){ Object.keys(p) }, "myexn"); 1231} 1232 1233TestKeysThrow({ 1234 ownKeys() { throw "myexn" } 1235}) 1236 1237TestKeysThrow({ 1238 ownKeys() { return this.keys2() }, 1239 keys2() { throw "myexn" } 1240}) 1241 1242TestKeysThrow({ 1243 ownKeys() { return ['1'] }, 1244 getOwnPropertyDescriptor: function() { throw "myexn" }, 1245}) 1246 1247TestKeysThrow({ 1248 ownKeys() { return this.getOwnPropertyNames2() }, 1249 getOwnPropertyNames2() { return ['1', '2'] }, 1250 getOwnPropertyDescriptor(k) { 1251 return this.getOwnPropertyDescriptor2(k) 1252 }, 1253 getOwnPropertyDescriptor2(k) { throw "myexn" } 1254}) 1255 1256TestKeysThrow({ 1257 get ownKeys() { throw "myexn" } 1258}) 1259 1260TestKeysThrow({ 1261 get ownKeys() { 1262 return function() { throw "myexn" } 1263 }, 1264}) 1265 1266TestKeysThrow({ 1267 get ownKeys() { 1268 return function() { return ['1', '2'] } 1269 }, 1270 getOwnPropertyDescriptor(k) { throw "myexn" } 1271}) 1272 1273 1274 1275// --------------------------------------------------------------------------- 1276// String conversion (Object.prototype.toString, 1277// Object.prototype.toLocaleString, 1278// Function.prototype.toString) 1279 1280var key 1281 1282function TestToString(handler) { 1283 var p = new Proxy({}, handler) 1284 key = "" 1285 assertEquals("[object Object]", Object.prototype.toString.call(p)) 1286 assertEquals(Symbol.toStringTag, key) 1287 assertEquals("my_proxy", Object.prototype.toLocaleString.call(p)) 1288 assertEquals("toString", key) 1289 1290 var f = new Proxy(function() {}, handler) 1291 key = "" 1292 assertEquals("[object Function]", Object.prototype.toString.call(f)) 1293 assertEquals(Symbol.toStringTag, key) 1294 assertEquals("my_proxy", Object.prototype.toLocaleString.call(f)) 1295 assertEquals("toString", key) 1296 assertThrows(function(){ Function.prototype.toString.call(f) }) 1297 1298 var o = Object.create(p) 1299 key = "" 1300 assertEquals("[object Object]", Object.prototype.toString.call(o)) 1301 assertEquals(Symbol.toStringTag, key) 1302 assertEquals("my_proxy", Object.prototype.toLocaleString.call(o)) 1303 assertEquals("toString", key) 1304} 1305 1306TestToString({ 1307 get: function(r, k) { key = k; return function() { return "my_proxy" } } 1308}) 1309 1310TestToString({ 1311 get: function(r, k) { return this.get2(r, k) }, 1312 get2: function(r, k) { key = k; return function() { return "my_proxy" } } 1313}) 1314 1315TestToString(new Proxy({}, { 1316 get: function(pr, pk) { 1317 return function(r, k) { key = k; return function() { return "my_proxy" } } 1318 } 1319})) 1320 1321 1322function TestToStringThrow(handler) { 1323 var p = new Proxy({}, handler) 1324 assertThrowsEquals(() => Object.prototype.toString.call(p), "myexn") 1325 assertThrowsEquals(() => Object.prototype.toLocaleString.call(p), "myexn") 1326 1327 var f = new Proxy(function(){}, handler) 1328 assertThrowsEquals(() => Object.prototype.toString.call(f), "myexn") 1329 assertThrowsEquals(() => Object.prototype.toLocaleString.call(f), "myexn") 1330 1331 var o = Object.create(p) 1332 assertThrowsEquals(() => Object.prototype.toString.call(o), "myexn") 1333 assertThrowsEquals(() => Object.prototype.toLocaleString.call(o), "myexn") 1334} 1335 1336TestToStringThrow({ 1337 get: function(r, k) { throw "myexn" } 1338}) 1339 1340TestToStringThrow({ 1341 get: function(r, k) { return this.get2(r, k) }, 1342 get2: function(r, k) { throw "myexn" } 1343}) 1344 1345TestToStringThrow(new Proxy({}, { 1346 get: function(pr, pk) { throw "myexn" } 1347})) 1348 1349TestToStringThrow(new Proxy({}, { 1350 get: function(pr, pk) { 1351 return function(r, k) { throw "myexn" } 1352 } 1353})) 1354 1355 1356// --------------------------------------------------------------------------- 1357// Value conversion (Object.prototype.toValue) 1358 1359function TestValueOf(handler) { 1360 TestWithProxies(TestValueOf2, handler) 1361} 1362 1363function TestValueOf2(create, handler) { 1364 var p = create(handler) 1365 assertSame(p, Object.prototype.valueOf.call(p)) 1366} 1367 1368TestValueOf({}) 1369 1370 1371 1372// --------------------------------------------------------------------------- 1373// Enumerability (Object.prototype.propertyIsEnumerable) 1374 1375var key 1376 1377function TestIsEnumerable(handler) { 1378 TestWithProxies(TestIsEnumerable2, handler) 1379} 1380 1381function TestIsEnumerable2(create, handler) { 1382 var p = create(handler) 1383 assertTrue(Object.prototype.propertyIsEnumerable.call(p, "a")) 1384 assertEquals("a", key) 1385 assertTrue(Object.prototype.propertyIsEnumerable.call(p, 2)) 1386 assertEquals("2", key) 1387 assertFalse(Object.prototype.propertyIsEnumerable.call(p, "z")) 1388 assertEquals("z", key) 1389 1390 var o = Object.create(p) 1391 key = "" 1392 assertFalse(Object.prototype.propertyIsEnumerable.call(o, "a")) 1393 assertEquals("", key) // trap not invoked 1394} 1395 1396TestIsEnumerable({ 1397 getOwnPropertyDescriptor(t, k) { 1398 key = k; 1399 return {enumerable: k < "z", configurable: true} 1400 }, 1401}) 1402 1403TestIsEnumerable({ 1404 getOwnPropertyDescriptor: function(t, k) { 1405 return this.getOwnPropertyDescriptor2(k) 1406 }, 1407 getOwnPropertyDescriptor2: function(k) { 1408 key = k; 1409 return {enumerable: k < "z", configurable: true} 1410 }, 1411}) 1412 1413TestIsEnumerable({ 1414 getOwnPropertyDescriptor: function(t, k) { 1415 key = k; 1416 return {get enumerable() { return k < "z" }, configurable: true} 1417 }, 1418}) 1419 1420TestIsEnumerable(new Proxy({}, { 1421 get: function(pt, pk, pr) { 1422 return function(t, k) { 1423 key = k; 1424 return {enumerable: k < "z", configurable: true} 1425 } 1426 } 1427})) 1428 1429 1430// --------------------------------------------------------------------------- 1431function TestIsEnumerableThrow(handler) { 1432 TestWithProxies(TestIsEnumerableThrow2, handler) 1433} 1434 1435function TestIsEnumerableThrow2(create, handler) { 1436 var p = create(handler) 1437 assertThrowsEquals(() => Object.prototype.propertyIsEnumerable.call(p, "a"), 1438 "myexn") 1439 assertThrowsEquals(() => Object.prototype.propertyIsEnumerable.call(p, 11), 1440 "myexn") 1441} 1442 1443TestIsEnumerableThrow({ 1444 getOwnPropertyDescriptor: function(k) { throw "myexn" } 1445}) 1446 1447TestIsEnumerableThrow({ 1448 getOwnPropertyDescriptor: function(k) { 1449 return this.getOwnPropertyDescriptor2(k) 1450 }, 1451 getOwnPropertyDescriptor2: function(k) { throw "myexn" } 1452}) 1453 1454TestIsEnumerableThrow({ 1455 getOwnPropertyDescriptor: function(k) { 1456 return {get enumerable() { throw "myexn" }, configurable: true} 1457 }, 1458}) 1459 1460TestIsEnumerableThrow(new Proxy({}, { 1461 get: function(pr, pk) { throw "myexn" } 1462})) 1463 1464TestIsEnumerableThrow(new Proxy({}, { 1465 get: function(pr, pk) { 1466 return function(k) { throw "myexn" } 1467 } 1468})); 1469 1470 1471 1472// --------------------------------------------------------------------------- 1473// Constructor functions with proxy prototypes. 1474 1475(function TestConstructorWithProxyPrototype() { 1476 TestWithProxies(TestConstructorWithProxyPrototype2, {}) 1477})(); 1478 1479function TestConstructorWithProxyPrototype2(create, handler) { 1480 function C() {}; 1481 C.prototype = create(handler); 1482 1483 var o = new C; 1484 assertSame(C.prototype, Object.getPrototypeOf(o)); 1485}; 1486 1487 1488(function TestOptWithProxyPrototype() { 1489 var handler = { 1490 get(t, k) { 1491 return 10; 1492 } 1493 }; 1494 1495 function C() {}; 1496 C.prototype = new Proxy({}, handler); 1497 var o = new C(); 1498 1499 function f() { 1500 return o.x; 1501 } 1502 assertEquals(10, f()); 1503 assertEquals(10, f()); 1504 %OptimizeFunctionOnNextCall(f); 1505 assertEquals(10, f()); 1506})(); 1507