mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-27 01:33:59 +01:00 
			
		
		
		
	sourceRevisionAtLastExport: 33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de targetRevisionAtLastExport: 31340cbd9add103f586d501b0c3354b7b182abc0
		
			
				
	
	
		
			2248 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			2248 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // Copyright 2014 the V8 project authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style license that can be
 | |
| // found in the LICENSE file.
 | |
| 
 | |
| // Flags: --allow-natives-syntax
 | |
| 
 | |
| (function TestSuperNamedLoads() {
 | |
|   function Base() { }
 | |
|   function fBase() { }
 | |
|   Base.prototype = {
 | |
|     f() {
 | |
|       return "Base " + this.toString();
 | |
|     },
 | |
|     x: 15,
 | |
|     toString() {
 | |
|       return "this is Base";
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   function Derived() {
 | |
|     this.derivedDataProperty = "xxx";
 | |
|   }
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     toString() { return "this is Derived"; },
 | |
|     x: 27,
 | |
|     f() {
 | |
|       assertEquals("Base this is Derived", super.f());
 | |
|       var a = super.x;
 | |
|       assertEquals(15, a);
 | |
|       assertEquals(15, super.x);
 | |
|       assertEquals(27, this.x);
 | |
|       return "Derived";
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   assertEquals("Base this is Base", new Base().f());
 | |
|   assertEquals("Derived", new Derived().f());
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSuperKeyedLoads() {
 | |
|   'use strict';
 | |
| 
 | |
|   var x = 'x';
 | |
|   var derivedDataProperty = 'derivedDataProperty';
 | |
|   var f = 'f';
 | |
| 
 | |
|   class Base {
 | |
|     f() {
 | |
|       return "Base " + this.toString();
 | |
|     }
 | |
|     toString() {
 | |
|       return "this is Base";
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Base.prototype[x] = 15;
 | |
| 
 | |
|   function Derived() {
 | |
|     this[derivedDataProperty] = "xxx";
 | |
|   }
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     toString() { return "this is Derived"; },
 | |
|     x: 27,
 | |
|     f() {
 | |
|       assertEquals("Base this is Derived", super[f]());
 | |
|       var a = super[x];
 | |
|       assertEquals(15, a);
 | |
|       assertEquals(15, super[x]);
 | |
|       assertEquals(27, this[x]);
 | |
|       return "Derived";
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   assertEquals("Base this is Base", new Base().f());
 | |
|   assertEquals("Derived", new Derived().f());
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSuperKeywordNonMethod() {
 | |
|   'use strict';
 | |
| 
 | |
|   class C {
 | |
|     f() {
 | |
|       super.unknown();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   assertThrows(function() {
 | |
|     new C().f();
 | |
|   }, TypeError);
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestGetter() {
 | |
|   function Base() {}
 | |
|   var derived;
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     get x() {
 | |
|       assertSame(this, derived);
 | |
|       return this._x;
 | |
|     },
 | |
|     _x: 'base'
 | |
|   };
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.__proto__ = Base;
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     _x: 'derived',
 | |
|     testGetter() {
 | |
|       return super.x;
 | |
|     },
 | |
|     testGetterStrict() {
 | |
|       'use strict';
 | |
|       return super.x;
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   derived = new Derived();
 | |
|   assertEquals('derived', derived.testGetter());
 | |
|   derived = new Derived();
 | |
|   assertEquals('derived', derived.testGetterStrict());
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestGetterKeyed() {
 | |
|   var x = 'x';
 | |
|   function Base() {}
 | |
|   var derived;
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     get x() {
 | |
|       assertSame(this, derived);
 | |
|       return this._x;
 | |
|     },
 | |
|     _x: 'base'
 | |
|   };
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.__proto__ = Base;
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     _x: 'derived',
 | |
|     testGetter() {
 | |
|       return super[x];
 | |
|     },
 | |
|     testGetterStrict() {
 | |
|       'use strict';
 | |
|       return super[x];
 | |
|     },
 | |
|     testGetterWithToString() {
 | |
|       var toStringCalled;
 | |
|       var o = { toString: function() {
 | |
|         toStringCalled++;
 | |
|         return 'x';
 | |
|       } };
 | |
| 
 | |
|       toStringCalled = 0;
 | |
|       assertEquals('derived', super[o]);
 | |
|       assertEquals(1, toStringCalled);
 | |
| 
 | |
|       var eToThrow = new Error();
 | |
|       var oThrowsInToString = { toString: function() {
 | |
|         throw eToThrow;
 | |
|       } };
 | |
| 
 | |
|       var ex = null;
 | |
|       try {
 | |
|         super[oThrowsInToString];
 | |
|       } catch(e) { ex = e }
 | |
|       assertEquals(eToThrow, ex);
 | |
| 
 | |
|       var oReturnsNumericString = { toString: function() {
 | |
|         return "1";
 | |
|       } };
 | |
| 
 | |
|       assertEquals(undefined, super[oReturnsNumericString]);
 | |
|       assertEquals(undefined, super[1]);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   derived = new Derived();
 | |
|   assertEquals('derived', derived.testGetter());
 | |
|   derived = new Derived();
 | |
|   assertEquals('derived', derived.testGetterStrict());
 | |
|   derived = new Derived();
 | |
|   derived.testGetterWithToString();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestGetterNumericKeyed() {
 | |
|   var x = 42;
 | |
|   function Base() {}
 | |
|   var derived;
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     _x: 'base'
 | |
|   };
 | |
| 
 | |
|   Object.defineProperty(Base.prototype, x, { get: function() {
 | |
|       assertSame(this, derived);
 | |
|       return this._x;
 | |
|   }});
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.__proto__ = Base;
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     _x: 'derived',
 | |
|     testGetter() {
 | |
|       return super[x];
 | |
|     },
 | |
|     testGetterStrict() {
 | |
|       'use strict';
 | |
|       return super[x];
 | |
|     },
 | |
|     testGetterWithToString() {
 | |
|       var toStringCalled;
 | |
|       var o = {
 | |
|         toString: function() {
 | |
|           toStringCalled++;
 | |
|           return '42';
 | |
|         }
 | |
|       };
 | |
| 
 | |
|       toStringCalled = 0;
 | |
|       assertEquals('derived', super[o]);
 | |
|       assertEquals(1, toStringCalled);
 | |
| 
 | |
|       var eToThrow = new Error();
 | |
|       var oThrowsInToString = {
 | |
|         toString: function() {
 | |
|           throw eToThrow;
 | |
|         }
 | |
|       };
 | |
| 
 | |
|       var ex = null;
 | |
|       try {
 | |
|         super[oThrowsInToString];
 | |
|       } catch(e) { ex = e }
 | |
|       assertEquals(eToThrow, ex);
 | |
| 
 | |
|       var oReturnsNumericString = {
 | |
|         toString: function() {
 | |
|           return "42";
 | |
|         }
 | |
|       };
 | |
| 
 | |
|       assertEquals('derived', super[oReturnsNumericString]);
 | |
|       assertEquals('derived', super[42]);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   derived = new Derived();
 | |
|   assertEquals('derived', derived.testGetter());
 | |
|   derived = new Derived();
 | |
|   assertEquals('derived', derived.testGetterStrict());
 | |
|   derived = new Derived();
 | |
|   derived.testGetterWithToString();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSetter() {
 | |
|   function Base() {}
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     get x() {
 | |
|       return this._x;
 | |
|     },
 | |
|     set x(v) {
 | |
|       this._x = v;
 | |
|     },
 | |
|     _x: 'base'
 | |
|   };
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.__proto__ = Base;
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     _x: 'derived',
 | |
|     testSetter() {
 | |
|       assertEquals('foobar', super.x = 'foobar');
 | |
|       assertEquals('foobarabc', super.x += 'abc');
 | |
|     },
 | |
|     testSetterStrict() {
 | |
|       'use strict';
 | |
|       assertEquals('foobar', super.x = 'foobar');
 | |
|       assertEquals('foobarabc', super.x += 'abc');
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   var d = new Derived();
 | |
|   d.testSetter();
 | |
|   assertEquals('base', Base.prototype._x);
 | |
|   assertEquals('foobarabc', d._x);
 | |
|   d._x = '';
 | |
| 
 | |
|   d.testSetterStrict();
 | |
|   assertEquals('base', Base.prototype._x);
 | |
|   assertEquals('foobarabc', d._x);
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSetterNumericKeyed() {
 | |
|   var x = 42;
 | |
|   function Base() {}
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     _x: 'base'
 | |
|   };
 | |
| 
 | |
|   Object.defineProperty(Base.prototype, x,
 | |
|     { get: function() { return this._x; },
 | |
|       set: function(v) { this._x = v; }
 | |
|     });
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.__proto__ = Base;
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     _x: 'derived',
 | |
|     testSetter() {
 | |
|       assertEquals('foobar', super[x] = 'foobar');
 | |
|       assertEquals('foobarabc', super[x] += 'abc');
 | |
|     },
 | |
|     testSetterStrict() {
 | |
|       'use strict';
 | |
|       assertEquals('foobar', super[x] = 'foobar');
 | |
|       assertEquals('foobarabc', super[x] += 'abc');
 | |
|     },
 | |
|     testSetterWithToString() {
 | |
|       var toStringCalled;
 | |
|       var o = {
 | |
|         toString: function() {
 | |
|           toStringCalled++;
 | |
|           return x;
 | |
|         }
 | |
|       };
 | |
| 
 | |
|       toStringCalled = 0;
 | |
|       super[o] = 'set';
 | |
|       assertEquals(1, toStringCalled);
 | |
|       assertEquals('set', this._x);
 | |
| 
 | |
|       var eToThrow = new Error();
 | |
|       var oThrowsInToString = {
 | |
|         toString: function() {
 | |
|           throw eToThrow;
 | |
|         }
 | |
|       };
 | |
| 
 | |
|       var ex = null;
 | |
|       try {
 | |
|         super[oThrowsInToString] = 'xyz';
 | |
|       } catch(e) { ex = e }
 | |
|       assertEquals(eToThrow, ex);
 | |
|       assertEquals('set', this._x);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   var d = new Derived();
 | |
|   d.testSetter();
 | |
|   assertEquals('base', Base.prototype._x);
 | |
|   assertEquals('foobarabc', d._x);
 | |
|   d._x = '';
 | |
| 
 | |
|   d.testSetterStrict();
 | |
|   assertEquals('base', Base.prototype._x);
 | |
|   assertEquals('foobarabc', d._x);
 | |
| 
 | |
|   d = new Derived();
 | |
|   d.testSetterWithToString();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSetterKeyed() {
 | |
|   var x = 'x';
 | |
|   function Base() {}
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     get x() {
 | |
|       return this._x;
 | |
|     },
 | |
|     set x(v) {
 | |
|       this._x = v;
 | |
|     },
 | |
|     _x: 'base'
 | |
|   };
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.__proto__ = Base;
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     _x: 'derived',
 | |
|     testSetter() {
 | |
|       assertEquals('foobar', super[x] = 'foobar');
 | |
|       assertEquals('foobarabc', super[x] += 'abc');
 | |
|     },
 | |
|     testSetterStrict() {
 | |
|       'use strict';
 | |
|       assertEquals('foobar', super[x] = 'foobar');
 | |
|       assertEquals('foobarabc', super[x] += 'abc');
 | |
|     },
 | |
|     testSetterWithToString() {
 | |
|       var toStringCalled;
 | |
|       var o = {
 | |
|         toString: function() {
 | |
|           toStringCalled++;
 | |
|           return 'x';
 | |
|         }
 | |
|       };
 | |
| 
 | |
|       toStringCalled = 0;
 | |
|       super[o] = 'set';
 | |
|       assertEquals(1, toStringCalled);
 | |
|       assertEquals('set', this._x);
 | |
| 
 | |
|       var eToThrow = new Error();
 | |
|       var oThrowsInToString = {
 | |
|         toString: function() {
 | |
|           throw eToThrow;
 | |
|         }
 | |
|       };
 | |
| 
 | |
|       var ex = null;
 | |
|       try {
 | |
|         super[oThrowsInToString] = 'xyz';
 | |
|       } catch(e) { ex = e }
 | |
|       assertEquals(eToThrow, ex);
 | |
|       assertEquals('set', this._x);
 | |
| 
 | |
|       var oReturnsNumericString = {
 | |
|         toString: function() {
 | |
|           return "1";
 | |
|         }
 | |
|       };
 | |
| 
 | |
|       assertEquals('abc', super[oReturnsNumericString] = 'abc');
 | |
| 
 | |
|       assertEquals('set', this._x);
 | |
| 
 | |
|       assertEquals(10,  super[1] = 10);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   var d = new Derived();
 | |
|   d.testSetter();
 | |
|   assertEquals('base', Base.prototype._x);
 | |
|   assertEquals('foobarabc', d._x);
 | |
|   d._x = '';
 | |
|   d.testSetterStrict();
 | |
|   assertEquals('base', Base.prototype._x);
 | |
|   assertEquals('foobarabc', d._x);
 | |
| 
 | |
|   d = new Derived();
 | |
|   d.testSetterWithToString();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSetterDataProperties() {
 | |
|   function Base() {}
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     x: 'x from Base'
 | |
|   };
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     testSetter() {
 | |
|       assertEquals('x from Base', super.x);
 | |
|       super.x = 'data property';
 | |
|       assertEquals('x from Base', super.x);
 | |
|       assertEquals('data property', this.x);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   new Derived().testSetter();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestKeyedSetterDataProperties() {
 | |
|   var x = 'x';
 | |
|   function Base() {}
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     x: 'x from Base'
 | |
|   };
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     testSetter() {
 | |
|       assertEquals('x from Base', super[x]);
 | |
|       super[x] = 'data property';
 | |
|       assertEquals('x from Base', super[x]);
 | |
|       assertEquals('data property', this[x]);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   new Derived().testSetter();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestKeyedNumericSetterDataProperties() {
 | |
|   var x = 42;
 | |
|   function Base() {}
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     42: 'x from Base'
 | |
|   };
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     testSetter() {
 | |
|       assertEquals('x from Base', super[x]);
 | |
|       super[x] = 'data property';
 | |
|       assertEquals('x from Base', super[x]);
 | |
|       assertEquals('data property', this[x]);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   new Derived().testSetter();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestAccessorsOnPrimitives() {
 | |
|   var getCalled = 0;
 | |
|   var setCalled = 0;
 | |
|   function Base() {}
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     get x() {
 | |
|       getCalled++;
 | |
|       return 1;
 | |
|     },
 | |
|     set x(v) {
 | |
|       setCalled++;
 | |
|       return v;
 | |
|     },
 | |
|   };
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     testSetter() {
 | |
|       setCalled = 0;
 | |
|       getCalled = 0;
 | |
|       assertEquals('object', typeof this);
 | |
|       assertInstanceof(this, Number)
 | |
|       assertEquals(42, this.valueOf());
 | |
|       assertEquals(1, super.x);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
| 
 | |
|       assertEquals(5, super.x = 5);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(1, setCalled);
 | |
| 
 | |
|       assertEquals(6, super.x += 5);
 | |
|       assertEquals(2, getCalled);
 | |
|       assertEquals(2, setCalled);
 | |
| 
 | |
|       super.newProperty = 15;
 | |
|       assertEquals(15, this.newProperty);
 | |
|       assertEquals(undefined, super.newProperty);
 | |
|     },
 | |
|     testSetterStrict() {
 | |
|       'use strict';
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       assertTrue(42 === this);
 | |
| 
 | |
|       assertEquals(1, super.x);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
| 
 | |
|       assertEquals(5, super.x = 5);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(1, setCalled);
 | |
| 
 | |
|       assertEquals(6, super.x += 5);
 | |
|       assertEquals(2, getCalled);
 | |
|       assertEquals(2, setCalled);
 | |
| 
 | |
|       var ex;
 | |
|       try {
 | |
|         super.newProperty = 15;
 | |
|       } catch (e) { ex = e; }
 | |
|       assertInstanceof(ex, TypeError);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Derived.prototype.testSetter.call(42);
 | |
|   Derived.prototype.testSetterStrict.call(42);
 | |
| 
 | |
|   function DerivedFromString() {}
 | |
|   DerivedFromString.prototype = {
 | |
|     __proto__: String.prototype,
 | |
|     f() {
 | |
|       'use strict';
 | |
|       assertTrue(42 === this);
 | |
|       assertEquals(String.prototype.toString, super.toString);
 | |
|       var ex;
 | |
|       try {
 | |
|         super.toString();
 | |
|       } catch(e) { ex = e; }
 | |
| 
 | |
|       assertInstanceof(ex, TypeError);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   DerivedFromString.prototype.f.call(42);
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestKeyedAccessorsOnPrimitives() {
 | |
|   var x = 'x';
 | |
|   var newProperty = 'newProperty';
 | |
|   var toString = 'toString';
 | |
|   var getCalled = 0;
 | |
|   var setCalled = 0;
 | |
|   function Base() {}
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     get x() {
 | |
|       getCalled++;
 | |
|       return 1;
 | |
|     },
 | |
|     set x(v) {
 | |
|       setCalled++;
 | |
|       return v;
 | |
|     },
 | |
|   };
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     testSetter() {
 | |
|       setCalled = 0;
 | |
|       getCalled = 0;
 | |
|       assertEquals('object', typeof this);
 | |
|       assertInstanceof(this, Number)
 | |
|       assertEquals(42, this.valueOf());
 | |
|       assertEquals(1, super[x]);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
| 
 | |
|       assertEquals(5, super[x] = 5);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(1, setCalled);
 | |
| 
 | |
|       assertEquals(6, super[x] += 5);
 | |
|       assertEquals(2, getCalled);
 | |
|       assertEquals(2, setCalled);
 | |
| 
 | |
|       super[newProperty] = 15;
 | |
|       assertEquals(15, this[newProperty]);
 | |
|       assertEquals(undefined, super[newProperty]);
 | |
|     },
 | |
|     testSetterStrict() {
 | |
|       'use strict';
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       assertTrue(42 === this);
 | |
| 
 | |
|       assertEquals(1, super[x]);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
| 
 | |
|       assertEquals(5, super[x] = 5);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(1, setCalled);
 | |
| 
 | |
|       assertEquals(6, super[x] += 5);
 | |
|       assertEquals(2, getCalled);
 | |
|       assertEquals(2, setCalled);
 | |
| 
 | |
|       var ex;
 | |
|       try {
 | |
|         super[newProperty] = 15;
 | |
|       } catch (e) { ex = e; }
 | |
|       assertInstanceof(ex,TypeError);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   Derived.prototype.testSetter.call(42);
 | |
|   Derived.prototype.testSetterStrict.call(42);
 | |
| 
 | |
|   function DerivedFromString() {}
 | |
|   DerivedFromString.prototype = {
 | |
|     __proto__: String.prototype,
 | |
|     f() {
 | |
|       'use strict';
 | |
|       assertTrue(42 === this);
 | |
|       assertEquals(String.prototype.toString, super[toString]);
 | |
|       var ex;
 | |
|       try {
 | |
|         super[toString]();
 | |
|       } catch(e) { ex = e; }
 | |
| 
 | |
|       assertInstanceof(ex, TypeError);
 | |
|     }
 | |
|   };
 | |
|   DerivedFromString.prototype.f.call(42);
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestNumericKeyedAccessorsOnPrimitives() {
 | |
|   var x = 42;
 | |
|   var newProperty = 43;
 | |
|   var getCalled = 0;
 | |
|   var setCalled = 0;
 | |
|   function Base() {}
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|   };
 | |
| 
 | |
|   Object.defineProperty(Base.prototype, x, {
 | |
|     get: function() {
 | |
|       getCalled++;
 | |
|       return 1;
 | |
|     },
 | |
|     set: function(v) {
 | |
|       setCalled++;
 | |
|       return v;
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     testSetter() {
 | |
|       setCalled = 0;
 | |
|       getCalled = 0;
 | |
|       assertEquals('object', typeof this);
 | |
|       assertInstanceof(this, Number)
 | |
|       assertEquals(42, this.valueOf());
 | |
|       assertEquals(1, super[x]);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
| 
 | |
|       assertEquals(5, super[x] = 5);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(1, setCalled);
 | |
| 
 | |
|       assertEquals(6, super[x] += 5);
 | |
|       assertEquals(2, getCalled);
 | |
|       assertEquals(2, setCalled);
 | |
| 
 | |
|       super[newProperty] = 15;
 | |
|       assertEquals(15, this[newProperty]);
 | |
|       assertEquals(undefined, super[newProperty]);
 | |
|     },
 | |
|     testSetterStrict() {
 | |
|       'use strict';
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       assertTrue(42 === this);
 | |
| 
 | |
|       assertEquals(1, super[x]);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
| 
 | |
|       assertEquals(5, super[x] = 5);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(1, setCalled);
 | |
| 
 | |
|       assertEquals(6, super[x] += 5);
 | |
|       assertEquals(2, getCalled);
 | |
|       assertEquals(2, setCalled);
 | |
| 
 | |
|       var ex;
 | |
|       try {
 | |
|         super[newProperty] = 15;
 | |
|       } catch (e) { ex = e; }
 | |
|       assertInstanceof(ex, TypeError);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   Derived.prototype.testSetter.call(42);
 | |
|   Derived.prototype.testSetterStrict.call(42);
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestKeyedNumericSetterOnExotics() {
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     callSetterOnArray() {
 | |
|       super[42] = 1;
 | |
|     },
 | |
|     callStrictSetterOnString() {
 | |
|       'use strict';
 | |
|       assertEquals('string', typeof this);
 | |
|       assertTrue('abcdef' === this);
 | |
|       var ex = null;
 | |
|       try {
 | |
|         super[5] = 'q';
 | |
|       } catch(e) { ex = e; }
 | |
|       assertInstanceof(ex, TypeError);
 | |
| 
 | |
|       ex = null;
 | |
|       try {
 | |
|         super[1024] = 'q';
 | |
|       } catch(e) { ex = e; }
 | |
|       assertInstanceof(ex, TypeError);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   var x = [];
 | |
|   assertEquals(0, x.length);
 | |
|   Derived.prototype.callSetterOnArray.call(x);
 | |
|   assertEquals(43, x.length);
 | |
|   assertEquals(1, x[42]);
 | |
| 
 | |
|   var s = 'abcdef';
 | |
|   Derived.prototype.callStrictSetterOnString.call(s)
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSetterUndefinedProperties() {
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     mSloppy() {
 | |
|       assertEquals(undefined, super.x);
 | |
|       assertEquals(undefined, this.x);
 | |
|       super.x = 10;
 | |
|       assertEquals(10, this.x);
 | |
|       assertEquals(undefined, super.x);
 | |
|     },
 | |
|     mStrict() {
 | |
|       'use strict';
 | |
|       assertEquals(undefined, super.x);
 | |
|       assertEquals(undefined, this.x);
 | |
|       super.x = 10;
 | |
|       assertEquals(10, this.x);
 | |
|       assertEquals(undefined, super.x);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   var d = new Derived();
 | |
|   d.mSloppy();
 | |
|   assertEquals(10, d.x);
 | |
|   var d1 = new Derived();
 | |
|   d1.mStrict();
 | |
|   assertEquals(10, d.x);
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestKeyedSetterUndefinedProperties() {
 | |
|   var x = 'x';
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     mSloppy() {
 | |
|       assertEquals(undefined, super[x]);
 | |
|       assertEquals(undefined, this[x]);
 | |
|       super[x] = 10;
 | |
|       assertEquals(10, this[x]);
 | |
|       assertEquals(undefined, super[x]);
 | |
|     },
 | |
|     mStrict() {
 | |
|       'use strict';
 | |
|       assertEquals(undefined, super[x]);
 | |
|       assertEquals(undefined, this[x]);
 | |
|       super[x] = 10;
 | |
|       assertEquals(10, this[x]);
 | |
|       assertEquals(undefined, super[x]);
 | |
|     }
 | |
|   };
 | |
|   var d = new Derived();
 | |
|   d.mSloppy();
 | |
|   assertEquals(10, d.x);
 | |
|   var d1 = new Derived();
 | |
|   d1.mStrict();
 | |
|   assertEquals(10, d.x);
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestKeyedNumericSetterUndefinedProperties() {
 | |
|   var x = 42;
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     mSloppy() {
 | |
|       assertEquals(undefined, super[x]);
 | |
|       assertEquals(undefined, this[x]);
 | |
|       super[x] = 10;
 | |
|       assertEquals(10, this[x]);
 | |
|       assertEquals(undefined, super[x]);
 | |
|     },
 | |
|     mStrict() {
 | |
|       'use strict';
 | |
|       assertEquals(undefined, super[x]);
 | |
|       assertEquals(undefined, this[x]);
 | |
|       super[x] = 10;
 | |
|       assertEquals(10, this[x]);
 | |
|       assertEquals(undefined, super[x]);
 | |
|     }
 | |
|   };
 | |
|   var d = new Derived();
 | |
|   d.mSloppy();
 | |
|   assertEquals(10, d[x]);
 | |
|   var d1 = new Derived();
 | |
|   d1.mStrict();
 | |
|   assertEquals(10, d[x]);
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSetterCreatingOwnPropertiesReconfigurable() {
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     mSloppy() {
 | |
|       assertEquals(42, this.ownReadOnly);
 | |
|       super.ownReadOnly = 55;
 | |
|       assertSame(undefined, super.ownReadOnly);
 | |
|       assertEquals(42, this.ownReadOnly);
 | |
|       assertFalse(Base.prototype.hasOwnProperty('ownReadOnly'));
 | |
| 
 | |
|       assertEquals(15, this.ownReadonlyAccessor);
 | |
|       super.ownReadonlyAccessor = 25;
 | |
|       assertSame(undefined, super.ownReadonlyAccessor);
 | |
|       assertEquals(15, this.ownReadonlyAccessor);
 | |
|       assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor'));
 | |
| 
 | |
|       super.ownSetter = 35;
 | |
|       assertSame(undefined, super.ownSetter);
 | |
|       var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter');
 | |
|       assertTrue('set' in descr);
 | |
|       assertFalse(Base.prototype.hasOwnProperty('ownSetter'));
 | |
|     },
 | |
|     mStrict() {
 | |
|       'use strict';
 | |
|       assertEquals(42, this.ownReadOnly);
 | |
|       assertThrows(() => {super.ownReadOnly = 55}, TypeError);
 | |
|       assertSame(undefined, super.ownReadOnly);
 | |
|       assertEquals(42, this.ownReadOnly);
 | |
|       assertFalse(Base.prototype.hasOwnProperty('ownReadOnly'));
 | |
| 
 | |
|       assertEquals(15, this.ownReadonlyAccessor);
 | |
|       assertThrows(() => {super.ownReadonlyAccessor = 25}, TypeError);
 | |
|       assertSame(undefined, super.ownReadonlyAccessor);
 | |
|       assertEquals(15, this.ownReadonlyAccessor);
 | |
|       assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor'));
 | |
| 
 | |
|       assertThrows(() => {super.ownSetter = 35}, TypeError);
 | |
|       assertSame(undefined, super.ownSetter);
 | |
|       var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter');
 | |
|       assertTrue('set' in descr);
 | |
|       assertFalse(Base.prototype.hasOwnProperty('ownSetter'));
 | |
|     },
 | |
|   };
 | |
| 
 | |
|   var d = new Derived();
 | |
|   Object.defineProperty(d, 'ownReadOnly', {
 | |
|     value: 42,
 | |
|     writable: false,
 | |
|     configurable: true
 | |
|   });
 | |
|   Object.defineProperty(d, 'ownSetter', {
 | |
|     set: function() { assertUnreachable(); },
 | |
|     configurable: true
 | |
|   });
 | |
|   Object.defineProperty(d, 'ownReadonlyAccessor', {
 | |
|     get: function() { return 15; },
 | |
|     configurable: true
 | |
|   });
 | |
| 
 | |
|   d.mSloppy();
 | |
| 
 | |
|   var d = new Derived();
 | |
|   Object.defineProperty(d, 'ownReadOnly', {
 | |
|     value: 42,
 | |
|     writable: false,
 | |
|     configurable: true
 | |
|   });
 | |
|   Object.defineProperty(d, 'ownSetter', {
 | |
|     set: function() { assertUnreachable(); },
 | |
|     configurable: true
 | |
|   });
 | |
|   Object.defineProperty(d, 'ownReadonlyAccessor', {
 | |
|     get: function() { return 15; },
 | |
|     configurable: true
 | |
|   });
 | |
|   d.mStrict();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSetterCreatingOwnPropertiesNonConfigurable() {
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     mSloppy() {
 | |
|       assertEquals(42, this.ownReadOnly);
 | |
|       super.ownReadOnly = 55;
 | |
|       assertEquals(42, this.ownReadOnly);
 | |
|       var descr = Object.getOwnPropertyDescriptor(this, 'ownReadOnly');
 | |
|       assertEquals(42, descr.value);
 | |
|       assertFalse(descr.configurable);
 | |
|       assertFalse(descr.enumerable);
 | |
|       assertFalse(descr.writable);
 | |
|       assertFalse(Base.prototype.hasOwnProperty('ownReadOnly'));
 | |
| 
 | |
|       assertEquals(15, this.ownReadonlyAccessor);
 | |
|       super.ownReadonlyAccessor = 25;
 | |
|       assertSame(undefined, super.ownReadonlyAccessor);
 | |
|       assertEquals(15, this.ownReadonlyAccessor);
 | |
|       var descr = Object.getOwnPropertyDescriptor(this, 'ownReadonlyAccessor');
 | |
|       assertFalse(descr.configurable);
 | |
|       assertFalse(descr.enumerable);
 | |
|       assertFalse(Base.prototype.hasOwnProperty('ownReadonlyAccessor'));
 | |
| 
 | |
|       super.ownSetter = 35;
 | |
|       var descr = Object.getOwnPropertyDescriptor(this, 'ownSetter');
 | |
|       assertFalse(descr.configurable);
 | |
|       assertFalse(descr.enumerable);
 | |
|       assertFalse(Base.prototype.hasOwnProperty('ownSetter'));
 | |
|     },
 | |
|     mStrict() {
 | |
|       'use strict';
 | |
|       var ex;
 | |
|       assertEquals(42, this.ownReadOnly);
 | |
|       try {
 | |
|         super.ownReadOnly = 55;
 | |
|       } catch (e) {
 | |
|         ex = e;
 | |
|       }
 | |
|       assertInstanceof(ex, TypeError);
 | |
|       assertEquals(
 | |
|           "Cannot assign to read only property 'ownReadOnly' of object '#<Base>'",
 | |
|           ex.message);
 | |
|       assertEquals(42, this.ownReadOnly);
 | |
| 
 | |
|       ex = null;
 | |
|       assertEquals(15, this.ownReadonlyAccessor);
 | |
|       try {
 | |
|         super.ownReadonlyAccessor = 25;
 | |
|       } catch (e) {
 | |
|         ex = e;
 | |
|       }
 | |
|       assertInstanceof(ex, TypeError);
 | |
|       assertEquals('Cannot redefine property: ownReadonlyAccessor', ex.message);
 | |
|       assertEquals(15, this.ownReadonlyAccessor);
 | |
| 
 | |
|       ex = null;
 | |
|       try {
 | |
|         super.ownSetter = 35;
 | |
|       } catch (e) {
 | |
|         ex = e;
 | |
|       }
 | |
|       assertInstanceof(ex, TypeError);
 | |
|       assertEquals('Cannot redefine property: ownSetter', ex.message);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   var d = new Derived();
 | |
|   Object.defineProperty(d, 'ownReadOnly', { value : 42, writable : false });
 | |
|   Object.defineProperty(d, 'ownSetter',
 | |
|       { set : function() { assertUnreachable(); } });
 | |
|   Object.defineProperty(d, 'ownReadonlyAccessor',
 | |
|       { get : function() { return 15; }});
 | |
|   d.mSloppy();
 | |
|   d.mStrict();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSetterInForIn() {
 | |
|   var setCalled = 0;
 | |
|   var getCalled = 0;
 | |
|   function Base() {}
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     get x() {
 | |
|       getCalled++;
 | |
|       return 1;
 | |
|     },
 | |
|     set x(v) {
 | |
|       setCalled++;
 | |
|       this.x_.push(v);
 | |
|     },
 | |
|   };
 | |
| 
 | |
|   function Derived() {
 | |
|     this.x_ = [];
 | |
|   }
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     testIter() {
 | |
|       setCalled = 0;
 | |
|       getCalled = 0;
 | |
|       for (super.x in [1,2,3]) {}
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(3, setCalled);
 | |
|       assertEquals(["0", "1", "2"], this.x_);
 | |
|     },
 | |
|     testIterKeyed() {
 | |
|       setCalled = 0;
 | |
|       getCalled = 0;
 | |
|       for (super[x] in [1,2,3]) {}
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(3, setCalled);
 | |
|       assertEquals(["0","1","2"], this.x_);
 | |
| 
 | |
|       this.x_ = [];
 | |
|       setCalled = 0;
 | |
|       getCalled = 0;
 | |
|       var toStringCalled = 0;
 | |
|       var o = {toString: function () { toStringCalled++; return x }};
 | |
|       for (super[o] in [1,2,3]) {}
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(3, setCalled);
 | |
|       assertEquals(3, toStringCalled);
 | |
|       assertEquals(["0","1","2"], this.x_);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   new Derived().testIter();
 | |
| 
 | |
|   var x = 'x';
 | |
| 
 | |
|   new Derived().testIterKeyed();
 | |
| }());
 | |
| 
 | |
| 
 | |
| function TestKeyedSetterCreatingOwnPropertiesReconfigurable(ownReadOnly,
 | |
|     ownReadonlyAccessor, ownSetter) {
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     mSloppy() {
 | |
|       assertEquals(42, this[ownReadOnly]);
 | |
|       super[ownReadOnly] = 55;
 | |
|       assertSame(undefined, super[ownReadOnly]);
 | |
|       assertEquals(42, this[ownReadOnly]);
 | |
|       assertFalse(Base.prototype.hasOwnProperty(ownReadOnly));
 | |
| 
 | |
|       assertEquals(15, this[ownReadonlyAccessor]);
 | |
|       super[ownReadonlyAccessor] = 25;
 | |
|       assertSame(undefined, super[ownReadonlyAccessor]);
 | |
|       assertEquals(15, this[ownReadonlyAccessor]);
 | |
|       assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor));
 | |
| 
 | |
|       super[ownSetter] = 35;
 | |
|       assertSame(undefined, super[ownSetter]);
 | |
|       var descr = Object.getOwnPropertyDescriptor(this, ownSetter);
 | |
|       assertTrue('set' in descr);
 | |
|       assertFalse(Base.prototype.hasOwnProperty(ownSetter));
 | |
|     },
 | |
|     mStrict() {
 | |
|       'use strict';
 | |
|       assertEquals(42, this[ownReadOnly]);
 | |
|       assertThrows(() => {super[ownReadOnly] = 55}, TypeError);
 | |
|       assertSame(undefined, super[ownReadOnly]);
 | |
|       assertEquals(42, this[ownReadOnly]);
 | |
|       assertFalse(Base.prototype.hasOwnProperty(ownReadOnly));
 | |
| 
 | |
|       assertEquals(15, this[ownReadonlyAccessor]);
 | |
|       assertThrows(() => {super[ownReadonlyAccessor] = 25}, TypeError);
 | |
|       assertSame(undefined, super[ownReadonlyAccessor]);
 | |
|       assertEquals(15, this[ownReadonlyAccessor]);
 | |
|       assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor));
 | |
| 
 | |
|       assertThrows(() => {super[ownSetter] = 35}, TypeError);
 | |
|       assertSame(undefined, super[ownSetter]);
 | |
|       var descr = Object.getOwnPropertyDescriptor(this, ownSetter);
 | |
|       assertTrue('set' in descr);
 | |
|       assertFalse(Base.prototype.hasOwnProperty(ownSetter));
 | |
|     },
 | |
|   };
 | |
| 
 | |
|   var d = new Derived();
 | |
|   Object.defineProperty(d, ownReadOnly, {
 | |
|     value: 42,
 | |
|     writable: false,
 | |
|     configurable: true
 | |
|   });
 | |
|   Object.defineProperty(d, ownSetter, {
 | |
|     set: function() { assertUnreachable(); },
 | |
|     configurable: true
 | |
|   });
 | |
|   Object.defineProperty(d, ownReadonlyAccessor, {
 | |
|     get: function() { return 15; },
 | |
|     configurable: true
 | |
|   });
 | |
| 
 | |
|   d.mSloppy();
 | |
| 
 | |
|   var d = new Derived();
 | |
|   Object.defineProperty(d, ownReadOnly, {
 | |
|     value: 42,
 | |
|     writable: false,
 | |
|     configurable: true
 | |
|   });
 | |
|   Object.defineProperty(d, ownSetter, {
 | |
|     set: function() { assertUnreachable(); },
 | |
|     configurable: true
 | |
|   });
 | |
|   Object.defineProperty(d, ownReadonlyAccessor, {
 | |
|     get: function() { return 15; },
 | |
|     configurable: true
 | |
|   });
 | |
|   d.mStrict();
 | |
| }
 | |
| TestKeyedSetterCreatingOwnPropertiesReconfigurable('ownReadOnly',
 | |
|                                                    'ownReadonlyAccessor',
 | |
|                                                    'ownSetter');
 | |
| TestKeyedSetterCreatingOwnPropertiesReconfigurable(42, 43, 44);
 | |
| 
 | |
| 
 | |
| function TestKeyedSetterCreatingOwnPropertiesNonConfigurable(
 | |
|     ownReadOnly, ownReadonlyAccessor, ownSetter) {
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     mSloppy() {
 | |
|       assertEquals(42, this[ownReadOnly]);
 | |
|       super[ownReadOnly] = 55;
 | |
|       assertEquals(42, this[ownReadOnly]);
 | |
|       var descr = Object.getOwnPropertyDescriptor(this, ownReadOnly);
 | |
|       assertEquals(42, descr.value);
 | |
|       assertFalse(descr.configurable);
 | |
|       assertFalse(descr.enumerable);
 | |
|       assertFalse(descr.writable);
 | |
|       assertFalse(Base.prototype.hasOwnProperty(ownReadOnly));
 | |
| 
 | |
|       assertEquals(15, this[ownReadonlyAccessor]);
 | |
|       super[ownReadonlyAccessor] = 25;
 | |
|       assertSame(undefined, super[ownReadonlyAccessor]);
 | |
|       assertEquals(15, this[ownReadonlyAccessor]);
 | |
|       var descr = Object.getOwnPropertyDescriptor(this, ownReadonlyAccessor);
 | |
|       assertFalse(descr.configurable);
 | |
|       assertFalse(descr.enumerable);
 | |
|       assertFalse(Base.prototype.hasOwnProperty(ownReadonlyAccessor));
 | |
| 
 | |
|       super[ownSetter] = 35;
 | |
|       var descr = Object.getOwnPropertyDescriptor(this, ownSetter);
 | |
|       assertFalse(descr.configurable);
 | |
|       assertFalse(descr.enumerable);
 | |
|       assertFalse(Base.prototype.hasOwnProperty(ownSetter));
 | |
|     },
 | |
|     mStrict() {
 | |
|       'use strict';
 | |
|       var ex;
 | |
|       assertEquals(42, this[ownReadOnly]);
 | |
|       try {
 | |
|         super[ownReadOnly] = 55;
 | |
|       } catch (e) {
 | |
|         ex = e;
 | |
|       }
 | |
|       assertInstanceof(ex, TypeError);
 | |
|       assertEquals(
 | |
|           "Cannot assign to read only property '" + ownReadOnly +
 | |
|               "' of object '#<Base>'",
 | |
|           ex.message);
 | |
|       assertEquals(42, this[ownReadOnly]);
 | |
| 
 | |
|       ex = null;
 | |
|       assertEquals(15, this[ownReadonlyAccessor]);
 | |
|       try {
 | |
|         super[ownReadonlyAccessor] = 25;
 | |
|       } catch (e) {
 | |
|         ex = e;
 | |
|       }
 | |
|       assertInstanceof(ex, TypeError);
 | |
|       assertEquals('Cannot redefine property: ' + ownReadonlyAccessor,
 | |
|                    ex.message);
 | |
|       assertEquals(15, this[ownReadonlyAccessor]);
 | |
| 
 | |
|       ex = null;
 | |
|       try {
 | |
|         super[ownSetter] = 35;
 | |
|       } catch (e) {
 | |
|         ex = e;
 | |
|       }
 | |
|       assertInstanceof(ex, TypeError);
 | |
|       assertEquals('Cannot redefine property: ' + ownSetter, ex.message);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   var d = new Derived();
 | |
|   Object.defineProperty(d, ownReadOnly, { value : 42, writable : false });
 | |
|   Object.defineProperty(d, ownSetter,
 | |
|       { set : function() { assertUnreachable(); } });
 | |
|   Object.defineProperty(d, ownReadonlyAccessor,
 | |
|       { get : function() { return 15; }});
 | |
|   d.mSloppy();
 | |
|   d.mStrict();
 | |
| }
 | |
| TestKeyedSetterCreatingOwnPropertiesNonConfigurable('ownReadOnly',
 | |
|     'ownReadonlyAccessor', 'ownSetter');
 | |
| TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44);
 | |
| 
 | |
| 
 | |
| (function TestSetterNoProtoWalk() {
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
|   var getCalled;
 | |
|   var setCalled;
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     get x() { getCalled++; return 42; },
 | |
|     set x(v) { setCalled++; },
 | |
|     mSloppy() {
 | |
|       setCalled = 0;
 | |
|       getCalled = 0;
 | |
|       assertEquals(42, this.x);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
| 
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       this.x = 43;
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(1, setCalled);
 | |
| 
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       super.x = 15;
 | |
|       assertEquals(0, setCalled);
 | |
|       assertEquals(0, getCalled);
 | |
| 
 | |
|       assertEquals(15, this.x);
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
|     },
 | |
|     mStrict() {
 | |
|       'use strict';
 | |
|       setCalled = 0;
 | |
|       getCalled = 0;
 | |
|       assertEquals(42, this.x);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
| 
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       this.x = 43;
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(1, setCalled);
 | |
| 
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       super.x = 15;
 | |
|       assertEquals(0, setCalled);
 | |
|       assertEquals(0, getCalled);
 | |
| 
 | |
|       assertEquals(15, this.x);
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   new Derived().mSloppy();
 | |
|   new Derived().mStrict();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestKeyedSetterNoProtoWalk() {
 | |
|   var x = 'x';
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
|   var getCalled;
 | |
|   var setCalled;
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     get x() { getCalled++; return 42; },
 | |
|     set x(v) { setCalled++; },
 | |
|     mSloppy() {
 | |
|       setCalled = 0;
 | |
|       getCalled = 0;
 | |
|       assertEquals(42, this[x]);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
| 
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       this[x] = 43;
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(1, setCalled);
 | |
| 
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       super[x] = 15;
 | |
|       assertEquals(0, setCalled);
 | |
|       assertEquals(0, getCalled);
 | |
| 
 | |
|       assertEquals(15, this[x]);
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
|     },
 | |
|     mStrict() {
 | |
|       'use strict';
 | |
|       setCalled = 0;
 | |
|       getCalled = 0;
 | |
|       assertEquals(42, this[x]);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
| 
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       this[x] = 43;
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(1, setCalled);
 | |
| 
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       super[x] = 15;
 | |
|       assertEquals(0, setCalled);
 | |
|       assertEquals(0, getCalled);
 | |
| 
 | |
|       assertEquals(15, this[x]);
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   new Derived().mSloppy();
 | |
|   new Derived().mStrict();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestKeyedNumericSetterNoProtoWalk() {
 | |
|   var x = 42;
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
|   var getCalled;
 | |
|   var setCalled;
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     mSloppy() {
 | |
|       setCalled = 0;
 | |
|       getCalled = 0;
 | |
|       assertEquals(42, this[x]);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
| 
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       this[x] = 43;
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(1, setCalled);
 | |
| 
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       super[x] = 15;
 | |
|       assertEquals(0, setCalled);
 | |
|       assertEquals(0, getCalled);
 | |
| 
 | |
|       assertEquals(15, this[x]);
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
|     },
 | |
|     mStrict() {
 | |
|       'use strict';
 | |
|       setCalled = 0;
 | |
|       getCalled = 0;
 | |
|       assertEquals(42, this[x]);
 | |
|       assertEquals(1, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
| 
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       this[x] = 43;
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(1, setCalled);
 | |
| 
 | |
|       getCalled = 0;
 | |
|       setCalled = 0;
 | |
|       super[x] = 15;
 | |
|       assertEquals(0, setCalled);
 | |
|       assertEquals(0, getCalled);
 | |
| 
 | |
|       assertEquals(15, this[x]);
 | |
|       assertEquals(0, getCalled);
 | |
|       assertEquals(0, setCalled);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   Object.defineProperty(Derived.prototype, x, {
 | |
|     get: function() { getCalled++; return 42; },
 | |
|     set: function(v) { setCalled++; }
 | |
|   });
 | |
| 
 | |
|   new Derived().mSloppy();
 | |
|   new Derived().mStrict();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSetterDoesNotReconfigure() {
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Derived.prototype,
 | |
|     mStrict(){
 | |
|       'use strict';
 | |
|       super.nonEnumConfig = 5;
 | |
|       var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig');
 | |
|       assertEquals(5, d1.value);
 | |
|       assertTrue(d1.configurable);
 | |
|       assertFalse(d1.enumerable);
 | |
| 
 | |
|       super.nonEnumNonConfig = 5;
 | |
|       var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig');
 | |
|       assertEquals(5, d1.value);
 | |
|       assertFalse(d1.configurable);
 | |
|       assertFalse(d1.enumerable);
 | |
|     },
 | |
|     mSloppy(){
 | |
|       super.nonEnumConfig = 42;
 | |
|       var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig');
 | |
|       assertEquals(42, d1.value);
 | |
|       assertTrue(d1.configurable);
 | |
|       assertFalse(d1.enumerable);
 | |
| 
 | |
|       super.nonEnumNonConfig = 42;
 | |
|       var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig');
 | |
|       assertEquals(42, d1.value);
 | |
|       assertFalse(d1.configurable);
 | |
|       assertFalse(d1.enumerable);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   var d = new Derived();
 | |
|   Object.defineProperty(d, 'nonEnumConfig',
 | |
|       { value : 0, enumerable : false, configurable : true, writable : true });
 | |
|   Object.defineProperty(d, 'nonEnumNonConfig',
 | |
|       { value : 0, enumerable : false, configurable : false, writable : true });
 | |
|   d.mStrict();
 | |
|   d.mSloppy();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestKeyedSetterDoesNotReconfigure() {
 | |
|   var nonEnumConfig = 'nonEnumConfig';
 | |
|   var nonEnumNonConfig = 'nonEnumNonConfig';
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
| 
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     mStrict(){
 | |
|       'use strict';
 | |
|       super[nonEnumConfig] = 5;
 | |
|       var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
 | |
|       assertEquals(5, d1.value);
 | |
|       assertTrue(d1.configurable);
 | |
|       assertFalse(d1.enumerable);
 | |
| 
 | |
|       super[nonEnumNonConfig] = 5;
 | |
|       var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
 | |
|       assertEquals(5, d1.value);
 | |
|       assertFalse(d1.configurable);
 | |
|       assertFalse(d1.enumerable);
 | |
|     },
 | |
|     mSloppy(){
 | |
|       super[nonEnumConfig] = 42;
 | |
|       var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
 | |
|       assertEquals(42, d1.value);
 | |
|       assertTrue(d1.configurable);
 | |
|       assertFalse(d1.enumerable);
 | |
| 
 | |
|       super[nonEnumNonConfig] = 42;
 | |
|       var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
 | |
|       assertEquals(42, d1.value);
 | |
|       assertFalse(d1.configurable);
 | |
|       assertFalse(d1.enumerable);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   var d = new Derived();
 | |
|   Object.defineProperty(d, nonEnumConfig,
 | |
|       { value : 0, enumerable : false, configurable : true, writable : true });
 | |
|   Object.defineProperty(d, nonEnumNonConfig,
 | |
|       { value : 0, enumerable : false, configurable : false, writable : true });
 | |
|   d.mStrict();
 | |
|   d.mSloppy();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestKeyedNumericSetterDoesNotReconfigure() {
 | |
|   var nonEnumConfig = 42;
 | |
|   var nonEnumNonConfig = 43;
 | |
|   function Base() {}
 | |
|   function Derived() {}
 | |
| 
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     mStrict(){
 | |
|       'use strict';
 | |
|       super[nonEnumConfig] = 5;
 | |
|       var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
 | |
|       assertEquals(5, d1.value);
 | |
|       assertTrue(d1.configurable);
 | |
|       assertFalse(d1.enumerable);
 | |
| 
 | |
|       super[nonEnumNonConfig] = 5;
 | |
|       var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
 | |
|       assertEquals(5, d1.value);
 | |
|       assertFalse(d1.configurable);
 | |
|       assertFalse(d1.enumerable);
 | |
|     },
 | |
|     mSloppy(){
 | |
|       super[nonEnumConfig] = 42;
 | |
|       var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
 | |
|       assertEquals(42, d1.value);
 | |
|       assertTrue(d1.configurable);
 | |
|       assertFalse(d1.enumerable);
 | |
| 
 | |
|       super[nonEnumNonConfig] = 42;
 | |
|       var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
 | |
|       assertEquals(42, d1.value);
 | |
|       assertFalse(d1.configurable);
 | |
|       assertFalse(d1.enumerable);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   var d = new Derived();
 | |
|   Object.defineProperty(d, nonEnumConfig,
 | |
|       { value : 0, enumerable : false, configurable : true, writable : true });
 | |
|   Object.defineProperty(d, nonEnumNonConfig,
 | |
|       { value : 0, enumerable : false, configurable : false, writable : true });
 | |
|   d.mStrict();
 | |
|   d.mSloppy();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestCountOperations() {
 | |
|   function Base() {}
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     get x() {
 | |
|       return this._x;
 | |
|     },
 | |
|     set x(v) {
 | |
|       this._x = v;
 | |
|     },
 | |
|     _x: 1
 | |
|   };
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.__proto__ = Base;
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     _x: 2,
 | |
|     testCounts() {
 | |
|       assertEquals(2, this._x);
 | |
|       assertEquals(2, super.x);
 | |
|       super.x++;
 | |
|       assertEquals(3, super.x);
 | |
|       ++super.x;
 | |
|       assertEquals(4, super.x);
 | |
|       assertEquals(4, super.x++);
 | |
|       assertEquals(5, super.x);
 | |
|       assertEquals(6, ++super.x);
 | |
|       assertEquals(6, super.x);
 | |
|       assertEquals(6, this._x);
 | |
| 
 | |
|       super.x--;
 | |
|       assertEquals(5, super.x);
 | |
|       --super.x;
 | |
|       assertEquals(4, super.x);
 | |
|       assertEquals(4, super.x--);
 | |
|       assertEquals(3, super.x);
 | |
|       assertEquals(2, --super.x);
 | |
|       assertEquals(2, super.x);
 | |
|       assertEquals(2, this._x);
 | |
|     }
 | |
|   };
 | |
|   new Derived().testCounts();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestKeyedCountOperations() {
 | |
|   var x = 'x';
 | |
|   function Base() {}
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     get x() {
 | |
|       return this._x;
 | |
|     },
 | |
|     set x(v) {
 | |
|       this._x = v;
 | |
|     },
 | |
|     _x: 1
 | |
|   };
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.__proto__ = Base;
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     _x: 2,
 | |
|     testCounts() {
 | |
|       assertEquals(2, this._x);
 | |
|       assertEquals(2, super[x]);
 | |
|       super[x]++;
 | |
|       assertEquals(3, super[x]);
 | |
|       ++super[x];
 | |
|       assertEquals(4, super[x]);
 | |
|       assertEquals(4, super[x]++);
 | |
|       assertEquals(5, super[x]);
 | |
|       assertEquals(6, ++super[x]);
 | |
|       assertEquals(6, super[x]);
 | |
|       assertEquals(6, this._x);
 | |
| 
 | |
|       super[x]--;
 | |
|       assertEquals(5, super[x]);
 | |
|       --super[x];
 | |
|       assertEquals(4, super[x]);
 | |
|       assertEquals(4, super[x]--);
 | |
|       assertEquals(3, super[x]);
 | |
|       assertEquals(2, --super[x]);
 | |
|       assertEquals(2, super[x]);
 | |
|       assertEquals(2, this._x);
 | |
|     }
 | |
|   };
 | |
|   new Derived().testCounts();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestKeyedNumericCountOperations() {
 | |
|   var x = 42;
 | |
|   function Base() {}
 | |
|   Base.prototype = {
 | |
|     constructor: Base,
 | |
|     _x: 1
 | |
|   };
 | |
| 
 | |
|   Object.defineProperty(Base.prototype, x, {
 | |
|     get: function() { return this._x; },
 | |
|     set: function(v) { this._x = v;; }
 | |
|   });
 | |
| 
 | |
|   function Derived() {}
 | |
|   Derived.__proto__ = Base;
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     _x: 2,
 | |
|     testCounts() {
 | |
|       assertEquals(2, this._x);
 | |
|       assertEquals(2, super[x]);
 | |
|       super[x]++;
 | |
|       assertEquals(3, super[x]);
 | |
|       ++super[x];
 | |
|       assertEquals(4, super[x]);
 | |
|       assertEquals(4, super[x]++);
 | |
|       assertEquals(5, super[x]);
 | |
|       assertEquals(6, ++super[x]);
 | |
|       assertEquals(6, super[x]);
 | |
|       assertEquals(6, this._x);
 | |
| 
 | |
|       super[x]--;
 | |
|       assertEquals(5, super[x]);
 | |
|       --super[x];
 | |
|       assertEquals(4, super[x]);
 | |
|       assertEquals(4, super[x]--);
 | |
|       assertEquals(3, super[x]);
 | |
|       assertEquals(2, --super[x]);
 | |
|       assertEquals(2, super[x]);
 | |
|       assertEquals(2, this._x);
 | |
|     }
 | |
|   };
 | |
|   new Derived().testCounts();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSetterSuperNonWritable() {
 | |
|   function Base() {}
 | |
|   Object.defineProperty(Base.prototype, 'x', { value : 27, writable: false });
 | |
|   function Derived() {}
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     mSloppy() {
 | |
|       assertEquals(27, super.x);
 | |
|       assertEquals(27, this.x);
 | |
|       super.x = 10;
 | |
|       assertEquals(27, super.x);
 | |
|       assertEquals(27, this.x);
 | |
|     },
 | |
|     mStrict() {
 | |
|       'use strict';
 | |
|       assertEquals(27, super.x);
 | |
|       assertEquals(27, this.x);
 | |
|       var ex = null;
 | |
|       try { super.x = 10; } catch(e) { ex = e; }
 | |
|       assertInstanceof(ex, TypeError);
 | |
|       assertEquals(27, super.x);
 | |
|       assertEquals(27, this.x);
 | |
|     }
 | |
|   };
 | |
|   new Derived().mSloppy();
 | |
|   new Derived().mStrict();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSetterKeyedSuperNonWritable() {
 | |
|   var x = 'xyz';
 | |
|   function Base() {}
 | |
|   Object.defineProperty(Base.prototype, x, { value : 27, writable: false });
 | |
|   function Derived() {}
 | |
| 
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     mSloppy() {
 | |
|       assertEquals(27, super[x]);
 | |
|       assertEquals(27, this[x]);
 | |
|       super[x] = 10;
 | |
|       assertEquals(27, super[x]);
 | |
|       assertEquals(27, this[x]);
 | |
|     },
 | |
|     mStrict() {
 | |
|       'use strict';
 | |
|       assertEquals(27, super[x]);
 | |
|       assertEquals(27, this[x]);
 | |
|       var ex = null;
 | |
|       try { super[x] = 10; } catch(e) { ex = e; }
 | |
|       assertInstanceof(ex, TypeError);
 | |
|       assertEquals(27, super[x]);
 | |
|       assertEquals(27, this[x]);
 | |
|     }
 | |
|   };
 | |
|   new Derived().mSloppy();
 | |
|   new Derived().mStrict();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSetterKeyedNumericSuperNonWritable() {
 | |
|   var x = 42;
 | |
|   function Base() {}
 | |
|   Object.defineProperty(Base.prototype, x, { value : 27, writable: false });
 | |
|   function Derived() {}
 | |
| 
 | |
|   Derived.prototype = {
 | |
|     __proto__: Base.prototype,
 | |
|     constructor: Derived,
 | |
|     mSloppy() {
 | |
|       assertEquals(27, super[x]);
 | |
|       assertEquals(27, this[x]);
 | |
|       super[x] = 10;
 | |
|       assertEquals(27, super[x]);
 | |
|       assertEquals(27, this[x]);
 | |
|     },
 | |
|     mStrict() {
 | |
|       'use strict';
 | |
|       assertEquals(27, super[x]);
 | |
|       assertEquals(27, this[x]);
 | |
|       var ex = null;
 | |
|       try { super[x] = 10; } catch(e) { ex = e; }
 | |
|       assertInstanceof(ex, TypeError);
 | |
|       assertEquals(27, super[x]);
 | |
|       assertEquals(27, this[x]);
 | |
|     }
 | |
|   };
 | |
|   new Derived().mSloppy();
 | |
|   new Derived().mStrict();
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSuperCall() {
 | |
|   'use strict';
 | |
| 
 | |
|   var baseCalled = 0;
 | |
|   var derivedCalled = 0;
 | |
|   var derivedDerivedCalled = 0;
 | |
| 
 | |
|   class Base {
 | |
|     constructor() {
 | |
|       baseCalled++;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   class Derived extends Base {
 | |
|     constructor() {
 | |
|       let r = super();
 | |
|       assertEquals(this, r);
 | |
|       derivedCalled++;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   assertEquals(Base, Base.prototype.constructor);
 | |
|   assertEquals(Base.prototype, Derived.prototype.__proto__);
 | |
| 
 | |
|   baseCalled = 0;
 | |
|   derivedCalled = 0;
 | |
|   new Derived();
 | |
|   assertEquals(1, baseCalled);
 | |
|   assertEquals(1, derivedCalled);
 | |
| 
 | |
|   class DerivedDerived extends Derived {
 | |
|     constructor() {
 | |
|       let r = super();
 | |
|       assertEquals(this, r);
 | |
|       derivedDerivedCalled++;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   baseCalled = 0;
 | |
|   derivedCalled = 0;
 | |
|   derivedDerivedCalled = 0;
 | |
|   new DerivedDerived();
 | |
|   assertEquals(1, baseCalled);
 | |
|   assertEquals(1, derivedCalled);
 | |
|   assertEquals(1, derivedDerivedCalled);
 | |
| 
 | |
|   class Base2 {
 | |
|     constructor(v) {
 | |
|       this.fromBase = v;
 | |
|     }
 | |
|   }
 | |
|   class Derived2 extends Base2 {
 | |
|     constructor(v1, v2) {
 | |
|       let r = super(v1);
 | |
|       assertEquals(this, r);
 | |
|       this.fromDerived = v2;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   var d = new Derived2("base", "derived");
 | |
|   assertEquals("base", d.fromBase);
 | |
|   assertEquals("derived", d.fromDerived);
 | |
| 
 | |
|   var calls = 0;
 | |
|   class G {
 | |
|     constructor() {
 | |
|       calls++;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   class F extends Object {
 | |
|     constructor() {
 | |
|       super();
 | |
|     }
 | |
|   }
 | |
|   F.__proto__ = G;
 | |
|   new F();
 | |
|   assertEquals(1, calls);
 | |
|   F.__proto__ = function() {};
 | |
|   new F();
 | |
|   assertEquals(1, calls);
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestExtendsObject() {
 | |
|   'use strict';
 | |
|   class F extends Object { }
 | |
|   var f = new F(42);
 | |
| 
 | |
|   assertInstanceof(f, F);
 | |
|   assertInstanceof(f, Object);
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSuperCallErrorCases() {
 | |
|   'use strict';
 | |
|   class T extends Object {
 | |
|     constructor() {
 | |
|       super();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   T.__proto__ = null;
 | |
|   assertThrows(function() { new T(); }, TypeError);
 | |
| }());
 | |
| 
 | |
| 
 | |
| (function TestSuperPropertyInEval() {
 | |
|   'use strict';
 | |
|   let y = 3;
 | |
|   class Base {
 | |
|     m() { return 1; }
 | |
|     get x() { return 2; }
 | |
|   }
 | |
|   class Derived extends Base {
 | |
|     evalM() {
 | |
|       assertEquals(1, eval('super.m()'));
 | |
|     }
 | |
|     evalX() {
 | |
|       assertEquals(2, eval('super.x'));
 | |
|     }
 | |
|     globalEval1() {
 | |
|       assertThrows('super.x', SyntaxError);
 | |
|       assertThrows('super.m()', SyntaxError);
 | |
|     }
 | |
|     globalEval2() {
 | |
|       super.x;
 | |
|       assertThrows('super.x', SyntaxError);
 | |
|       assertThrows('super.m()', SyntaxError);
 | |
|     }
 | |
|   }
 | |
|   let d = new Derived();
 | |
|   d.globalEval1();
 | |
|   d.globalEval2();
 | |
|   d.evalM();
 | |
|   d.evalX();
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function TestSuperPropertyInArrow() {
 | |
|   'use strict';
 | |
|   let y = 3;
 | |
|   class Base {
 | |
|     m() { return 1; }
 | |
|     get x() { return 2; }
 | |
|   }
 | |
|   class Derived extends Base {
 | |
|     arrow() {
 | |
|       assertSame(super.x, (() => super.x)());
 | |
|       assertSame(super.m(), (() => super.m())());
 | |
|       return (() => super.m())();
 | |
|     }
 | |
|   }
 | |
|   let d = new Derived();
 | |
|   assertSame(1, d.arrow());
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function TestSuperInOtherScopes() {
 | |
|   var p = {x: 99};
 | |
|   var o0 = {__proto__: p, f() { return eval("'use strict'; super.x") }};
 | |
|   assertEquals(p.x, o0.f());
 | |
|   var o1 = {__proto__: p, f() { with ({}) return super.x }};
 | |
|   assertEquals(p.x, o1.f());
 | |
|   var o2 = {__proto__: p, f({a}) { return super.x }};
 | |
|   assertEquals(p.x, o2.f({}));
 | |
|   var o3 = {__proto__: p, f(...a) { return super.x }};
 | |
|   assertEquals(p.x, o3.f());
 | |
|   var o4 = {__proto__: p, f() { 'use strict'; { let x; return super.x } }};
 | |
|   assertEquals(p.x, o4.f());
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function TestSuperCallInOtherScopes() {
 | |
|   class C {constructor() { this.x = 99 }}
 | |
|   class D0 extends C {constructor() { eval("'use strict'; super()") }}
 | |
|   assertEquals(99, (new D0).x);
 | |
|   class D2 extends C {constructor({a}) { super() }}
 | |
|   assertEquals(99, (new D2({})).x);
 | |
|   class D3 extends C {constructor(...a) { super() }}
 | |
|   assertEquals(99, (new D3()).x);
 | |
|   class D4 extends C {constructor() { { let x; super() } }}
 | |
|   assertEquals(99, (new D4).x);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function TestSuperCallInEval() {
 | |
|   'use strict';
 | |
|   class Base {
 | |
|     constructor(x) {
 | |
|       this.x = x;
 | |
|     }
 | |
|   }
 | |
|   class Derived extends Base {
 | |
|     constructor(x) {
 | |
|       let r = eval('super(x)');
 | |
|       assertEquals(this, r);
 | |
|     }
 | |
|   }
 | |
|   let d = new Derived(42);
 | |
|   assertSame(42, d.x);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function TestSuperCallInArrow() {
 | |
|   'use strict';
 | |
|   class Base {
 | |
|     constructor(x) {
 | |
|       this.x = x;
 | |
|     }
 | |
|   }
 | |
|   class Derived extends Base {
 | |
|     constructor(x) {
 | |
|       let r = (() => super(x))();
 | |
|       assertEquals(this, r);
 | |
|     }
 | |
|   }
 | |
|   let d = new Derived(42);
 | |
|   assertSame(42, d.x);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function TestSuperCallEscapes() {
 | |
|   'use strict';
 | |
|   class Base {
 | |
|     constructor(x) {
 | |
|       this.x = x;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   let f;
 | |
|   class Derived extends Base {
 | |
|     constructor() {
 | |
|       f = () => super(2);
 | |
|     }
 | |
|   }
 | |
|   assertThrows(function() {
 | |
|     new Derived();
 | |
|   }, ReferenceError);
 | |
| 
 | |
|   let o = f();
 | |
|   assertEquals(2, o.x);
 | |
|   assertInstanceof(o, Derived);
 | |
| 
 | |
|   assertThrows(function() {
 | |
|     f();
 | |
|   }, ReferenceError);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function TestSuperCallInLoop() {
 | |
|   'use strict';
 | |
|   class Base {
 | |
|     constructor(x) {
 | |
|       this.x = x;
 | |
|     }
 | |
|   }
 | |
|   class Derived extends Base {
 | |
|     constructor(x, n) {
 | |
|       for (var i = 0; i < n; ++i) {
 | |
|         super(x);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   let o = new Derived(23, 1);
 | |
|   assertEquals(23, o.x);
 | |
|   assertInstanceof(o, Derived);
 | |
| 
 | |
|   assertThrows("new Derived(42, 0)", ReferenceError);
 | |
|   assertThrows("new Derived(65, 2)", ReferenceError);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function TestSuperCallReentrant() {
 | |
|   'use strict';
 | |
|   class Base {
 | |
|     constructor(fun) {
 | |
|       this.x = fun();
 | |
|     }
 | |
|   }
 | |
|   class Derived extends Base {
 | |
|     constructor(x) {
 | |
|       let f = () => super(() => x)
 | |
|       super(f);
 | |
|     }
 | |
|   }
 | |
|   assertThrows("new Derived(23)", ReferenceError);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function TestSuperCallSpreadInEval() {
 | |
|   'use strict';
 | |
|   class Base {
 | |
|     constructor(x) {
 | |
|       this.x = x;
 | |
|     }
 | |
|   }
 | |
|   class Derived extends Base {
 | |
|     constructor(x) {
 | |
|       let r = eval('super(...[x])');
 | |
|       assertEquals(this, r);
 | |
|     }
 | |
|   }
 | |
|   let d = new Derived(42);
 | |
|   assertSame(42, d.x);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function TestSuperCallSpreadInArrow() {
 | |
|   'use strict';
 | |
|   class Base {
 | |
|     constructor(x) {
 | |
|       this.x = x;
 | |
|     }
 | |
|   }
 | |
|   class Derived extends Base {
 | |
|     constructor(x) {
 | |
|       let r = (() => super(...[x]))();
 | |
|       assertEquals(this, r);
 | |
|     }
 | |
|   }
 | |
|   let d = new Derived(42);
 | |
|   assertSame(42, d.x);
 | |
| })();
 | |
| 
 | |
| (function TestNullSuperPropertyLoad() {
 | |
|   var obj = {
 | |
|     __proto__: null,
 | |
|     named() { return super.x },
 | |
|     keyed() { return super[5] }
 | |
|   };
 | |
|   assertThrows(obj.named, TypeError);
 | |
|   assertThrows(obj.keyed, TypeError);
 | |
|   class C extends null {
 | |
|     named() { return super.x }
 | |
|     keyed() { return super[5] }
 | |
|   }
 | |
|   assertThrows(C.prototype.named, TypeError);
 | |
|   assertThrows(C.prototype.keyed, TypeError);
 | |
| })();
 | |
| 
 | |
| (function TestNullSuperPropertyStore() {
 | |
|   var obj = {
 | |
|     __proto__: null,
 | |
|     named() { super.x = 42 },
 | |
|     keyed() { super[5] = 42 }
 | |
|   };
 | |
|   assertThrows(obj.named, TypeError);
 | |
|   assertThrows(obj.keyed, TypeError);
 | |
|   class C extends null {
 | |
|     named() { super.x = 42 }
 | |
|     keyed() { super[5] = 42 }
 | |
|   }
 | |
|   assertThrows(C.prototype.named, TypeError);
 | |
|   assertThrows(C.prototype.keyed, TypeError);
 | |
| })();
 |