Source code

Revision control

Copy as Markdown

Other Tools

class base {
constructor() { }
method() { this.methodCalled++; }
}
class derived extends base {
constructor() { super(); this.methodCalled = 0; }
// Test orderings of various evaluations relative to the superbase
// Unlike in regular element evaluation, the propVal is evaluated before
// checking the starting object ([[HomeObject]].[[Prototype]])
testElem() { super[ruin()]; }
// The starting object for looking up super.method is determined before
// ruin() is called.
testProp() { super.method(ruin()); }
// The entire super.method property lookup has concluded before the args
// are evaluated
testPropCallDeleted() { super.method(()=>delete base.prototype.method); }
// The starting object for looking up super["prop"] is determined before
// ruin() is called.
testElemAssign() { super["prop"] = ruin(); }
// Test the normal assignment gotchas
testAssignElemPropValChange() {
let x = "prop1";
super[x] = (()=>(x = "prop2", 0))();
assertEq(this.prop1, 0);
assertEq(this.prop2, undefined);
}
testAssignProp() {
Object.defineProperty(base.prototype, "piggy",
{
configurable: true,
set() { throw "WEE WEE WEE WEE"; }
});
// The property lookup is noted, but not actually evaluated, until the
// right hand side is. Please don't make the piggy cry.
super.piggy = (() => delete base.prototype.piggy)();
}
testCompoundAssignProp() {
let getterCalled = false;
Object.defineProperty(base.prototype, "horse",
{
configurable: true,
get() { getterCalled = true; return "Of course"; },
set() { throw "NO!"; }
});
super.horse += (()=>(delete base.prototype.horse, ", of course!"))();
assertEq(getterCalled, true);
// So, is a horse a horse?
assertEq(this.horse, "Of course, of course!");
}
}
function ruin() {
Object.setPrototypeOf(derived.prototype, null);
return 5;
}
function reset() {
Object.setPrototypeOf(derived.prototype, base.prototype);
}
let instance = new derived();
assertThrowsInstanceOf(() => instance.testElem(), TypeError);
reset();
instance.testProp();
assertEq(instance.methodCalled, 1);
reset();
instance.testPropCallDeleted();
assertEq(instance.methodCalled, 2);
instance.testElemAssign();
assertEq(instance.prop, 5);
reset();
instance.testAssignElemPropValChange();
instance.testAssignProp();
instance.testCompoundAssignProp();
if (typeof reportCompare === 'function')
reportCompare(0,0,"OK");