// Reviewed function shouldBe(expected, actual, msg) { if (msg === void 0) msg = ""; else msg = " for " + msg; if (actual !== expected) throw new Error("bad value" + msg + ": " + actual + ". Expected " + expected); } function shouldBeAsync(expected, run, msg) { let actual; var hadError = false; run().then(function(value) { actual = value; }, function(error) { hadError = true; actual = error; }); drainMicrotasks(); if (hadError) throw actual; shouldBe(expected, actual, msg); } class BaseClass { baseClassValue() { return "BaseClassValue"; } get property() { return "test!"; } } class ChildClass extends BaseClass { asyncSuperProp() { return async x => super.baseClassValue(); } asyncSuperProp2() { return async x => { return super.baseClassValue(); } } } shouldBeAsync("BaseClassValue", new ChildClass().asyncSuperProp()); shouldBeAsync("BaseClassValue", new ChildClass().asyncSuperProp2()); class ChildClass2 extends BaseClass { constructor() { return async (self = super()) => self.baseClassValue() + ' ' + super.property; } } shouldBeAsync("BaseClassValue test!", new ChildClass2()); var error = undefined; var value = undefined; class A { constructor() { this._id = 'class-id'; } } const childA1 = new class extends A { constructor() { var f = async (a=super()) => { return 'abc'; } f().then( val => {value = val; }, err => { error = err;}); } } drainMicrotasks(); shouldBe(childA1._id, 'class-id'); shouldBe(value, 'abc'); shouldBe(error, undefined); value = undefined; error = undefined; const childA2 = new class extends A { constructor() { var f = async (a) => { super(); return 'abc'; } f().then( val => {value = val; }, err => { error = err;}); } } drainMicrotasks(); shouldBe(childA2._id, 'class-id'); shouldBe(value, 'abc'); shouldBe(error, undefined); value = undefined; error = undefined; const childA3 = new class extends A { constructor() { var f = async (a = super()) => { super(); return 'abc'; } f().then( val => {value = val; }, err => { error = err;}); } } drainMicrotasks(); shouldBe(childA3._id, 'class-id'); shouldBe(value, undefined); shouldBe(error.toString(), 'ReferenceError: \'super()\' can\'t be called more than once in a constructor.'); let childA4; let catchError; error = undefined; try { childA4 = new class extends A { constructor() { var f = async (a) => { await 'await value'; super(); return 'abc'; } f().then(val => { value = val; }, err => { error = err; }); } } } catch (err) { catchError = err; } drainMicrotasks(); shouldBe(childA4, undefined); shouldBe(value, 'abc'); shouldBe(error, undefined); shouldBe(catchError.toString(), 'ReferenceError: Cannot access uninitialized variable.'); catchError = undefined; error = undefined; value = undefined; const childA5 = new class extends A { constructor() { var f = async (a) => { super(); await 'await value'; return 'abc'; } f().then(val => { value = val; }, err => { error = err; }); } } drainMicrotasks(); shouldBe(childA5._id, 'class-id'); shouldBe(value, 'abc'); shouldBe(error, undefined); shouldBe(catchError, undefined); function checkClass(classSource) { let base1 = undefined; let error = undefined; let value = undefined; let catchError = undefined; try { base1 = eval(classSource); drainMicrotasks(); } catch (err) { catchError = err; } shouldBe(base1, undefined); shouldBe(value, undefined); shouldBe(error, undefined); shouldBe(catchError.toString(), 'SyntaxError: super is not valid in this context.'); } checkClass(`new class { constructor() { var f = async (a) => { super(); return 'abc'; } f().then(val => { value = val; }, err => { error = err; }); } }`); checkClass(`new class { constructor() { var f = async (a) => { await 'p'; super(); return 'abc'; } f().then(val => { value = val; }, err => { error = err; }); } }`); checkClass(`new class { constructor() { var f = async (a) => { super(); await 'p'; return 'abc'; } f().then(val => { value = val; }, err => { error = err; }); } }`); checkClass(`new class extends A { method() { var f = async (a) => { super(); return 'abc'; } f().then(val => { value = val; }, err => { error = err; }); } }`); checkClass(`new class extends A { get prop() { var f = async (a) => { super(); return 'abc'; } f().then(val => { value = val; }, err => { error = err; }); } }`); checkClass(`new class extends A { set prop(_value) { var f = async (a) => { super(); return 'abc'; } f().then(val => { value = val; }, err => { error = err; }); } }`);