1// Copyright 2014 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Flags: --allow-natives-syntax 6 7(function TestSuperNamedLoads() { 8 function Base() { } 9 function fBase() { } 10 Base.prototype = { 11 f() { 12 return "Base " + this.toString(); 13 }, 14 x: 15, 15 toString() { 16 return "this is Base"; 17 } 18 }; 19 20 function Derived() { 21 this.derivedDataProperty = "xxx"; 22 } 23 Derived.prototype = { 24 __proto__: Base.prototype, 25 toString() { return "this is Derived"; }, 26 x: 27, 27 f() { 28 assertEquals("Base this is Derived", super.f()); 29 var a = super.x; 30 assertEquals(15, a); 31 assertEquals(15, super.x); 32 assertEquals(27, this.x); 33 return "Derived"; 34 } 35 }; 36 37 assertEquals("Base this is Base", new Base().f()); 38 assertEquals("Derived", new Derived().f()); 39}()); 40 41 42(function TestSuperKeyedLoads() { 43 'use strict'; 44 45 var x = 'x'; 46 var derivedDataProperty = 'derivedDataProperty'; 47 var f = 'f'; 48 49 class Base { 50 f() { 51 return "Base " + this.toString(); 52 } 53 toString() { 54 return "this is Base"; 55 } 56 } 57 58 Base.prototype[x] = 15; 59 60 function Derived() { 61 this[derivedDataProperty] = "xxx"; 62 } 63 Derived.prototype = { 64 __proto__: Base.prototype, 65 toString() { return "this is Derived"; }, 66 x: 27, 67 f() { 68 assertEquals("Base this is Derived", super[f]()); 69 var a = super[x]; 70 assertEquals(15, a); 71 assertEquals(15, super[x]); 72 assertEquals(27, this[x]); 73 return "Derived"; 74 } 75 }; 76 77 assertEquals("Base this is Base", new Base().f()); 78 assertEquals("Derived", new Derived().f()); 79}()); 80 81 82(function TestSuperKeywordNonMethod() { 83 'use strict'; 84 85 class C { 86 f() { 87 super.unknown(); 88 } 89 } 90 91 assertThrows(function() { 92 new C().f(); 93 }, TypeError); 94}()); 95 96 97(function TestGetter() { 98 function Base() {} 99 var derived; 100 Base.prototype = { 101 constructor: Base, 102 get x() { 103 assertSame(this, derived); 104 return this._x; 105 }, 106 _x: 'base' 107 }; 108 109 function Derived() {} 110 Derived.__proto__ = Base; 111 Derived.prototype = { 112 __proto__: Base.prototype, 113 constructor: Derived, 114 _x: 'derived', 115 testGetter() { 116 return super.x; 117 }, 118 testGetterStrict() { 119 'use strict'; 120 return super.x; 121 } 122 }; 123 124 derived = new Derived(); 125 assertEquals('derived', derived.testGetter()); 126 derived = new Derived(); 127 assertEquals('derived', derived.testGetterStrict()); 128}()); 129 130 131(function TestGetterKeyed() { 132 var x = 'x'; 133 function Base() {} 134 var derived; 135 Base.prototype = { 136 constructor: Base, 137 get x() { 138 assertSame(this, derived); 139 return this._x; 140 }, 141 _x: 'base' 142 }; 143 144 function Derived() {} 145 Derived.__proto__ = Base; 146 Derived.prototype = { 147 __proto__: Base.prototype, 148 constructor: Derived, 149 _x: 'derived', 150 testGetter() { 151 return super[x]; 152 }, 153 testGetterStrict() { 154 'use strict'; 155 return super[x]; 156 }, 157 testGetterWithToString() { 158 var toStringCalled; 159 var o = { toString: function() { 160 toStringCalled++; 161 return 'x'; 162 } }; 163 164 toStringCalled = 0; 165 assertEquals('derived', super[o]); 166 assertEquals(1, toStringCalled); 167 168 var eToThrow = new Error(); 169 var oThrowsInToString = { toString: function() { 170 throw eToThrow; 171 } }; 172 173 var ex = null; 174 try { 175 super[oThrowsInToString]; 176 } catch(e) { ex = e } 177 assertEquals(eToThrow, ex); 178 179 var oReturnsNumericString = { toString: function() { 180 return "1"; 181 } }; 182 183 assertEquals(undefined, super[oReturnsNumericString]); 184 assertEquals(undefined, super[1]); 185 } 186 }; 187 188 derived = new Derived(); 189 assertEquals('derived', derived.testGetter()); 190 derived = new Derived(); 191 assertEquals('derived', derived.testGetterStrict()); 192 derived = new Derived(); 193 derived.testGetterWithToString(); 194}()); 195 196 197(function TestGetterNumericKeyed() { 198 var x = 42; 199 function Base() {} 200 var derived; 201 Base.prototype = { 202 constructor: Base, 203 _x: 'base' 204 }; 205 206 Object.defineProperty(Base.prototype, x, { get: function() { 207 assertSame(this, derived); 208 return this._x; 209 }}); 210 211 function Derived() {} 212 Derived.__proto__ = Base; 213 Derived.prototype = { 214 __proto__: Base.prototype, 215 constructor: Derived, 216 _x: 'derived', 217 testGetter() { 218 return super[x]; 219 }, 220 testGetterStrict() { 221 'use strict'; 222 return super[x]; 223 }, 224 testGetterWithToString() { 225 var toStringCalled; 226 var o = { 227 toString: function() { 228 toStringCalled++; 229 return '42'; 230 } 231 }; 232 233 toStringCalled = 0; 234 assertEquals('derived', super[o]); 235 assertEquals(1, toStringCalled); 236 237 var eToThrow = new Error(); 238 var oThrowsInToString = { 239 toString: function() { 240 throw eToThrow; 241 } 242 }; 243 244 var ex = null; 245 try { 246 super[oThrowsInToString]; 247 } catch(e) { ex = e } 248 assertEquals(eToThrow, ex); 249 250 var oReturnsNumericString = { 251 toString: function() { 252 return "42"; 253 } 254 }; 255 256 assertEquals('derived', super[oReturnsNumericString]); 257 assertEquals('derived', super[42]); 258 } 259 }; 260 261 derived = new Derived(); 262 assertEquals('derived', derived.testGetter()); 263 derived = new Derived(); 264 assertEquals('derived', derived.testGetterStrict()); 265 derived = new Derived(); 266 derived.testGetterWithToString(); 267}()); 268 269 270(function TestSetter() { 271 function Base() {} 272 Base.prototype = { 273 constructor: Base, 274 get x() { 275 return this._x; 276 }, 277 set x(v) { 278 this._x = v; 279 }, 280 _x: 'base' 281 }; 282 283 function Derived() {} 284 Derived.__proto__ = Base; 285 Derived.prototype = { 286 __proto__: Base.prototype, 287 constructor: Derived, 288 _x: 'derived', 289 testSetter() { 290 assertEquals('foobar', super.x = 'foobar'); 291 assertEquals('foobarabc', super.x += 'abc'); 292 }, 293 testSetterStrict() { 294 'use strict'; 295 assertEquals('foobar', super.x = 'foobar'); 296 assertEquals('foobarabc', super.x += 'abc'); 297 } 298 }; 299 300 var d = new Derived(); 301 d.testSetter(); 302 assertEquals('base', Base.prototype._x); 303 assertEquals('foobarabc', d._x); 304 d._x = ''; 305 306 d.testSetterStrict(); 307 assertEquals('base', Base.prototype._x); 308 assertEquals('foobarabc', d._x); 309}()); 310 311 312(function TestSetterNumericKeyed() { 313 var x = 42; 314 function Base() {} 315 Base.prototype = { 316 constructor: Base, 317 _x: 'base' 318 }; 319 320 Object.defineProperty(Base.prototype, x, 321 { get: function() { return this._x; }, 322 set: function(v) { this._x = v; } 323 }); 324 325 function Derived() {} 326 Derived.__proto__ = Base; 327 Derived.prototype = { 328 __proto__: Base.prototype, 329 constructor: Derived, 330 _x: 'derived', 331 testSetter() { 332 assertEquals('foobar', super[x] = 'foobar'); 333 assertEquals('foobarabc', super[x] += 'abc'); 334 }, 335 testSetterStrict() { 336 'use strict'; 337 assertEquals('foobar', super[x] = 'foobar'); 338 assertEquals('foobarabc', super[x] += 'abc'); 339 }, 340 testSetterWithToString() { 341 var toStringCalled; 342 var o = { 343 toString: function() { 344 toStringCalled++; 345 return x; 346 } 347 }; 348 349 toStringCalled = 0; 350 super[o] = 'set'; 351 assertEquals(1, toStringCalled); 352 assertEquals('set', this._x); 353 354 var eToThrow = new Error(); 355 var oThrowsInToString = { 356 toString: function() { 357 throw eToThrow; 358 } 359 }; 360 361 var ex = null; 362 try { 363 super[oThrowsInToString] = 'xyz'; 364 } catch(e) { ex = e } 365 assertEquals(eToThrow, ex); 366 assertEquals('set', this._x); 367 } 368 }; 369 370 var d = new Derived(); 371 d.testSetter(); 372 assertEquals('base', Base.prototype._x); 373 assertEquals('foobarabc', d._x); 374 d._x = ''; 375 376 d.testSetterStrict(); 377 assertEquals('base', Base.prototype._x); 378 assertEquals('foobarabc', d._x); 379 380 d = new Derived(); 381 d.testSetterWithToString(); 382}()); 383 384 385(function TestSetterKeyed() { 386 var x = 'x'; 387 function Base() {} 388 Base.prototype = { 389 constructor: Base, 390 get x() { 391 return this._x; 392 }, 393 set x(v) { 394 this._x = v; 395 }, 396 _x: 'base' 397 }; 398 399 function Derived() {} 400 Derived.__proto__ = Base; 401 Derived.prototype = { 402 __proto__: Base.prototype, 403 constructor: Derived, 404 _x: 'derived', 405 testSetter() { 406 assertEquals('foobar', super[x] = 'foobar'); 407 assertEquals('foobarabc', super[x] += 'abc'); 408 }, 409 testSetterStrict() { 410 'use strict'; 411 assertEquals('foobar', super[x] = 'foobar'); 412 assertEquals('foobarabc', super[x] += 'abc'); 413 }, 414 testSetterWithToString() { 415 var toStringCalled; 416 var o = { 417 toString: function() { 418 toStringCalled++; 419 return 'x'; 420 } 421 }; 422 423 toStringCalled = 0; 424 super[o] = 'set'; 425 assertEquals(1, toStringCalled); 426 assertEquals('set', this._x); 427 428 var eToThrow = new Error(); 429 var oThrowsInToString = { 430 toString: function() { 431 throw eToThrow; 432 } 433 }; 434 435 var ex = null; 436 try { 437 super[oThrowsInToString] = 'xyz'; 438 } catch(e) { ex = e } 439 assertEquals(eToThrow, ex); 440 assertEquals('set', this._x); 441 442 var oReturnsNumericString = { 443 toString: function() { 444 return "1"; 445 } 446 }; 447 448 assertEquals('abc', super[oReturnsNumericString] = 'abc'); 449 450 assertEquals('set', this._x); 451 452 assertEquals(10, super[1] = 10); 453 } 454 }; 455 456 var d = new Derived(); 457 d.testSetter(); 458 assertEquals('base', Base.prototype._x); 459 assertEquals('foobarabc', d._x); 460 d._x = ''; 461 d.testSetterStrict(); 462 assertEquals('base', Base.prototype._x); 463 assertEquals('foobarabc', d._x); 464 465 d = new Derived(); 466 d.testSetterWithToString(); 467}()); 468 469 470(function TestSetterDataProperties() { 471 function Base() {} 472 Base.prototype = { 473 constructor: Base, 474 x: 'x from Base' 475 }; 476 477 function Derived() {} 478 Derived.prototype = { 479 __proto__: Base.prototype, 480 constructor: Derived, 481 testSetter() { 482 assertEquals('x from Base', super.x); 483 super.x = 'data property'; 484 assertEquals('x from Base', super.x); 485 assertEquals('data property', this.x); 486 } 487 }; 488 489 new Derived().testSetter(); 490}()); 491 492 493(function TestKeyedSetterDataProperties() { 494 var x = 'x'; 495 function Base() {} 496 Base.prototype = { 497 constructor: Base, 498 x: 'x from Base' 499 }; 500 501 function Derived() {} 502 Derived.prototype = { 503 __proto__: Base.prototype, 504 constructor: Derived, 505 testSetter() { 506 assertEquals('x from Base', super[x]); 507 super[x] = 'data property'; 508 assertEquals('x from Base', super[x]); 509 assertEquals('data property', this[x]); 510 } 511 }; 512 513 new Derived().testSetter(); 514}()); 515 516 517(function TestKeyedNumericSetterDataProperties() { 518 var x = 42; 519 function Base() {} 520 Base.prototype = { 521 constructor: Base, 522 42: 'x from Base' 523 }; 524 525 function Derived() {} 526 Derived.prototype = { 527 __proto__: Base.prototype, 528 constructor: Derived, 529 testSetter() { 530 assertEquals('x from Base', super[x]); 531 super[x] = 'data property'; 532 assertEquals('x from Base', super[x]); 533 assertEquals('data property', this[x]); 534 } 535 }; 536 537 new Derived().testSetter(); 538}()); 539 540 541(function TestAccessorsOnPrimitives() { 542 var getCalled = 0; 543 var setCalled = 0; 544 function Base() {} 545 Base.prototype = { 546 constructor: Base, 547 get x() { 548 getCalled++; 549 return 1; 550 }, 551 set x(v) { 552 setCalled++; 553 return v; 554 }, 555 }; 556 557 function Derived() {} 558 Derived.prototype = { 559 __proto__: Base.prototype, 560 constructor: Derived, 561 testSetter() { 562 setCalled = 0; 563 getCalled = 0; 564 assertEquals('object', typeof this); 565 assertInstanceof(this, Number) 566 assertEquals(42, this.valueOf()); 567 assertEquals(1, super.x); 568 assertEquals(1, getCalled); 569 assertEquals(0, setCalled); 570 571 assertEquals(5, super.x = 5); 572 assertEquals(1, getCalled); 573 assertEquals(1, setCalled); 574 575 assertEquals(6, super.x += 5); 576 assertEquals(2, getCalled); 577 assertEquals(2, setCalled); 578 579 super.newProperty = 15; 580 assertEquals(15, this.newProperty); 581 assertEquals(undefined, super.newProperty); 582 }, 583 testSetterStrict() { 584 'use strict'; 585 getCalled = 0; 586 setCalled = 0; 587 assertTrue(42 === this); 588 589 assertEquals(1, super.x); 590 assertEquals(1, getCalled); 591 assertEquals(0, setCalled); 592 593 assertEquals(5, super.x = 5); 594 assertEquals(1, getCalled); 595 assertEquals(1, setCalled); 596 597 assertEquals(6, super.x += 5); 598 assertEquals(2, getCalled); 599 assertEquals(2, setCalled); 600 601 var ex; 602 try { 603 super.newProperty = 15; 604 } catch (e) { ex = e; } 605 assertInstanceof(ex, TypeError); 606 } 607 } 608 609 Derived.prototype.testSetter.call(42); 610 Derived.prototype.testSetterStrict.call(42); 611 612 function DerivedFromString() {} 613 DerivedFromString.prototype = { 614 __proto__: String.prototype, 615 f() { 616 'use strict'; 617 assertTrue(42 === this); 618 assertEquals(String.prototype.toString, super.toString); 619 var ex; 620 try { 621 super.toString(); 622 } catch(e) { ex = e; } 623 624 assertInstanceof(ex, TypeError); 625 } 626 }; 627 628 DerivedFromString.prototype.f.call(42); 629}()); 630 631 632(function TestKeyedAccessorsOnPrimitives() { 633 var x = 'x'; 634 var newProperty = 'newProperty'; 635 var toString = 'toString'; 636 var getCalled = 0; 637 var setCalled = 0; 638 function Base() {} 639 Base.prototype = { 640 constructor: Base, 641 get x() { 642 getCalled++; 643 return 1; 644 }, 645 set x(v) { 646 setCalled++; 647 return v; 648 }, 649 }; 650 651 function Derived() {} 652 Derived.prototype = { 653 __proto__: Base.prototype, 654 constructor: Derived, 655 testSetter() { 656 setCalled = 0; 657 getCalled = 0; 658 assertEquals('object', typeof this); 659 assertInstanceof(this, Number) 660 assertEquals(42, this.valueOf()); 661 assertEquals(1, super[x]); 662 assertEquals(1, getCalled); 663 assertEquals(0, setCalled); 664 665 assertEquals(5, super[x] = 5); 666 assertEquals(1, getCalled); 667 assertEquals(1, setCalled); 668 669 assertEquals(6, super[x] += 5); 670 assertEquals(2, getCalled); 671 assertEquals(2, setCalled); 672 673 super[newProperty] = 15; 674 assertEquals(15, this[newProperty]); 675 assertEquals(undefined, super[newProperty]); 676 }, 677 testSetterStrict() { 678 'use strict'; 679 getCalled = 0; 680 setCalled = 0; 681 assertTrue(42 === this); 682 683 assertEquals(1, super[x]); 684 assertEquals(1, getCalled); 685 assertEquals(0, setCalled); 686 687 assertEquals(5, super[x] = 5); 688 assertEquals(1, getCalled); 689 assertEquals(1, setCalled); 690 691 assertEquals(6, super[x] += 5); 692 assertEquals(2, getCalled); 693 assertEquals(2, setCalled); 694 695 var ex; 696 try { 697 super[newProperty] = 15; 698 } catch (e) { ex = e; } 699 assertInstanceof(ex,TypeError); 700 } 701 }; 702 703 Derived.prototype.testSetter.call(42); 704 Derived.prototype.testSetterStrict.call(42); 705 706 function DerivedFromString() {} 707 DerivedFromString.prototype = { 708 __proto__: String.prototype, 709 f() { 710 'use strict'; 711 assertTrue(42 === this); 712 assertEquals(String.prototype.toString, super[toString]); 713 var ex; 714 try { 715 super[toString](); 716 } catch(e) { ex = e; } 717 718 assertInstanceof(ex, TypeError); 719 } 720 }; 721 DerivedFromString.prototype.f.call(42); 722}()); 723 724 725(function TestNumericKeyedAccessorsOnPrimitives() { 726 var x = 42; 727 var newProperty = 43; 728 var getCalled = 0; 729 var setCalled = 0; 730 function Base() {} 731 Base.prototype = { 732 constructor: Base, 733 }; 734 735 Object.defineProperty(Base.prototype, x, { 736 get: function() { 737 getCalled++; 738 return 1; 739 }, 740 set: function(v) { 741 setCalled++; 742 return v; 743 } 744 }); 745 746 function Derived() {} 747 Derived.prototype = { 748 __proto__: Base.prototype, 749 constructor: Derived, 750 testSetter() { 751 setCalled = 0; 752 getCalled = 0; 753 assertEquals('object', typeof this); 754 assertInstanceof(this, Number) 755 assertEquals(42, this.valueOf()); 756 assertEquals(1, super[x]); 757 assertEquals(1, getCalled); 758 assertEquals(0, setCalled); 759 760 assertEquals(5, super[x] = 5); 761 assertEquals(1, getCalled); 762 assertEquals(1, setCalled); 763 764 assertEquals(6, super[x] += 5); 765 assertEquals(2, getCalled); 766 assertEquals(2, setCalled); 767 768 super[newProperty] = 15; 769 assertEquals(15, this[newProperty]); 770 assertEquals(undefined, super[newProperty]); 771 }, 772 testSetterStrict() { 773 'use strict'; 774 getCalled = 0; 775 setCalled = 0; 776 assertTrue(42 === this); 777 778 assertEquals(1, super[x]); 779 assertEquals(1, getCalled); 780 assertEquals(0, setCalled); 781 782 assertEquals(5, super[x] = 5); 783 assertEquals(1, getCalled); 784 assertEquals(1, setCalled); 785 786 assertEquals(6, super[x] += 5); 787 assertEquals(2, getCalled); 788 assertEquals(2, setCalled); 789 790 var ex; 791 try { 792 super[newProperty] = 15; 793 } catch (e) { ex = e; } 794 assertInstanceof(ex, TypeError); 795 } 796 }; 797 798 Derived.prototype.testSetter.call(42); 799 Derived.prototype.testSetterStrict.call(42); 800}()); 801 802 803(function TestKeyedNumericSetterOnExotics() { 804 function Base() {} 805 function Derived() {} 806 Derived.prototype = { 807 __proto__: Base.prototype, 808 callSetterOnArray() { 809 super[42] = 1; 810 }, 811 callStrictSetterOnString() { 812 'use strict'; 813 assertEquals('string', typeof this); 814 assertTrue('abcdef' === this); 815 var ex = null; 816 try { 817 super[5] = 'q'; 818 } catch(e) { ex = e; } 819 assertInstanceof(ex, TypeError); 820 821 ex = null; 822 try { 823 super[1024] = 'q'; 824 } catch(e) { ex = e; } 825 assertInstanceof(ex, TypeError); 826 } 827 }; 828 829 var x = []; 830 assertEquals(0, x.length); 831 Derived.prototype.callSetterOnArray.call(x); 832 assertEquals(43, x.length); 833 assertEquals(1, x[42]); 834 835 var s = 'abcdef'; 836 Derived.prototype.callStrictSetterOnString.call(s) 837}()); 838 839 840(function TestSetterUndefinedProperties() { 841 function Base() {} 842 function Derived() {} 843 Derived.prototype = { 844 __proto__: Base.prototype, 845 mSloppy() { 846 assertEquals(undefined, super.x); 847 assertEquals(undefined, this.x); 848 super.x = 10; 849 assertEquals(10, this.x); 850 assertEquals(undefined, super.x); 851 }, 852 mStrict() { 853 'use strict'; 854 assertEquals(undefined, super.x); 855 assertEquals(undefined, this.x); 856 super.x = 10; 857 assertEquals(10, this.x); 858 assertEquals(undefined, super.x); 859 } 860 }; 861 862 var d = new Derived(); 863 d.mSloppy(); 864 assertEquals(10, d.x); 865 var d1 = new Derived(); 866 d1.mStrict(); 867 assertEquals(10, d.x); 868}()); 869 870 871(function TestKeyedSetterUndefinedProperties() { 872 var x = 'x'; 873 function Base() {} 874 function Derived() {} 875 Derived.prototype = { 876 __proto__: Base.prototype, 877 mSloppy() { 878 assertEquals(undefined, super[x]); 879 assertEquals(undefined, this[x]); 880 super[x] = 10; 881 assertEquals(10, this[x]); 882 assertEquals(undefined, super[x]); 883 }, 884 mStrict() { 885 'use strict'; 886 assertEquals(undefined, super[x]); 887 assertEquals(undefined, this[x]); 888 super[x] = 10; 889 assertEquals(10, this[x]); 890 assertEquals(undefined, super[x]); 891 } 892 }; 893 var d = new Derived(); 894 d.mSloppy(); 895 assertEquals(10, d.x); 896 var d1 = new Derived(); 897 d1.mStrict(); 898 assertEquals(10, d.x); 899}()); 900 901 902(function TestKeyedNumericSetterUndefinedProperties() { 903 var x = 42; 904 function Base() {} 905 function Derived() {} 906 Derived.prototype = { 907 __proto__: Base.prototype, 908 mSloppy() { 909 assertEquals(undefined, super[x]); 910 assertEquals(undefined, this[x]); 911 super[x] = 10; 912 assertEquals(10, this[x]); 913 assertEquals(undefined, super[x]); 914 }, 915 mStrict() { 916 'use strict'; 917 assertEquals(undefined, super[x]); 918 assertEquals(undefined, this[x]); 919 super[x] = 10; 920 assertEquals(10, this[x]); 921 assertEquals(undefined, super[x]); 922 } 923 }; 924 var d = new Derived(); 925 d.mSloppy(); 926 assertEquals(10, d[x]); 927 var d1 = new Derived(); 928 d1.mStrict(); 929 assertEquals(10, d[x]); 930}()); 931 932 933(function TestSetterCreatingOwnPropertiesReconfigurable() { 934 function Base() {} 935 function Derived() {} 936 Derived.prototype = { 937 __proto__: Base.prototype, 938 mSloppy() { 939 assertEquals(42, this.ownReadOnly); 940 super.ownReadOnly = 55; 941 assertSame(undefined, super.ownReadOnly); 942 assertEquals(42, this.ownReadOnly); 943 assertFalse(Base.prototype.hasOwnProperty('ownReadOnly')); 944 945 assertEquals(15, this.ownReadonlyAccessor); 946 super.ownReadonlyAccessor = 25; 947 assertSame(undefined, super.ownReadonlyAccessor); 948 assertEquals(15, this.ownReadonlyAccessor); 949 assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor')); 950 951 super.ownSetter = 35; 952 assertSame(undefined, super.ownSetter); 953 var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter'); 954 assertTrue('set' in descr); 955 assertFalse(Base.prototype.hasOwnProperty('ownSetter')); 956 }, 957 mStrict() { 958 'use strict'; 959 assertEquals(42, this.ownReadOnly); 960 assertThrows(() => {super.ownReadOnly = 55}, TypeError); 961 assertSame(undefined, super.ownReadOnly); 962 assertEquals(42, this.ownReadOnly); 963 assertFalse(Base.prototype.hasOwnProperty('ownReadOnly')); 964 965 assertEquals(15, this.ownReadonlyAccessor); 966 assertThrows(() => {super.ownReadonlyAccessor = 25}, TypeError); 967 assertSame(undefined, super.ownReadonlyAccessor); 968 assertEquals(15, this.ownReadonlyAccessor); 969 assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor')); 970 971 assertThrows(() => {super.ownSetter = 35}, TypeError); 972 assertSame(undefined, super.ownSetter); 973 var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter'); 974 assertTrue('set' in descr); 975 assertFalse(Base.prototype.hasOwnProperty('ownSetter')); 976 }, 977 }; 978 979 var d = new Derived(); 980 Object.defineProperty(d, 'ownReadOnly', { 981 value: 42, 982 writable: false, 983 configurable: true 984 }); 985 Object.defineProperty(d, 'ownSetter', { 986 set: function() { assertUnreachable(); }, 987 configurable: true 988 }); 989 Object.defineProperty(d, 'ownReadonlyAccessor', { 990 get: function() { return 15; }, 991 configurable: true 992 }); 993 994 d.mSloppy(); 995 996 var d = new Derived(); 997 Object.defineProperty(d, 'ownReadOnly', { 998 value: 42, 999 writable: false, 1000 configurable: true 1001 }); 1002 Object.defineProperty(d, 'ownSetter', { 1003 set: function() { assertUnreachable(); }, 1004 configurable: true 1005 }); 1006 Object.defineProperty(d, 'ownReadonlyAccessor', { 1007 get: function() { return 15; }, 1008 configurable: true 1009 }); 1010 d.mStrict(); 1011}()); 1012 1013 1014(function TestSetterCreatingOwnPropertiesNonConfigurable() { 1015 function Base() {} 1016 function Derived() {} 1017 Derived.prototype = { 1018 __proto__: Base.prototype, 1019 mSloppy() { 1020 assertEquals(42, this.ownReadOnly); 1021 super.ownReadOnly = 55; 1022 assertEquals(42, this.ownReadOnly); 1023 var descr = Object.getOwnPropertyDescriptor(this, 'ownReadOnly'); 1024 assertEquals(42, descr.value); 1025 assertFalse(descr.configurable); 1026 assertFalse(descr.enumerable); 1027 assertFalse(descr.writable); 1028 assertFalse(Base.prototype.hasOwnProperty('ownReadOnly')); 1029 1030 assertEquals(15, this.ownReadonlyAccessor); 1031 super.ownReadonlyAccessor = 25; 1032 assertSame(undefined, super.ownReadonlyAccessor); 1033 assertEquals(15, this.ownReadonlyAccessor); 1034 var descr = Object.getOwnPropertyDescriptor(this, 'ownReadonlyAccessor'); 1035 assertFalse(descr.configurable); 1036 assertFalse(descr.enumerable); 1037 assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor')); 1038 1039 super.ownSetter = 35; 1040 var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter'); 1041 assertFalse(descr.configurable); 1042 assertFalse(descr.enumerable); 1043 assertFalse(Base.prototype.hasOwnProperty('ownSetter')); 1044 }, 1045 mStrict() { 1046 'use strict'; 1047 var ex; 1048 assertEquals(42, this.ownReadOnly); 1049 try { 1050 super.ownReadOnly = 55; 1051 } catch (e) { 1052 ex = e; 1053 } 1054 assertInstanceof(ex, TypeError); 1055 assertEquals( 1056 "Cannot assign to read only property 'ownReadOnly' of object '#<Base>'", 1057 ex.message); 1058 assertEquals(42, this.ownReadOnly); 1059 1060 ex = null; 1061 assertEquals(15, this.ownReadonlyAccessor); 1062 try { 1063 super.ownReadonlyAccessor = 25; 1064 } catch (e) { 1065 ex = e; 1066 } 1067 assertInstanceof(ex, TypeError); 1068 assertEquals('Cannot redefine property: ownReadonlyAccessor', ex.message); 1069 assertEquals(15, this.ownReadonlyAccessor); 1070 1071 ex = null; 1072 try { 1073 super.ownSetter = 35; 1074 } catch (e) { 1075 ex = e; 1076 } 1077 assertInstanceof(ex, TypeError); 1078 assertEquals('Cannot redefine property: ownSetter', ex.message); 1079 } 1080 }; 1081 1082 var d = new Derived(); 1083 Object.defineProperty(d, 'ownReadOnly', { value : 42, writable : false }); 1084 Object.defineProperty(d, 'ownSetter', 1085 { set : function() { assertUnreachable(); } }); 1086 Object.defineProperty(d, 'ownReadonlyAccessor', 1087 { get : function() { return 15; }}); 1088 d.mSloppy(); 1089 d.mStrict(); 1090}()); 1091 1092 1093(function TestSetterInForIn() { 1094 var setCalled = 0; 1095 var getCalled = 0; 1096 function Base() {} 1097 Base.prototype = { 1098 constructor: Base, 1099 get x() { 1100 getCalled++; 1101 return 1; 1102 }, 1103 set x(v) { 1104 setCalled++; 1105 this.x_.push(v); 1106 }, 1107 }; 1108 1109 function Derived() { 1110 this.x_ = []; 1111 } 1112 Derived.prototype = { 1113 __proto__: Base.prototype, 1114 constructor: Derived, 1115 testIter() { 1116 setCalled = 0; 1117 getCalled = 0; 1118 for (super.x in [1,2,3]) {} 1119 assertEquals(0, getCalled); 1120 assertEquals(3, setCalled); 1121 assertEquals(["0", "1", "2"], this.x_); 1122 }, 1123 testIterKeyed() { 1124 setCalled = 0; 1125 getCalled = 0; 1126 for (super[x] in [1,2,3]) {} 1127 assertEquals(0, getCalled); 1128 assertEquals(3, setCalled); 1129 assertEquals(["0","1","2"], this.x_); 1130 1131 this.x_ = []; 1132 setCalled = 0; 1133 getCalled = 0; 1134 var toStringCalled = 0; 1135 var o = {toString: function () { toStringCalled++; return x }}; 1136 for (super[o] in [1,2,3]) {} 1137 assertEquals(0, getCalled); 1138 assertEquals(3, setCalled); 1139 assertEquals(3, toStringCalled); 1140 assertEquals(["0","1","2"], this.x_); 1141 } 1142 }; 1143 1144 new Derived().testIter(); 1145 1146 var x = 'x'; 1147 1148 new Derived().testIterKeyed(); 1149}()); 1150 1151 1152function TestKeyedSetterCreatingOwnPropertiesReconfigurable(ownReadOnly, 1153 ownReadonlyAccessor, ownSetter) { 1154 function Base() {} 1155 function Derived() {} 1156 Derived.prototype = { 1157 __proto__: Base.prototype, 1158 mSloppy() { 1159 assertEquals(42, this[ownReadOnly]); 1160 super[ownReadOnly] = 55; 1161 assertSame(undefined, super[ownReadOnly]); 1162 assertEquals(42, this[ownReadOnly]); 1163 assertFalse(Base.prototype.hasOwnProperty(ownReadOnly)); 1164 1165 assertEquals(15, this[ownReadonlyAccessor]); 1166 super[ownReadonlyAccessor] = 25; 1167 assertSame(undefined, super[ownReadonlyAccessor]); 1168 assertEquals(15, this[ownReadonlyAccessor]); 1169 assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor)); 1170 1171 super[ownSetter] = 35; 1172 assertSame(undefined, super[ownSetter]); 1173 var descr = Object.getOwnPropertyDescriptor(this, ownSetter); 1174 assertTrue('set' in descr); 1175 assertFalse(Base.prototype.hasOwnProperty(ownSetter)); 1176 }, 1177 mStrict() { 1178 'use strict'; 1179 assertEquals(42, this[ownReadOnly]); 1180 assertThrows(() => {super[ownReadOnly] = 55}, TypeError); 1181 assertSame(undefined, super[ownReadOnly]); 1182 assertEquals(42, this[ownReadOnly]); 1183 assertFalse(Base.prototype.hasOwnProperty(ownReadOnly)); 1184 1185 assertEquals(15, this[ownReadonlyAccessor]); 1186 assertThrows(() => {super[ownReadonlyAccessor] = 25}, TypeError); 1187 assertSame(undefined, super[ownReadonlyAccessor]); 1188 assertEquals(15, this[ownReadonlyAccessor]); 1189 assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor)); 1190 1191 assertThrows(() => {super[ownSetter] = 35}, TypeError); 1192 assertSame(undefined, super[ownSetter]); 1193 var descr = Object.getOwnPropertyDescriptor(this, ownSetter); 1194 assertTrue('set' in descr); 1195 assertFalse(Base.prototype.hasOwnProperty(ownSetter)); 1196 }, 1197 }; 1198 1199 var d = new Derived(); 1200 Object.defineProperty(d, ownReadOnly, { 1201 value: 42, 1202 writable: false, 1203 configurable: true 1204 }); 1205 Object.defineProperty(d, ownSetter, { 1206 set: function() { assertUnreachable(); }, 1207 configurable: true 1208 }); 1209 Object.defineProperty(d, ownReadonlyAccessor, { 1210 get: function() { return 15; }, 1211 configurable: true 1212 }); 1213 1214 d.mSloppy(); 1215 1216 var d = new Derived(); 1217 Object.defineProperty(d, ownReadOnly, { 1218 value: 42, 1219 writable: false, 1220 configurable: true 1221 }); 1222 Object.defineProperty(d, ownSetter, { 1223 set: function() { assertUnreachable(); }, 1224 configurable: true 1225 }); 1226 Object.defineProperty(d, ownReadonlyAccessor, { 1227 get: function() { return 15; }, 1228 configurable: true 1229 }); 1230 d.mStrict(); 1231} 1232TestKeyedSetterCreatingOwnPropertiesReconfigurable('ownReadOnly', 1233 'ownReadonlyAccessor', 1234 'ownSetter'); 1235TestKeyedSetterCreatingOwnPropertiesReconfigurable(42, 43, 44); 1236 1237 1238function TestKeyedSetterCreatingOwnPropertiesNonConfigurable( 1239 ownReadOnly, ownReadonlyAccessor, ownSetter) { 1240 function Base() {} 1241 function Derived() {} 1242 Derived.prototype = { 1243 __proto__: Base.prototype, 1244 mSloppy() { 1245 assertEquals(42, this[ownReadOnly]); 1246 super[ownReadOnly] = 55; 1247 assertEquals(42, this[ownReadOnly]); 1248 var descr = Object.getOwnPropertyDescriptor(this, ownReadOnly); 1249 assertEquals(42, descr.value); 1250 assertFalse(descr.configurable); 1251 assertFalse(descr.enumerable); 1252 assertFalse(descr.writable); 1253 assertFalse(Base.prototype.hasOwnProperty(ownReadOnly)); 1254 1255 assertEquals(15, this[ownReadonlyAccessor]); 1256 super[ownReadonlyAccessor] = 25; 1257 assertSame(undefined, super[ownReadonlyAccessor]); 1258 assertEquals(15, this[ownReadonlyAccessor]); 1259 var descr = Object.getOwnPropertyDescriptor(this, ownReadonlyAccessor); 1260 assertFalse(descr.configurable); 1261 assertFalse(descr.enumerable); 1262 assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor)); 1263 1264 super[ownSetter] = 35; 1265 var descr = Object.getOwnPropertyDescriptor(this, ownSetter); 1266 assertFalse(descr.configurable); 1267 assertFalse(descr.enumerable); 1268 assertFalse(Base.prototype.hasOwnProperty(ownSetter)); 1269 }, 1270 mStrict() { 1271 'use strict'; 1272 var ex; 1273 assertEquals(42, this[ownReadOnly]); 1274 try { 1275 super[ownReadOnly] = 55; 1276 } catch (e) { 1277 ex = e; 1278 } 1279 assertInstanceof(ex, TypeError); 1280 assertEquals( 1281 "Cannot assign to read only property '" + ownReadOnly + 1282 "' of object '#<Base>'", 1283 ex.message); 1284 assertEquals(42, this[ownReadOnly]); 1285 1286 ex = null; 1287 assertEquals(15, this[ownReadonlyAccessor]); 1288 try { 1289 super[ownReadonlyAccessor] = 25; 1290 } catch (e) { 1291 ex = e; 1292 } 1293 assertInstanceof(ex, TypeError); 1294 assertEquals('Cannot redefine property: ' + ownReadonlyAccessor, 1295 ex.message); 1296 assertEquals(15, this[ownReadonlyAccessor]); 1297 1298 ex = null; 1299 try { 1300 super[ownSetter] = 35; 1301 } catch (e) { 1302 ex = e; 1303 } 1304 assertInstanceof(ex, TypeError); 1305 assertEquals('Cannot redefine property: ' + ownSetter, ex.message); 1306 } 1307 }; 1308 1309 var d = new Derived(); 1310 Object.defineProperty(d, ownReadOnly, { value : 42, writable : false }); 1311 Object.defineProperty(d, ownSetter, 1312 { set : function() { assertUnreachable(); } }); 1313 Object.defineProperty(d, ownReadonlyAccessor, 1314 { get : function() { return 15; }}); 1315 d.mSloppy(); 1316 d.mStrict(); 1317} 1318TestKeyedSetterCreatingOwnPropertiesNonConfigurable('ownReadOnly', 1319 'ownReadonlyAccessor', 'ownSetter'); 1320TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44); 1321 1322 1323(function TestSetterNoProtoWalk() { 1324 function Base() {} 1325 function Derived() {} 1326 var getCalled; 1327 var setCalled; 1328 Derived.prototype = { 1329 __proto__: Base.prototype, 1330 get x() { getCalled++; return 42; }, 1331 set x(v) { setCalled++; }, 1332 mSloppy() { 1333 setCalled = 0; 1334 getCalled = 0; 1335 assertEquals(42, this.x); 1336 assertEquals(1, getCalled); 1337 assertEquals(0, setCalled); 1338 1339 getCalled = 0; 1340 setCalled = 0; 1341 this.x = 43; 1342 assertEquals(0, getCalled); 1343 assertEquals(1, setCalled); 1344 1345 getCalled = 0; 1346 setCalled = 0; 1347 super.x = 15; 1348 assertEquals(0, setCalled); 1349 assertEquals(0, getCalled); 1350 1351 assertEquals(15, this.x); 1352 assertEquals(0, getCalled); 1353 assertEquals(0, setCalled); 1354 }, 1355 mStrict() { 1356 'use strict'; 1357 setCalled = 0; 1358 getCalled = 0; 1359 assertEquals(42, this.x); 1360 assertEquals(1, getCalled); 1361 assertEquals(0, setCalled); 1362 1363 getCalled = 0; 1364 setCalled = 0; 1365 this.x = 43; 1366 assertEquals(0, getCalled); 1367 assertEquals(1, setCalled); 1368 1369 getCalled = 0; 1370 setCalled = 0; 1371 super.x = 15; 1372 assertEquals(0, setCalled); 1373 assertEquals(0, getCalled); 1374 1375 assertEquals(15, this.x); 1376 assertEquals(0, getCalled); 1377 assertEquals(0, setCalled); 1378 } 1379 }; 1380 1381 new Derived().mSloppy(); 1382 new Derived().mStrict(); 1383}()); 1384 1385 1386(function TestKeyedSetterNoProtoWalk() { 1387 var x = 'x'; 1388 function Base() {} 1389 function Derived() {} 1390 var getCalled; 1391 var setCalled; 1392 Derived.prototype = { 1393 __proto__: Base.prototype, 1394 get x() { getCalled++; return 42; }, 1395 set x(v) { setCalled++; }, 1396 mSloppy() { 1397 setCalled = 0; 1398 getCalled = 0; 1399 assertEquals(42, this[x]); 1400 assertEquals(1, getCalled); 1401 assertEquals(0, setCalled); 1402 1403 getCalled = 0; 1404 setCalled = 0; 1405 this[x] = 43; 1406 assertEquals(0, getCalled); 1407 assertEquals(1, setCalled); 1408 1409 getCalled = 0; 1410 setCalled = 0; 1411 super[x] = 15; 1412 assertEquals(0, setCalled); 1413 assertEquals(0, getCalled); 1414 1415 assertEquals(15, this[x]); 1416 assertEquals(0, getCalled); 1417 assertEquals(0, setCalled); 1418 }, 1419 mStrict() { 1420 'use strict'; 1421 setCalled = 0; 1422 getCalled = 0; 1423 assertEquals(42, this[x]); 1424 assertEquals(1, getCalled); 1425 assertEquals(0, setCalled); 1426 1427 getCalled = 0; 1428 setCalled = 0; 1429 this[x] = 43; 1430 assertEquals(0, getCalled); 1431 assertEquals(1, setCalled); 1432 1433 getCalled = 0; 1434 setCalled = 0; 1435 super[x] = 15; 1436 assertEquals(0, setCalled); 1437 assertEquals(0, getCalled); 1438 1439 assertEquals(15, this[x]); 1440 assertEquals(0, getCalled); 1441 assertEquals(0, setCalled); 1442 } 1443 }; 1444 1445 new Derived().mSloppy(); 1446 new Derived().mStrict(); 1447}()); 1448 1449 1450(function TestKeyedNumericSetterNoProtoWalk() { 1451 var x = 42; 1452 function Base() {} 1453 function Derived() {} 1454 var getCalled; 1455 var setCalled; 1456 Derived.prototype = { 1457 __proto__: Base.prototype, 1458 mSloppy() { 1459 setCalled = 0; 1460 getCalled = 0; 1461 assertEquals(42, this[x]); 1462 assertEquals(1, getCalled); 1463 assertEquals(0, setCalled); 1464 1465 getCalled = 0; 1466 setCalled = 0; 1467 this[x] = 43; 1468 assertEquals(0, getCalled); 1469 assertEquals(1, setCalled); 1470 1471 getCalled = 0; 1472 setCalled = 0; 1473 super[x] = 15; 1474 assertEquals(0, setCalled); 1475 assertEquals(0, getCalled); 1476 1477 assertEquals(15, this[x]); 1478 assertEquals(0, getCalled); 1479 assertEquals(0, setCalled); 1480 }, 1481 mStrict() { 1482 'use strict'; 1483 setCalled = 0; 1484 getCalled = 0; 1485 assertEquals(42, this[x]); 1486 assertEquals(1, getCalled); 1487 assertEquals(0, setCalled); 1488 1489 getCalled = 0; 1490 setCalled = 0; 1491 this[x] = 43; 1492 assertEquals(0, getCalled); 1493 assertEquals(1, setCalled); 1494 1495 getCalled = 0; 1496 setCalled = 0; 1497 super[x] = 15; 1498 assertEquals(0, setCalled); 1499 assertEquals(0, getCalled); 1500 1501 assertEquals(15, this[x]); 1502 assertEquals(0, getCalled); 1503 assertEquals(0, setCalled); 1504 } 1505 }; 1506 1507 Object.defineProperty(Derived.prototype, x, { 1508 get: function() { getCalled++; return 42; }, 1509 set: function(v) { setCalled++; } 1510 }); 1511 1512 new Derived().mSloppy(); 1513 new Derived().mStrict(); 1514}()); 1515 1516 1517(function TestSetterDoesNotReconfigure() { 1518 function Base() {} 1519 function Derived() {} 1520 Derived.prototype = { 1521 __proto__: Derived.prototype, 1522 mStrict(){ 1523 'use strict'; 1524 super.nonEnumConfig = 5; 1525 var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig'); 1526 assertEquals(5, d1.value); 1527 assertTrue(d1.configurable); 1528 assertFalse(d1.enumerable); 1529 1530 super.nonEnumNonConfig = 5; 1531 var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig'); 1532 assertEquals(5, d1.value); 1533 assertFalse(d1.configurable); 1534 assertFalse(d1.enumerable); 1535 }, 1536 mSloppy(){ 1537 super.nonEnumConfig = 42; 1538 var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig'); 1539 assertEquals(42, d1.value); 1540 assertTrue(d1.configurable); 1541 assertFalse(d1.enumerable); 1542 1543 super.nonEnumNonConfig = 42; 1544 var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig'); 1545 assertEquals(42, d1.value); 1546 assertFalse(d1.configurable); 1547 assertFalse(d1.enumerable); 1548 } 1549 }; 1550 1551 var d = new Derived(); 1552 Object.defineProperty(d, 'nonEnumConfig', 1553 { value : 0, enumerable : false, configurable : true, writable : true }); 1554 Object.defineProperty(d, 'nonEnumNonConfig', 1555 { value : 0, enumerable : false, configurable : false, writable : true }); 1556 d.mStrict(); 1557 d.mSloppy(); 1558}()); 1559 1560 1561(function TestKeyedSetterDoesNotReconfigure() { 1562 var nonEnumConfig = 'nonEnumConfig'; 1563 var nonEnumNonConfig = 'nonEnumNonConfig'; 1564 function Base() {} 1565 function Derived() {} 1566 1567 Derived.prototype = { 1568 __proto__: Base.prototype, 1569 mStrict(){ 1570 'use strict'; 1571 super[nonEnumConfig] = 5; 1572 var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig); 1573 assertEquals(5, d1.value); 1574 assertTrue(d1.configurable); 1575 assertFalse(d1.enumerable); 1576 1577 super[nonEnumNonConfig] = 5; 1578 var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig); 1579 assertEquals(5, d1.value); 1580 assertFalse(d1.configurable); 1581 assertFalse(d1.enumerable); 1582 }, 1583 mSloppy(){ 1584 super[nonEnumConfig] = 42; 1585 var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig); 1586 assertEquals(42, d1.value); 1587 assertTrue(d1.configurable); 1588 assertFalse(d1.enumerable); 1589 1590 super[nonEnumNonConfig] = 42; 1591 var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig); 1592 assertEquals(42, d1.value); 1593 assertFalse(d1.configurable); 1594 assertFalse(d1.enumerable); 1595 } 1596 }; 1597 1598 var d = new Derived(); 1599 Object.defineProperty(d, nonEnumConfig, 1600 { value : 0, enumerable : false, configurable : true, writable : true }); 1601 Object.defineProperty(d, nonEnumNonConfig, 1602 { value : 0, enumerable : false, configurable : false, writable : true }); 1603 d.mStrict(); 1604 d.mSloppy(); 1605}()); 1606 1607 1608(function TestKeyedNumericSetterDoesNotReconfigure() { 1609 var nonEnumConfig = 42; 1610 var nonEnumNonConfig = 43; 1611 function Base() {} 1612 function Derived() {} 1613 1614 Derived.prototype = { 1615 __proto__: Base.prototype, 1616 mStrict(){ 1617 'use strict'; 1618 super[nonEnumConfig] = 5; 1619 var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig); 1620 assertEquals(5, d1.value); 1621 assertTrue(d1.configurable); 1622 assertFalse(d1.enumerable); 1623 1624 super[nonEnumNonConfig] = 5; 1625 var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig); 1626 assertEquals(5, d1.value); 1627 assertFalse(d1.configurable); 1628 assertFalse(d1.enumerable); 1629 }, 1630 mSloppy(){ 1631 super[nonEnumConfig] = 42; 1632 var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig); 1633 assertEquals(42, d1.value); 1634 assertTrue(d1.configurable); 1635 assertFalse(d1.enumerable); 1636 1637 super[nonEnumNonConfig] = 42; 1638 var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig); 1639 assertEquals(42, d1.value); 1640 assertFalse(d1.configurable); 1641 assertFalse(d1.enumerable); 1642 } 1643 }; 1644 1645 var d = new Derived(); 1646 Object.defineProperty(d, nonEnumConfig, 1647 { value : 0, enumerable : false, configurable : true, writable : true }); 1648 Object.defineProperty(d, nonEnumNonConfig, 1649 { value : 0, enumerable : false, configurable : false, writable : true }); 1650 d.mStrict(); 1651 d.mSloppy(); 1652}()); 1653 1654 1655(function TestCountOperations() { 1656 function Base() {} 1657 Base.prototype = { 1658 constructor: Base, 1659 get x() { 1660 return this._x; 1661 }, 1662 set x(v) { 1663 this._x = v; 1664 }, 1665 _x: 1 1666 }; 1667 1668 function Derived() {} 1669 Derived.__proto__ = Base; 1670 Derived.prototype = { 1671 __proto__: Base.prototype, 1672 constructor: Derived, 1673 _x: 2, 1674 testCounts() { 1675 assertEquals(2, this._x); 1676 assertEquals(2, super.x); 1677 super.x++; 1678 assertEquals(3, super.x); 1679 ++super.x; 1680 assertEquals(4, super.x); 1681 assertEquals(4, super.x++); 1682 assertEquals(5, super.x); 1683 assertEquals(6, ++super.x); 1684 assertEquals(6, super.x); 1685 assertEquals(6, this._x); 1686 1687 super.x--; 1688 assertEquals(5, super.x); 1689 --super.x; 1690 assertEquals(4, super.x); 1691 assertEquals(4, super.x--); 1692 assertEquals(3, super.x); 1693 assertEquals(2, --super.x); 1694 assertEquals(2, super.x); 1695 assertEquals(2, this._x); 1696 } 1697 }; 1698 new Derived().testCounts(); 1699}()); 1700 1701 1702(function TestKeyedCountOperations() { 1703 var x = 'x'; 1704 function Base() {} 1705 Base.prototype = { 1706 constructor: Base, 1707 get x() { 1708 return this._x; 1709 }, 1710 set x(v) { 1711 this._x = v; 1712 }, 1713 _x: 1 1714 }; 1715 1716 function Derived() {} 1717 Derived.__proto__ = Base; 1718 Derived.prototype = { 1719 __proto__: Base.prototype, 1720 constructor: Derived, 1721 _x: 2, 1722 testCounts() { 1723 assertEquals(2, this._x); 1724 assertEquals(2, super[x]); 1725 super[x]++; 1726 assertEquals(3, super[x]); 1727 ++super[x]; 1728 assertEquals(4, super[x]); 1729 assertEquals(4, super[x]++); 1730 assertEquals(5, super[x]); 1731 assertEquals(6, ++super[x]); 1732 assertEquals(6, super[x]); 1733 assertEquals(6, this._x); 1734 1735 super[x]--; 1736 assertEquals(5, super[x]); 1737 --super[x]; 1738 assertEquals(4, super[x]); 1739 assertEquals(4, super[x]--); 1740 assertEquals(3, super[x]); 1741 assertEquals(2, --super[x]); 1742 assertEquals(2, super[x]); 1743 assertEquals(2, this._x); 1744 } 1745 }; 1746 new Derived().testCounts(); 1747}()); 1748 1749 1750(function TestKeyedNumericCountOperations() { 1751 var x = 42; 1752 function Base() {} 1753 Base.prototype = { 1754 constructor: Base, 1755 _x: 1 1756 }; 1757 1758 Object.defineProperty(Base.prototype, x, { 1759 get: function() { return this._x; }, 1760 set: function(v) { this._x = v;; } 1761 }); 1762 1763 function Derived() {} 1764 Derived.__proto__ = Base; 1765 Derived.prototype = { 1766 __proto__: Base.prototype, 1767 constructor: Derived, 1768 _x: 2, 1769 testCounts() { 1770 assertEquals(2, this._x); 1771 assertEquals(2, super[x]); 1772 super[x]++; 1773 assertEquals(3, super[x]); 1774 ++super[x]; 1775 assertEquals(4, super[x]); 1776 assertEquals(4, super[x]++); 1777 assertEquals(5, super[x]); 1778 assertEquals(6, ++super[x]); 1779 assertEquals(6, super[x]); 1780 assertEquals(6, this._x); 1781 1782 super[x]--; 1783 assertEquals(5, super[x]); 1784 --super[x]; 1785 assertEquals(4, super[x]); 1786 assertEquals(4, super[x]--); 1787 assertEquals(3, super[x]); 1788 assertEquals(2, --super[x]); 1789 assertEquals(2, super[x]); 1790 assertEquals(2, this._x); 1791 } 1792 }; 1793 new Derived().testCounts(); 1794}()); 1795 1796 1797(function TestSetterSuperNonWritable() { 1798 function Base() {} 1799 Object.defineProperty(Base.prototype, 'x', { value : 27, writable: false }); 1800 function Derived() {} 1801 Derived.prototype = { 1802 __proto__: Base.prototype, 1803 constructor: Derived, 1804 mSloppy() { 1805 assertEquals(27, super.x); 1806 assertEquals(27, this.x); 1807 super.x = 10; 1808 assertEquals(27, super.x); 1809 assertEquals(27, this.x); 1810 }, 1811 mStrict() { 1812 'use strict'; 1813 assertEquals(27, super.x); 1814 assertEquals(27, this.x); 1815 var ex = null; 1816 try { super.x = 10; } catch(e) { ex = e; } 1817 assertInstanceof(ex, TypeError); 1818 assertEquals(27, super.x); 1819 assertEquals(27, this.x); 1820 } 1821 }; 1822 new Derived().mSloppy(); 1823 new Derived().mStrict(); 1824}()); 1825 1826 1827(function TestSetterKeyedSuperNonWritable() { 1828 var x = 'xyz'; 1829 function Base() {} 1830 Object.defineProperty(Base.prototype, x, { value : 27, writable: false }); 1831 function Derived() {} 1832 1833 Derived.prototype = { 1834 __proto__: Base.prototype, 1835 constructor: Derived, 1836 mSloppy() { 1837 assertEquals(27, super[x]); 1838 assertEquals(27, this[x]); 1839 super[x] = 10; 1840 assertEquals(27, super[x]); 1841 assertEquals(27, this[x]); 1842 }, 1843 mStrict() { 1844 'use strict'; 1845 assertEquals(27, super[x]); 1846 assertEquals(27, this[x]); 1847 var ex = null; 1848 try { super[x] = 10; } catch(e) { ex = e; } 1849 assertInstanceof(ex, TypeError); 1850 assertEquals(27, super[x]); 1851 assertEquals(27, this[x]); 1852 } 1853 }; 1854 new Derived().mSloppy(); 1855 new Derived().mStrict(); 1856}()); 1857 1858 1859(function TestSetterKeyedNumericSuperNonWritable() { 1860 var x = 42; 1861 function Base() {} 1862 Object.defineProperty(Base.prototype, x, { value : 27, writable: false }); 1863 function Derived() {} 1864 1865 Derived.prototype = { 1866 __proto__: Base.prototype, 1867 constructor: Derived, 1868 mSloppy() { 1869 assertEquals(27, super[x]); 1870 assertEquals(27, this[x]); 1871 super[x] = 10; 1872 assertEquals(27, super[x]); 1873 assertEquals(27, this[x]); 1874 }, 1875 mStrict() { 1876 'use strict'; 1877 assertEquals(27, super[x]); 1878 assertEquals(27, this[x]); 1879 var ex = null; 1880 try { super[x] = 10; } catch(e) { ex = e; } 1881 assertInstanceof(ex, TypeError); 1882 assertEquals(27, super[x]); 1883 assertEquals(27, this[x]); 1884 } 1885 }; 1886 new Derived().mSloppy(); 1887 new Derived().mStrict(); 1888}()); 1889 1890 1891(function TestSuperCall() { 1892 'use strict'; 1893 1894 var baseCalled = 0; 1895 var derivedCalled = 0; 1896 var derivedDerivedCalled = 0; 1897 1898 class Base { 1899 constructor() { 1900 baseCalled++; 1901 } 1902 } 1903 1904 class Derived extends Base { 1905 constructor() { 1906 let r = super(); 1907 assertEquals(this, r); 1908 derivedCalled++; 1909 } 1910 } 1911 1912 assertEquals(Base, Base.prototype.constructor); 1913 assertEquals(Base.prototype, Derived.prototype.__proto__); 1914 1915 baseCalled = 0; 1916 derivedCalled = 0; 1917 new Derived(); 1918 assertEquals(1, baseCalled); 1919 assertEquals(1, derivedCalled); 1920 1921 class DerivedDerived extends Derived { 1922 constructor() { 1923 let r = super(); 1924 assertEquals(this, r); 1925 derivedDerivedCalled++; 1926 } 1927 } 1928 1929 baseCalled = 0; 1930 derivedCalled = 0; 1931 derivedDerivedCalled = 0; 1932 new DerivedDerived(); 1933 assertEquals(1, baseCalled); 1934 assertEquals(1, derivedCalled); 1935 assertEquals(1, derivedDerivedCalled); 1936 1937 class Base2 { 1938 constructor(v) { 1939 this.fromBase = v; 1940 } 1941 } 1942 class Derived2 extends Base2 { 1943 constructor(v1, v2) { 1944 let r = super(v1); 1945 assertEquals(this, r); 1946 this.fromDerived = v2; 1947 } 1948 } 1949 1950 var d = new Derived2("base", "derived"); 1951 assertEquals("base", d.fromBase); 1952 assertEquals("derived", d.fromDerived); 1953 1954 var calls = 0; 1955 class G { 1956 constructor() { 1957 calls++; 1958 } 1959 } 1960 1961 class F extends Object { 1962 constructor() { 1963 super(); 1964 } 1965 } 1966 F.__proto__ = G; 1967 new F(); 1968 assertEquals(1, calls); 1969 F.__proto__ = function() {}; 1970 new F(); 1971 assertEquals(1, calls); 1972}()); 1973 1974 1975(function TestExtendsObject() { 1976 'use strict'; 1977 class F extends Object { } 1978 var f = new F(42); 1979 1980 assertInstanceof(f, F); 1981 assertInstanceof(f, Object); 1982}()); 1983 1984 1985(function TestSuperCallErrorCases() { 1986 'use strict'; 1987 class T extends Object { 1988 constructor() { 1989 super(); 1990 } 1991 } 1992 1993 T.__proto__ = null; 1994 assertThrows(function() { new T(); }, TypeError); 1995}()); 1996 1997 1998(function TestSuperPropertyInEval() { 1999 'use strict'; 2000 let y = 3; 2001 class Base { 2002 m() { return 1; } 2003 get x() { return 2; } 2004 } 2005 class Derived extends Base { 2006 evalM() { 2007 assertEquals(1, eval('super.m()')); 2008 } 2009 evalX() { 2010 assertEquals(2, eval('super.x')); 2011 } 2012 globalEval1() { 2013 assertThrows('super.x', SyntaxError); 2014 assertThrows('super.m()', SyntaxError); 2015 } 2016 globalEval2() { 2017 super.x; 2018 assertThrows('super.x', SyntaxError); 2019 assertThrows('super.m()', SyntaxError); 2020 } 2021 } 2022 let d = new Derived(); 2023 d.globalEval1(); 2024 d.globalEval2(); 2025 d.evalM(); 2026 d.evalX(); 2027})(); 2028 2029 2030(function TestSuperPropertyInArrow() { 2031 'use strict'; 2032 let y = 3; 2033 class Base { 2034 m() { return 1; } 2035 get x() { return 2; } 2036 } 2037 class Derived extends Base { 2038 arrow() { 2039 assertSame(super.x, (() => super.x)()); 2040 assertSame(super.m(), (() => super.m())()); 2041 return (() => super.m())(); 2042 } 2043 } 2044 let d = new Derived(); 2045 assertSame(1, d.arrow()); 2046})(); 2047 2048 2049(function TestSuperInOtherScopes() { 2050 var p = {x: 99}; 2051 var o0 = {__proto__: p, f() { return eval("'use strict'; super.x") }}; 2052 assertEquals(p.x, o0.f()); 2053 var o1 = {__proto__: p, f() { with ({}) return super.x }}; 2054 assertEquals(p.x, o1.f()); 2055 var o2 = {__proto__: p, f({a}) { return super.x }}; 2056 assertEquals(p.x, o2.f({})); 2057 var o3 = {__proto__: p, f(...a) { return super.x }}; 2058 assertEquals(p.x, o3.f()); 2059 var o4 = {__proto__: p, f() { 'use strict'; { let x; return super.x } }}; 2060 assertEquals(p.x, o4.f()); 2061})(); 2062 2063 2064(function TestSuperCallInOtherScopes() { 2065 class C {constructor() { this.x = 99 }} 2066 class D0 extends C {constructor() { eval("'use strict'; super()") }} 2067 assertEquals(99, (new D0).x); 2068 class D2 extends C {constructor({a}) { super() }} 2069 assertEquals(99, (new D2({})).x); 2070 class D3 extends C {constructor(...a) { super() }} 2071 assertEquals(99, (new D3()).x); 2072 class D4 extends C {constructor() { { let x; super() } }} 2073 assertEquals(99, (new D4).x); 2074})(); 2075 2076 2077(function TestSuperCallInEval() { 2078 'use strict'; 2079 class Base { 2080 constructor(x) { 2081 this.x = x; 2082 } 2083 } 2084 class Derived extends Base { 2085 constructor(x) { 2086 let r = eval('super(x)'); 2087 assertEquals(this, r); 2088 } 2089 } 2090 let d = new Derived(42); 2091 assertSame(42, d.x); 2092})(); 2093 2094 2095(function TestSuperCallInArrow() { 2096 'use strict'; 2097 class Base { 2098 constructor(x) { 2099 this.x = x; 2100 } 2101 } 2102 class Derived extends Base { 2103 constructor(x) { 2104 let r = (() => super(x))(); 2105 assertEquals(this, r); 2106 } 2107 } 2108 let d = new Derived(42); 2109 assertSame(42, d.x); 2110})(); 2111 2112 2113(function TestSuperCallEscapes() { 2114 'use strict'; 2115 class Base { 2116 constructor(x) { 2117 this.x = x; 2118 } 2119 } 2120 2121 let f; 2122 class Derived extends Base { 2123 constructor() { 2124 f = () => super(2); 2125 } 2126 } 2127 assertThrows(function() { 2128 new Derived(); 2129 }, ReferenceError); 2130 2131 let o = f(); 2132 assertEquals(2, o.x); 2133 assertInstanceof(o, Derived); 2134 2135 assertThrows(function() { 2136 f(); 2137 }, ReferenceError); 2138})(); 2139 2140 2141(function TestSuperCallInLoop() { 2142 'use strict'; 2143 class Base { 2144 constructor(x) { 2145 this.x = x; 2146 } 2147 } 2148 class Derived extends Base { 2149 constructor(x, n) { 2150 for (var i = 0; i < n; ++i) { 2151 super(x); 2152 } 2153 } 2154 } 2155 2156 let o = new Derived(23, 1); 2157 assertEquals(23, o.x); 2158 assertInstanceof(o, Derived); 2159 2160 assertThrows("new Derived(42, 0)", ReferenceError); 2161 assertThrows("new Derived(65, 2)", ReferenceError); 2162})(); 2163 2164 2165(function TestSuperCallReentrant() { 2166 'use strict'; 2167 class Base { 2168 constructor(fun) { 2169 this.x = fun(); 2170 } 2171 } 2172 class Derived extends Base { 2173 constructor(x) { 2174 let f = () => super(() => x) 2175 super(f); 2176 } 2177 } 2178 assertThrows("new Derived(23)", ReferenceError); 2179})(); 2180 2181 2182(function TestSuperCallSpreadInEval() { 2183 'use strict'; 2184 class Base { 2185 constructor(x) { 2186 this.x = x; 2187 } 2188 } 2189 class Derived extends Base { 2190 constructor(x) { 2191 let r = eval('super(...[x])'); 2192 assertEquals(this, r); 2193 } 2194 } 2195 let d = new Derived(42); 2196 assertSame(42, d.x); 2197})(); 2198 2199 2200(function TestSuperCallSpreadInArrow() { 2201 'use strict'; 2202 class Base { 2203 constructor(x) { 2204 this.x = x; 2205 } 2206 } 2207 class Derived extends Base { 2208 constructor(x) { 2209 let r = (() => super(...[x]))(); 2210 assertEquals(this, r); 2211 } 2212 } 2213 let d = new Derived(42); 2214 assertSame(42, d.x); 2215})(); 2216