summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/class/classHeritage.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/tests/non262/class/classHeritage.js97
1 files changed, 97 insertions, 0 deletions
diff --git a/js/src/tests/non262/class/classHeritage.js b/js/src/tests/non262/class/classHeritage.js
new file mode 100644
index 0000000000..478c23fc21
--- /dev/null
+++ b/js/src/tests/non262/class/classHeritage.js
@@ -0,0 +1,97 @@
+// 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");