X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fv8%2Ftest%2Fmjsunit%2Fharmony%2Fsuper.js;h=d972407520ecda11269608609d185b0cbbc38ca8;hb=1afa4dd80ef85af7c90efaea6959db1d92330844;hp=89fb4b1c1689ef60c1c6aec3813d4b09170d728b;hpb=90762837333c13ccf56f2ad88e4481fc71e8d281;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/v8/test/mjsunit/harmony/super.js b/src/v8/test/mjsunit/harmony/super.js index 89fb4b1..d972407 100644 --- a/src/v8/test/mjsunit/harmony/super.js +++ b/src/v8/test/mjsunit/harmony/super.js @@ -18,6 +18,8 @@ function fDerived() { assertEquals("Base this is Derived", super.f()); + var a = super.x; + assertEquals(15, a); assertEquals(15, super.x); assertEquals(27, this.x); @@ -34,6 +36,77 @@ assertEquals("Derived", new Derived().f()); }()); + +(function TestSuperKeyedLoads() { + var x = 'x'; + var derivedDataProperty = 'derivedDataProperty'; + var f = 'f'; + function Base() { } + function Derived() { + this[derivedDataProperty] = 'xxx'; + } + Derived.prototype = Object.create(Base.prototype); + + function fBase() { return "Base " + this.toString(); } + + Base.prototype[f] = fBase.toMethod(Base.prototype); + + function fDerived() { + assertEquals("Base this is Derived", super[f]()); + var a = super[x]; + assertEquals(15, a); + assertEquals(15, super[x]); + assertEquals(27, this[x]); + + return "Derived" + } + + Base.prototype[x] = 15; + Base.prototype.toString = function() { return "this is Base"; }; + Derived.prototype.toString = function() { return "this is Derived"; }; + Derived.prototype[x] = 27; + Derived.prototype[f] = fDerived.toMethod(Derived.prototype); + + assertEquals("Base this is Base", new Base().f()); + assertEquals("Derived", new Derived().f()); +}()); + + +(function TestSuperNumericKeyedLoads() { + var x = 1; + var derivedDataProperty = 2; + var f = 3; + function Base() { } + function Derived() { + this[derivedDataProperty] = 'xxx'; + } + Derived.prototype = Object.create(Base.prototype); + + function fBase() { return "Base " + this.toString(); } + + Base.prototype[f] = fBase.toMethod(Base.prototype); + + function fDerived() { + assertEquals("Base this is Derived", super[f]()); + var a = super[x]; + assertEquals(15, a); + assertEquals(15, super[x]); + assertEquals(27, this[x]); + + return "Derived" + } + + Base.prototype[x] = 15; + Base.prototype.toString = function() { return "this is Base"; }; + Derived.prototype.toString = function() { return "this is Derived"; }; + Derived.prototype[x] = 27; + Derived.prototype[f] = fDerived.toMethod(Derived.prototype); + + assertEquals("Base this is Base", new Base()[f]()); + assertEquals("Derived", new Derived()[f]()); +}()); + + (function TestSuperKeywordNonMethod() { function f() { super.unknown(); @@ -65,12 +138,149 @@ Derived.prototype.testGetter = function() { return super.x; }.toMethod(Derived.prototype); + Derived.prototype.testGetterStrict = function() { + 'use strict'; + return super.x; + }.toMethod(Derived.prototype); + 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' + }; + Derived.prototype.testGetter = function() { + return super[x]; + }.toMethod(Derived.prototype); + Derived.prototype.testGetterStrict = function() { + 'use strict'; + return super[x]; + }.toMethod(Derived.prototype); + Derived.prototype.testGetterWithToString = function() { + 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]); + }.toMethod(Derived.prototype); + 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' + }; + Derived.prototype.testGetter = function() { + return super[x]; + }.toMethod(Derived.prototype); + Derived.prototype.testGetterStrict = function() { + 'use strict'; + return super[x]; + }.toMethod(Derived.prototype); + + Derived.prototype.testGetterWithToString = function() { + 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]); + }.toMethod(Derived.prototype); derived = new Derived(); assertEquals('derived', derived.testGetter()); + derived = new Derived(); + assertEquals('derived', derived.testGetterStrict()); + derived = new Derived(); + derived.testGetterWithToString(); }()); -/* - * TODO[dslomov]: named stores and keyed loads/stores not implemented yet. + (function TestSetter() { function Base() {} Base.prototype = { @@ -92,24 +302,37 @@ _x: 'derived' }; Derived.prototype.testSetter = function() { - super.x = 'foobar'; - }.toMethod(Derived.prototype); + assertEquals('foobar', super.x = 'foobar'); + assertEquals('foobarabc', super.x += 'abc'); + }.toMethod(Derived.prototype); var d = new Derived(); d.testSetter(); assertEquals('base', Base.prototype._x); - assertEquals('foobar', d._x); + assertEquals('foobarabc', d._x); + d._x = ''; + Derived.prototype.testSetterStrict = function() { + 'use strict'; + assertEquals('foobar', super.x = 'foobar'); + assertEquals('foobarabc', super.x += 'abc'); + }.toMethod(Derived.prototype); + d.testSetterStrict(); + assertEquals('base', Base.prototype._x); + assertEquals('foobarabc', d._x); }()); -(function TestKeyedGetter() { +(function TestSetterNumericKeyed() { + var x = 42; function Base() {} Base.prototype = { constructor: Base, _x: 'base' }; - Object.defineProperty(Base.prototype, '0', - { get: function() { return this._x; } }); + Object.defineProperty(Base.prototype, x, + { get: function() { return this._x; }, + set: function(v) { this._x = v; } + }); function Derived() {} Derived.__proto__ = Base; @@ -118,10 +341,1523 @@ constructor: Derived, _x: 'derived' }; - Derived.prototype.testGetter = function() { - return super[0]; - }.toMethod(Derived.prototype); - assertEquals('derived', new Derived()[0]); - // assertEquals('derived', new Derived().testGetter()); + Derived.prototype.testSetter = function() { + assertEquals('foobar', super[x] = 'foobar'); + assertEquals('foobarabc', super[x] += 'abc'); + }.toMethod(Derived.prototype); + var d = new Derived(); + d.testSetter(); + assertEquals('base', Base.prototype._x); + assertEquals('foobarabc', d._x); + d._x = ''; + Derived.prototype.testSetterStrict = function() { + 'use strict'; + assertEquals('foobar', super[x] = 'foobar'); + assertEquals('foobarabc', super[x] += 'abc'); + }.toMethod(Derived.prototype); + d.testSetterStrict(); + assertEquals('base', Base.prototype._x); + assertEquals('foobarabc', d._x); + + + Derived.prototype.testSetterWithToString = function() { + 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); + }.toMethod(Derived.prototype); + 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' + }; + Derived.prototype.testSetter = function() { + assertEquals('foobar', super[x] = 'foobar'); + assertEquals('foobarabc', super[x] += 'abc'); + }.toMethod(Derived.prototype); + var d = new Derived(); + d.testSetter(); + assertEquals('base', Base.prototype._x); + assertEquals('foobarabc', d._x); + d._x = ''; + Derived.prototype.testSetterStrict = function() { + 'use strict'; + assertEquals('foobar', super[x] = 'foobar'); + assertEquals('foobarabc', super[x] += 'abc'); + }.toMethod(Derived.prototype); + d.testSetterStrict(); + assertEquals('base', Base.prototype._x); + assertEquals('foobarabc', d._x); + + + Derived.prototype.testSetterWithToString = function() { + 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); + }.toMethod(Derived.prototype); + 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, + }; + + Derived.prototype.testSetter = function() { + assertEquals('x from Base', super.x); + super.x = 'data property'; + assertEquals('x from Base', super.x); + assertEquals('data property', this.x); + }.toMethod(Derived.prototype); + + 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, + }; + + Derived.prototype.testSetter = function() { + assertEquals('x from Base', super[x]); + super[x] = 'data property'; + assertEquals('x from Base', super[x]); + assertEquals('data property', this[x]); + }.toMethod(Derived.prototype); + + 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, + }; + + Derived.prototype.testSetter = function() { + assertEquals('x from Base', super[x]); + super[x] = 'data property'; + assertEquals('x from Base', super[x]); + assertEquals('data property', this[x]); + }.toMethod(Derived.prototype); + + 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, + }; + Derived.prototype.testSetter = function() { + setCalled = 0; + getCalled = 0; + assertEquals('object', typeof this); + assertTrue(this instanceof 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); + }.toMethod(Derived.prototype); + + Derived.prototype.testSetterStrict = function() { + '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; } + assertTrue(ex instanceof TypeError); + }.toMethod(Derived.prototype); + + Derived.prototype.testSetter.call(42); + Derived.prototype.testSetterStrict.call(42); + + function DerivedFromString() {} + DerivedFromString.prototype = Object.create(String.prototype); + + function f() { + 'use strict'; + assertTrue(42 === this); + assertEquals(String.prototype.toString, super.toString); + var ex; + try { + super.toString(); + } catch(e) { ex = e; } + + assertTrue(ex instanceof TypeError); + } + f.toMethod(DerivedFromString.prototype).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, + }; + Derived.prototype.testSetter = function() { + setCalled = 0; + getCalled = 0; + assertEquals('object', typeof this); + assertTrue(this instanceof 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]); + }.toMethod(Derived.prototype); + + Derived.prototype.testSetterStrict = function() { + '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; } + assertTrue(ex instanceof TypeError); + }.toMethod(Derived.prototype); + + Derived.prototype.testSetter.call(42); + Derived.prototype.testSetterStrict.call(42); + + function DerivedFromString() {} + DerivedFromString.prototype = Object.create(String.prototype); + + function f() { + 'use strict'; + assertTrue(42 === this); + assertEquals(String.prototype.toString, super[toString]); + var ex; + try { + super[toString](); + } catch(e) { ex = e; } + + assertTrue(ex instanceof TypeError); + } + f.toMethod(DerivedFromString.prototype).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, + }; + Derived.prototype.testSetter = function() { + setCalled = 0; + getCalled = 0; + assertEquals('object', typeof this); + assertTrue(this instanceof 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]); + }.toMethod(Derived.prototype); + + Derived.prototype.testSetterStrict = function() { + '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; } + assertTrue(ex instanceof TypeError); + }.toMethod(Derived.prototype); + + Derived.prototype.testSetter.call(42); + Derived.prototype.testSetterStrict.call(42); +}()); + + +(function TestKeyedNumericSetterOnExotics() { + function Base() {} + function Derived() {} + Derived.prototype = { __proto__: Base.prototype }; + + Derived.prototype.callSetterOnArray = function() { + super[42] = 1; + }.toMethod(Derived.prototype); + + Derived.prototype.callStrictSetterOnString = function() { + 'use strict'; + assertEquals('string', typeof this); + assertTrue('abcdef' === this); + var ex = null; + try { + super[5] = 'q'; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + + ex = null; + try { + super[1024] = 'q'; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + }.toMethod(Derived.prototype); + + 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 }; + Derived.prototype.mSloppy = function () { + assertEquals(undefined, super.x); + assertEquals(undefined, this.x); + super.x = 10; + assertEquals(10, this.x); + assertEquals(undefined, super.x); + }.toMethod(Derived.prototype); + + Derived.prototype.mStrict = function () { + 'use strict'; + assertEquals(undefined, super.x); + assertEquals(undefined, this.x); + super.x = 10; + assertEquals(10, this.x); + assertEquals(undefined, super.x); + }.toMethod(Derived.prototype); + 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 }; + Derived.prototype.mSloppy = function () { + assertEquals(undefined, super[x]); + assertEquals(undefined, this[x]); + super[x] = 10; + assertEquals(10, this[x]); + assertEquals(undefined, super[x]); + }.toMethod(Derived.prototype); + + Derived.prototype.mStrict = function () { + 'use strict'; + assertEquals(undefined, super[x]); + assertEquals(undefined, this[x]); + super[x] = 10; + assertEquals(10, this[x]); + assertEquals(undefined, super[x]); + }.toMethod(Derived.prototype); + 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 }; + Derived.prototype.mSloppy = function () { + assertEquals(undefined, super[x]); + assertEquals(undefined, this[x]); + super[x] = 10; + assertEquals(10, this[x]); + assertEquals(undefined, super[x]); + }.toMethod(Derived.prototype); + + Derived.prototype.mStrict = function () { + 'use strict'; + assertEquals(undefined, super[x]); + assertEquals(undefined, this[x]); + super[x] = 10; + assertEquals(10, this[x]); + assertEquals(undefined, super[x]); + }.toMethod(Derived.prototype); + var d = new Derived(); + d.mSloppy(); + assertEquals(10, d[x]); + var d1 = new Derived(); + d1.mStrict(); + assertEquals(10, d[x]); +}()); + + +(function TestSetterCreatingOwnProperties() { + function Base() {} + function Derived() {} + Derived.prototype = { __proto__ : Base.prototype }; + var setterCalled; + + Derived.prototype.mSloppy = function() { + assertEquals(42, this.ownReadOnly); + super.ownReadOnly = 55; + assertEquals(42, this.ownReadOnly); + + assertEquals(15, this.ownReadonlyAccessor); + super.ownReadonlyAccessor = 55; + assertEquals(15, this.ownReadonlyAccessor); + + setterCalled = 0; + super.ownSetter = 42; + assertEquals(1, setterCalled); + }.toMethod(Derived.prototype); + + Derived.prototype.mStrict = function() { + 'use strict'; + assertEquals(42, this.ownReadOnly); + var ex; + try { + super.ownReadOnly = 55; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(42, this.ownReadOnly); + + assertEquals(15, this.ownReadonlyAccessor); + ex = null; + try { + super.ownReadonlyAccessor = 55; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(15, this.ownReadonlyAccessor); + + setterCalled = 0; + super.ownSetter = 42; + assertEquals(1, setterCalled); + }.toMethod(Derived.prototype); + + var d = new Derived(); + Object.defineProperty(d, 'ownReadOnly', { value : 42, writable : false }); + Object.defineProperty(d, 'ownSetter', + { set : function() { setterCalled++; } }); + 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, + }; + + Derived.prototype.testIter = function() { + setCalled = 0; + getCalled = 0; + for (super.x in [1,2,3]) {} + assertEquals(0, getCalled); + assertEquals(3, setCalled); + assertEquals(["0","1","2"], this.x_); + }.toMethod(Derived.prototype); + + new Derived().testIter(); + + var x = 'x'; + Derived.prototype.testIterKeyed = function() { + 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_); + }.toMethod(Derived.prototype); + + new Derived().testIterKeyed(); +}()); + + +(function TestKeyedSetterCreatingOwnProperties() { + var ownReadOnly = 'ownReadOnly'; + var ownReadonlyAccessor = 'ownReadonlyAccessor'; + var ownSetter = 'ownSetter'; + function Base() {} + function Derived() {} + Derived.prototype = { __proto__ : Base.prototype }; + var setterCalled; + + Derived.prototype.mSloppy = function() { + assertEquals(42, this[ownReadOnly]); + super[ownReadOnly] = 55; + assertEquals(42, this[ownReadOnly]); + + assertEquals(15, this[ownReadonlyAccessor]); + super[ownReadonlyAccessor] = 55; + assertEquals(15, this[ownReadonlyAccessor]); + + setterCalled = 0; + super[ownSetter] = 42; + assertEquals(1, setterCalled); + }.toMethod(Derived.prototype); + + Derived.prototype.mStrict = function() { + 'use strict'; + assertEquals(42, this[ownReadOnly]); + var ex; + try { + super[ownReadOnly] = 55; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(42, this[ownReadOnly]); + + assertEquals(15, this[ownReadonlyAccessor]); + ex = null; + try { + super[ownReadonlyAccessor] = 55; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(15, this[ownReadonlyAccessor]); + + setterCalled = 0; + super[ownSetter] = 42; + assertEquals(1, setterCalled); + }.toMethod(Derived.prototype); + + var d = new Derived(); + Object.defineProperty(d, 'ownReadOnly', { value : 42, writable : false }); + Object.defineProperty(d, 'ownSetter', + { set : function() { setterCalled++; } }); + Object.defineProperty(d, 'ownReadonlyAccessor', + { get : function() { return 15; }}); + d.mSloppy(); + d.mStrict(); +}()); + + +(function TestKeyedNumericSetterCreatingOwnProperties() { + var ownReadOnly = 42; + var ownReadonlyAccessor = 43; + var ownSetter = 44; + function Base() {} + function Derived() {} + Derived.prototype = { __proto__ : Base.prototype }; + var setterCalled; + + Derived.prototype.mSloppy = function() { + assertEquals(42, this[ownReadOnly]); + super[ownReadOnly] = 55; + assertEquals(42, this[ownReadOnly]); + + assertEquals(15, this[ownReadonlyAccessor]); + super[ownReadonlyAccessor] = 55; + assertEquals(15, this[ownReadonlyAccessor]); + + setterCalled = 0; + super[ownSetter] = 42; + assertEquals(1, setterCalled); + }.toMethod(Derived.prototype); + + Derived.prototype.mStrict = function() { + 'use strict'; + assertEquals(42, this[ownReadOnly]); + var ex; + try { + super[ownReadOnly] = 55; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(42, this[ownReadOnly]); + + assertEquals(15, this[ownReadonlyAccessor]); + ex = null; + try { + super[ownReadonlyAccessor] = 55; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(15, this[ownReadonlyAccessor]); + + setterCalled = 0; + super[ownSetter] = 42; + assertEquals(1, setterCalled); + }.toMethod(Derived.prototype); + + var d = new Derived(); + Object.defineProperty(d, ownReadOnly, { value : 42, writable : false }); + Object.defineProperty(d, ownSetter, + { set : function() { setterCalled++; } }); + Object.defineProperty(d, ownReadonlyAccessor, + { get : function() { return 15; }}); + d.mSloppy(); + d.mStrict(); +}()); + + +(function TestSetterNoProtoWalk() { + function Base() {} + function Derived() {} + var getCalled; + var setCalled; + Derived.prototype = { + __proto__ : Base.prototype, + get x() { getCalled++; return 42; }, + set x(v) { setCalled++; } + }; + + Derived.prototype.mSloppy = function() { + 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); + + }.toMethod(Derived.prototype); + + Derived.prototype.mStrict = function() { + '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); + + }.toMethod(Derived.prototype); + + 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++; } + }; + + Derived.prototype.mSloppy = function() { + 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); + + }.toMethod(Derived.prototype); + + Derived.prototype.mStrict = function() { + '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); + + }.toMethod(Derived.prototype); + + new Derived().mSloppy(); + new Derived().mStrict(); +}()); + + +(function TestKeyedNumericSetterNoProtoWalk() { + var x = 42; + function Base() {} + function Derived() {} + var getCalled; + var setCalled; + Derived.prototype = { + __proto__ : Base.prototype, + }; + + Object.defineProperty(Derived.prototype, x, { + get: function() { getCalled++; return 42; }, + set: function(v) { setCalled++; } + }); + + Derived.prototype.mSloppy = function() { + 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); + + }.toMethod(Derived.prototype); + + Derived.prototype.mStrict = function() { + '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); + + }.toMethod(Derived.prototype); + + new Derived().mSloppy(); + new Derived().mStrict(); +}()); + + +(function TestSetterDoesNotReconfigure() { + function Base() {} + function Derived() {} + + Derived.prototype.mStrict = function (){ + '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); + }.toMethod(Derived.prototype); + + Derived.prototype.mSloppy = function (){ + 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); + }.toMethod(Derived.prototype); + + 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 }; + + Derived.prototype.mStrict = function (){ + '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); + }.toMethod(Derived.prototype); + + Derived.prototype.mSloppy = function (){ + 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); + }.toMethod(Derived.prototype); + + 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 }; + + Derived.prototype.mStrict = function (){ + '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); + }.toMethod(Derived.prototype); + + Derived.prototype.mSloppy = function (){ + 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); + }.toMethod(Derived.prototype); + + 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 + }; + + Derived.prototype.testCounts = function() { + 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); + }.toMethod(Derived.prototype); + 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 + }; + + Derived.prototype.testCounts = function() { + 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); + }.toMethod(Derived.prototype); + 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 + }; + + Derived.prototype.testCounts = function() { + 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); + }.toMethod(Derived.prototype); + 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 }; + + Derived.prototype.mSloppy = function() { + assertEquals(27, super.x); + assertEquals(27, this.x); + super.x = 10; + assertEquals(27, super.x); + assertEquals(27, this.x); + }.toMethod(Derived.prototype); + Derived.prototype.mStrict = function() { + 'use strict'; + assertEquals(27, super.x); + assertEquals(27, this.x); + var ex = null; + try { super.x = 10; } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(27, super.x); + assertEquals(27, this.x); + }.toMethod(Derived.prototype); + 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 }; + + Derived.prototype.mSloppy = function() { + assertEquals(27, super[x]); + assertEquals(27, this[x]); + super[x] = 10; + assertEquals(27, super[x]); + assertEquals(27, this[x]); + }.toMethod(Derived.prototype); + Derived.prototype.mStrict = function() { + 'use strict'; + assertEquals(27, super[x]); + assertEquals(27, this[x]); + var ex = null; + try { super[x] = 10; } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(27, super[x]); + assertEquals(27, this[x]); + }.toMethod(Derived.prototype); + 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 }; + + Derived.prototype.mSloppy = function() { + assertEquals(27, super[x]); + assertEquals(27, this[x]); + super[x] = 10; + assertEquals(27, super[x]); + assertEquals(27, this[x]); + }.toMethod(Derived.prototype); + Derived.prototype.mStrict = function() { + 'use strict'; + assertEquals(27, super[x]); + assertEquals(27, this[x]); + var ex = null; + try { super[x] = 10; } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(27, super[x]); + assertEquals(27, this[x]); + }.toMethod(Derived.prototype); + new Derived().mSloppy(); + new Derived().mStrict(); +}()); + + +function Subclass(base, constructor) { + var homeObject = { + __proto__: base.prototype, + constructor: constructor + }; + constructor.__proto__ = base; + constructor.prototype = homeObject; + // not doing toMethod: home object is not required for + // super constructor calls. + return constructor; +} + +(function TestSuperCall() { + var baseCalled = 0; + var derivedCalled = 0; + var derivedDerivedCalled = 0; + + function Base() { + baseCalled++; + } + + var Derived = Subclass(Base, function () { + super(); + derivedCalled++; + }); + + assertEquals(Base, Base.prototype.constructor); + assertEquals(Base.prototype, Derived.prototype.__proto__); + + baseCalled = 0; + derivedCalled = 0; + new Derived(); + assertEquals(1, baseCalled); + assertEquals(1, derivedCalled); + + var DerivedDerived = Subclass(Derived, function () { + super(); + derivedDerivedCalled++; + }); + + baseCalled = 0; + derivedCalled = 0; + derivedDerivedCalled = 0; + new DerivedDerived(); + assertEquals(1, baseCalled); + assertEquals(1, derivedCalled); + assertEquals(1, derivedDerivedCalled); + + function Base2(v) { + this.fromBase = v; + } + var Derived2 = Subclass(Base2, function (v1, v2) { + super(v1); + this.fromDerived = v2; + }); + + var d = new Derived2("base", "derived"); + assertEquals("base", d.fromBase); + assertEquals("derived", d.fromDerived); + + function ImplicitSubclassOfFunction() { + super(); + this.x = 123; + } + + var o = new ImplicitSubclassOfFunction(); + assertEquals(123, o.x); + + var calls = 0; + function G() { + calls++; + } + function F() { + super(); + } + F.__proto__ = G; + new F(); + assertEquals(1, calls); + F.__proto__ = function() {}; + new F(); + assertEquals(1, calls); +}()); + + +(function TestNewSuper() { + var baseCalled = 0; + var derivedCalled = 0; + + function Base() { + baseCalled++; + this.x = 15; + } + + + var Derived = Subclass(Base, function() { + baseCalled = 0; + var b = new super(); + assertEquals(1, baseCalled) + assertEquals(Base.prototype, b.__proto__); + assertEquals(15, b.x); + assertEquals(undefined, this.x); + derivedCalled++; + }); + + derivedCalled = 0; + new Derived(); + assertEquals(1, derivedCalled); +}()); + + +(function TestSuperCallErrorCases() { + function T() { + super(); + } + T.__proto__ = null; + // Spec says ReferenceError here, but for other IsCallable failures + // we throw TypeError. + // Filed https://bugs.ecmascript.org/show_bug.cgi?id=3282 + assertThrows(function() { new T(); }, TypeError); + + function T1() { + var b = new super(); + } + T1.__proto = null; + assertThrows(function() { new T1(); }, TypeError); }()); -*/