summaryrefslogtreecommitdiffstats
path: root/js/src/tests/ecma_6/Class/superPropOrdering.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/ecma_6/Class/superPropOrdering.js')
-rw-r--r--js/src/tests/ecma_6/Class/superPropOrdering.js93
1 files changed, 93 insertions, 0 deletions
diff --git a/js/src/tests/ecma_6/Class/superPropOrdering.js b/js/src/tests/ecma_6/Class/superPropOrdering.js
new file mode 100644
index 000000000..1374d52c1
--- /dev/null
+++ b/js/src/tests/ecma_6/Class/superPropOrdering.js
@@ -0,0 +1,93 @@
+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");