| // It's an error to have a non-constructor as your heritage |
| assertThrowsInstanceOf(() => eval(`class a extends Math.sin { |
| constructor() { } |
| }`), TypeError); |
| assertThrowsInstanceOf(() => eval(`(class a extends Math.sin { |
| constructor() { } |
| })`), TypeError); |
| |
| // Unless it's null, in which case it works like a normal class, except that |
| // the prototype object does not inherit from Object.prototype. |
| class basic { |
| constructor() { } |
| } |
| class nullExtends extends null { |
| constructor() { } |
| } |
| var nullExtendsExpr = class extends null { constructor() { } }; |
| |
| assertEq(Object.getPrototypeOf(basic), Function.prototype); |
| assertEq(Object.getPrototypeOf(basic.prototype), Object.prototype); |
| |
| for (let extension of [nullExtends, nullExtendsExpr]) { |
| assertEq(Object.getPrototypeOf(extension), Function.prototype); |
| assertEq(Object.getPrototypeOf(extension.prototype), null); |
| } |
| |
| var baseMethodCalled; |
| var staticMethodCalled; |
| var overrideCalled; |
| class base { |
| constructor() { }; |
| method() { baseMethodCalled = true; } |
| static staticMethod() { staticMethodCalled = true; } |
| override() { overrideCalled = "base" } |
| } |
| class derived extends base { |
| constructor() { super(); }; |
| override() { overrideCalled = "derived"; } |
| } |
| var derivedExpr = class extends base { |
| constructor() { super(); }; |
| override() { overrideCalled = "derived"; } |
| }; |
| |
| // Make sure we get the right object layouts. |
| for (let extension of [derived, derivedExpr]) { |
| baseMethodCalled = false; |
| staticMethodCalled = false; |
| overrideCalled = ""; |
| // Make sure we get the right object layouts. |
| assertEq(Object.getPrototypeOf(extension), base); |
| assertEq(Object.getPrototypeOf(extension.prototype), base.prototype); |
| |
| // We do inherit the methods, right? |
| (new extension()).method(); |
| assertEq(baseMethodCalled, true); |
| |
| // But we can still override them? |
| (new extension()).override(); |
| assertEq(overrideCalled, "derived"); |
| |
| // What about the statics? |
| extension.staticMethod(); |
| assertEq(staticMethodCalled, true); |
| } |
| |
| // Gotta extend an object, or null. |
| function nope() { |
| class Foo extends "Bar" { |
| constructor() { } |
| } |
| } |
| function nopeExpr() { |
| (class extends "Bar" { |
| constructor() { } |
| }); |
| } |
| assertThrowsInstanceOf(nope, TypeError); |
| assertThrowsInstanceOf(nopeExpr, TypeError); |
| |
| // The .prototype of the extension must be an object, or null. |
| nope.prototype = "not really, no"; |
| function stillNo() { |
| class Foo extends nope { |
| constructor() { } |
| } |
| } |
| function stillNoExpr() { |
| (class extends nope { |
| constructor() { } |
| }); |
| } |
| assertThrowsInstanceOf(stillNo, TypeError); |
| assertThrowsInstanceOf(stillNoExpr, TypeError); |
| |
| if (typeof reportCompare === "function") |
| reportCompare(0, 0, "OK"); |