mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 02:57:44 +00:00
Libraries: Move to Userland/Libraries/
This commit is contained in:
parent
dc28c07fa5
commit
13d7c09125
1857 changed files with 266 additions and 274 deletions
|
@ -0,0 +1,35 @@
|
|||
test("extending function", () => {
|
||||
class A extends function () {
|
||||
this.foo = 10;
|
||||
} {}
|
||||
|
||||
expect(new A().foo).toBe(10);
|
||||
});
|
||||
|
||||
test("extending null", () => {
|
||||
class A extends null {}
|
||||
|
||||
expect(Object.getPrototypeOf(A.prototype)).toBeNull();
|
||||
|
||||
expect(() => {
|
||||
new A();
|
||||
}).toThrowWithMessage(ReferenceError, "|this| has not been initialized");
|
||||
});
|
||||
|
||||
test("extending String", () => {
|
||||
class MyString extends String {}
|
||||
|
||||
const ms = new MyString("abc");
|
||||
expect(ms).toBeInstanceOf(MyString);
|
||||
expect(ms).toBeInstanceOf(String);
|
||||
expect(ms.charAt(1)).toBe("b");
|
||||
|
||||
class MyString2 extends MyString {
|
||||
charAt(i) {
|
||||
return `#${super.charAt(i)}`;
|
||||
}
|
||||
}
|
||||
|
||||
const ms2 = new MyString2("abc");
|
||||
expect(ms2.charAt(1)).toBe("#b");
|
||||
});
|
5
Userland/Libraries/LibJS/Tests/classes/class-basic.js
Normal file
5
Userland/Libraries/LibJS/Tests/classes/class-basic.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
test("class properties", () => {
|
||||
class A {}
|
||||
expect(A.name).toBe("A");
|
||||
expect(A).toHaveLength(0);
|
||||
});
|
67
Userland/Libraries/LibJS/Tests/classes/class-constructor.js
Normal file
67
Userland/Libraries/LibJS/Tests/classes/class-constructor.js
Normal file
|
@ -0,0 +1,67 @@
|
|||
test("property initialization", () => {
|
||||
class A {
|
||||
constructor() {
|
||||
this.x = 3;
|
||||
}
|
||||
}
|
||||
|
||||
expect(new A().x).toBe(3);
|
||||
});
|
||||
|
||||
test("method initialization", () => {
|
||||
class A {
|
||||
constructor() {
|
||||
this.x = () => 10;
|
||||
}
|
||||
}
|
||||
|
||||
expect(new A().x()).toBe(10);
|
||||
});
|
||||
|
||||
test("initialize to class method", () => {
|
||||
class A {
|
||||
constructor() {
|
||||
this.x = this.method;
|
||||
}
|
||||
|
||||
method() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
expect(new A().x()).toBe(10);
|
||||
});
|
||||
|
||||
test("constructor length affects class length", () => {
|
||||
class A {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
expect(A).toHaveLength(0);
|
||||
|
||||
class B {
|
||||
constructor(a, b, c = 2) {}
|
||||
}
|
||||
|
||||
expect(B).toHaveLength(2);
|
||||
});
|
||||
|
||||
test("must be invoked with 'new'", () => {
|
||||
class A {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
expect(() => {
|
||||
A();
|
||||
}).toThrowWithMessage(TypeError, "Class constructor A must be called with 'new'");
|
||||
|
||||
expect(() => {
|
||||
A.prototype.constructor();
|
||||
}).toThrowWithMessage(TypeError, "Class constructor A must be called with 'new'");
|
||||
});
|
||||
|
||||
test("implicit constructor", () => {
|
||||
class A {}
|
||||
|
||||
expect(new A()).toBeInstanceOf(A);
|
||||
});
|
100
Userland/Libraries/LibJS/Tests/classes/class-errors.js
Normal file
100
Userland/Libraries/LibJS/Tests/classes/class-errors.js
Normal file
|
@ -0,0 +1,100 @@
|
|||
describe("non-syntax errors", () => {
|
||||
test("super reference inside nested-but-same |this| scope with no base class", () => {
|
||||
expect(`
|
||||
class A {
|
||||
foo() {
|
||||
() => { super.bar; }
|
||||
}
|
||||
}`).toEval();
|
||||
});
|
||||
|
||||
test("super reference property lookup with no base class", () => {
|
||||
expect(`
|
||||
class A {
|
||||
constructor() {
|
||||
super.foo;
|
||||
}
|
||||
}`).toEval();
|
||||
});
|
||||
});
|
||||
|
||||
describe("reference errors", () => {
|
||||
test("derived class doesn't call super in constructor before using this", () => {
|
||||
class Parent {}
|
||||
class Child extends Parent {
|
||||
constructor() {
|
||||
this;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => {
|
||||
new Child();
|
||||
}).toThrowWithMessage(ReferenceError, "|this| has not been initialized");
|
||||
});
|
||||
|
||||
test("derived class calls super twice in constructor", () => {
|
||||
class Parent {}
|
||||
class Child extends Parent {
|
||||
constructor() {
|
||||
super();
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => {
|
||||
new Child();
|
||||
}).toThrowWithMessage(ReferenceError, "|this| is already initialized");
|
||||
});
|
||||
});
|
||||
|
||||
describe("syntax errors", () => {
|
||||
test("getter with argument", () => {
|
||||
expect(`
|
||||
class A {
|
||||
get foo(v) {
|
||||
return 0;
|
||||
}
|
||||
}`).not.toEval();
|
||||
});
|
||||
|
||||
test("setter with no arguments", () => {
|
||||
expect(`
|
||||
class A {
|
||||
set foo() {
|
||||
}
|
||||
}`).not.toEval();
|
||||
});
|
||||
|
||||
test("setter with more than one argument", () => {
|
||||
expect(`
|
||||
class A {
|
||||
set foo(bar, baz) {
|
||||
}
|
||||
}`).not.toEval();
|
||||
expect(`
|
||||
class A {
|
||||
set foo(...bar) {
|
||||
}
|
||||
}`).not.toEval();
|
||||
});
|
||||
|
||||
test("super reference inside different |this| scope", () => {
|
||||
expect(`
|
||||
class Parent {}
|
||||
|
||||
class Child extends Parent {
|
||||
foo() {
|
||||
function f() { super.foo; }
|
||||
}
|
||||
}`).not.toEval();
|
||||
});
|
||||
|
||||
test("super reference call with no base class", () => {
|
||||
expect(`
|
||||
class A {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}`).not.toEval();
|
||||
});
|
||||
});
|
68
Userland/Libraries/LibJS/Tests/classes/class-expressions.js
Normal file
68
Userland/Libraries/LibJS/Tests/classes/class-expressions.js
Normal file
|
@ -0,0 +1,68 @@
|
|||
test("basic functionality", () => {
|
||||
const A = class {
|
||||
constructor(x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
getX() {
|
||||
return this.x * 2;
|
||||
}
|
||||
};
|
||||
|
||||
expect(new A(10).getX()).toBe(20);
|
||||
});
|
||||
|
||||
test("inline instantiation", () => {
|
||||
// prettier-ignore
|
||||
const a = new class {
|
||||
constructor() {
|
||||
this.x = 10;
|
||||
}
|
||||
|
||||
getX() {
|
||||
return this.x * 2;
|
||||
}
|
||||
};
|
||||
|
||||
expect(a.getX()).toBe(20);
|
||||
});
|
||||
|
||||
test("inline instantiation with argument", () => {
|
||||
// prettier-ignore
|
||||
const a = new class {
|
||||
constructor(x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
getX() {
|
||||
return this.x * 2;
|
||||
}
|
||||
}(10);
|
||||
|
||||
expect(a.getX()).toBe(20);
|
||||
});
|
||||
|
||||
test("extending class expressions", () => {
|
||||
class A extends class {
|
||||
constructor(x) {
|
||||
this.x = x;
|
||||
}
|
||||
} {
|
||||
constructor(y) {
|
||||
super(y);
|
||||
this.y = y * 2;
|
||||
}
|
||||
}
|
||||
|
||||
const a = new A(10);
|
||||
expect(a.x).toBe(10);
|
||||
expect(a.y).toBe(20);
|
||||
});
|
||||
|
||||
test("class expression name", () => {
|
||||
let A = class {};
|
||||
expect(A.name).toBe("A");
|
||||
|
||||
let B = class C {};
|
||||
expect(B.name).toBe("C");
|
||||
});
|
75
Userland/Libraries/LibJS/Tests/classes/class-getters.js
Normal file
75
Userland/Libraries/LibJS/Tests/classes/class-getters.js
Normal file
|
@ -0,0 +1,75 @@
|
|||
test("basic functionality", () => {
|
||||
class A {
|
||||
get x() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
expect(A).not.toHaveProperty("x");
|
||||
expect(new A().x).toBe(10);
|
||||
});
|
||||
test("name", () => {
|
||||
class A {
|
||||
get x() {}
|
||||
}
|
||||
|
||||
const d = Object.getOwnPropertyDescriptor(A.prototype, "x");
|
||||
expect(d.get.name).toBe("get x");
|
||||
});
|
||||
|
||||
test("extended name syntax", () => {
|
||||
const s = Symbol("foo");
|
||||
|
||||
class A {
|
||||
get "method with space"() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
get 12() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
get [`he${"llo"}`]() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
get [s]() {
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
const a = new A();
|
||||
expect(a["method with space"]).toBe(1);
|
||||
expect(a[12]).toBe(2);
|
||||
expect(a.hello).toBe(3);
|
||||
expect(a[s]).toBe(4);
|
||||
});
|
||||
|
||||
test("inherited getter", () => {
|
||||
class Parent {
|
||||
get x() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {}
|
||||
|
||||
expect(Child).not.toHaveProperty("x");
|
||||
expect(new Child().x).toBe(3);
|
||||
});
|
||||
|
||||
test("inherited getter overriding", () => {
|
||||
class Parent {
|
||||
get x() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {
|
||||
get x() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
expect(new Child().x).toBe(10);
|
||||
});
|
133
Userland/Libraries/LibJS/Tests/classes/class-inheritance.js
Normal file
133
Userland/Libraries/LibJS/Tests/classes/class-inheritance.js
Normal file
|
@ -0,0 +1,133 @@
|
|||
test("method inheritance", () => {
|
||||
class Parent {
|
||||
method() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {}
|
||||
|
||||
const p = new Parent();
|
||||
const c = new Child();
|
||||
expect(p.method()).toBe(3);
|
||||
expect(c.method()).toBe(3);
|
||||
});
|
||||
|
||||
test("method overriding", () => {
|
||||
class Parent {
|
||||
method() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {
|
||||
method() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
const p = new Parent();
|
||||
const c = new Child();
|
||||
expect(p.method()).toBe(3);
|
||||
expect(c.method()).toBe(10);
|
||||
});
|
||||
|
||||
test("parent method reference with super", () => {
|
||||
class Parent {
|
||||
method() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {
|
||||
method() {
|
||||
return super.method() * 2;
|
||||
}
|
||||
}
|
||||
|
||||
const p = new Parent();
|
||||
const c = new Child();
|
||||
expect(p.method()).toBe(3);
|
||||
expect(c.method()).toBe(6);
|
||||
});
|
||||
|
||||
test("child class access to parent class initialized properties", () => {
|
||||
class Parent {
|
||||
constructor() {
|
||||
this.x = 3;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {}
|
||||
|
||||
const p = new Parent();
|
||||
const c = new Child();
|
||||
expect(p.x).toBe(3);
|
||||
expect(c.x).toBe(3);
|
||||
});
|
||||
|
||||
test("child class modification of parent class properties", () => {
|
||||
class Parent {
|
||||
constructor() {
|
||||
this.x = 3;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {
|
||||
change() {
|
||||
this.x = 10;
|
||||
}
|
||||
}
|
||||
|
||||
const p = new Parent();
|
||||
const c = new Child();
|
||||
expect(p.x).toBe(3);
|
||||
expect(c.x).toBe(3);
|
||||
|
||||
c.change();
|
||||
expect(c.x).toBe(10);
|
||||
});
|
||||
|
||||
test("inheritance and hasOwnProperty", () => {
|
||||
class Parent {
|
||||
constructor() {
|
||||
this.x = 3;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {
|
||||
method() {
|
||||
this.y = 10;
|
||||
}
|
||||
}
|
||||
|
||||
const p = new Parent();
|
||||
const c = new Child();
|
||||
expect(p.hasOwnProperty("x")).toBeTrue();
|
||||
expect(p.hasOwnProperty("y")).toBeFalse();
|
||||
expect(c.hasOwnProperty("x")).toBeTrue();
|
||||
expect(c.hasOwnProperty("y")).toBeFalse();
|
||||
|
||||
c.method();
|
||||
expect(c.hasOwnProperty("x")).toBeTrue();
|
||||
expect(c.hasOwnProperty("y")).toBeTrue();
|
||||
});
|
||||
|
||||
test("super constructor call from child class with argument", () => {
|
||||
class Parent {
|
||||
constructor(x) {
|
||||
this.x = x;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {
|
||||
constructor() {
|
||||
super(10);
|
||||
}
|
||||
}
|
||||
|
||||
const p = new Parent(3);
|
||||
const c = new Child(3);
|
||||
expect(p.x).toBe(3);
|
||||
expect(c.x).toBe(10);
|
||||
});
|
51
Userland/Libraries/LibJS/Tests/classes/class-methods.js
Normal file
51
Userland/Libraries/LibJS/Tests/classes/class-methods.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
test("basic functionality", () => {
|
||||
class A {
|
||||
number() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
string() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
|
||||
const a = new A();
|
||||
expect(a.number()).toBe(2);
|
||||
expect(a.string()).toBe("foo");
|
||||
});
|
||||
|
||||
test("length", () => {
|
||||
class A {
|
||||
method1() {}
|
||||
|
||||
method2(a, b, c, d) {}
|
||||
|
||||
method3(a, b, ...c) {}
|
||||
}
|
||||
|
||||
const a = new A();
|
||||
expect(a.method1).toHaveLength(0);
|
||||
expect(a.method2).toHaveLength(4);
|
||||
expect(a.method3).toHaveLength(2);
|
||||
});
|
||||
|
||||
test("extended name syntax", () => {
|
||||
class A {
|
||||
"method with space"() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
12() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
[`he${"llo"}`]() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
const a = new A();
|
||||
expect(a["method with space"]()).toBe(1);
|
||||
expect(a[12]()).toBe(2);
|
||||
expect(a.hello()).toBe(3);
|
||||
});
|
108
Userland/Libraries/LibJS/Tests/classes/class-setters.js
Normal file
108
Userland/Libraries/LibJS/Tests/classes/class-setters.js
Normal file
|
@ -0,0 +1,108 @@
|
|||
test("basic functionality", () => {
|
||||
class A {
|
||||
get x() {
|
||||
return this._x;
|
||||
}
|
||||
|
||||
set x(value) {
|
||||
this._x = value * 2;
|
||||
}
|
||||
}
|
||||
|
||||
expect(A.x).toBeUndefined();
|
||||
expect(A).not.toHaveProperty("_x");
|
||||
const a = new A();
|
||||
expect(a.x).toBeUndefined();
|
||||
expect(a).not.toHaveProperty("_x");
|
||||
a.x = 3;
|
||||
expect(a.x).toBe(6);
|
||||
expect(a).toHaveProperty("_x", 6);
|
||||
});
|
||||
|
||||
test("name", () => {
|
||||
class A {
|
||||
set x(v) {}
|
||||
}
|
||||
|
||||
const d = Object.getOwnPropertyDescriptor(A.prototype, "x");
|
||||
expect(d.set.name).toBe("set x");
|
||||
});
|
||||
|
||||
test("extended name syntax", () => {
|
||||
const s = Symbol("foo");
|
||||
|
||||
class A {
|
||||
set "method with space"(value) {
|
||||
this.a = value;
|
||||
}
|
||||
|
||||
set 12(value) {
|
||||
this.b = value;
|
||||
}
|
||||
|
||||
set [`he${"llo"}`](value) {
|
||||
this.c = value;
|
||||
}
|
||||
|
||||
set [s](value) {
|
||||
this.d = value;
|
||||
}
|
||||
}
|
||||
|
||||
const a = new A();
|
||||
a["method with space"] = 1;
|
||||
a[12] = 2;
|
||||
a.hello = 3;
|
||||
a[s] = 4;
|
||||
expect(a.a).toBe(1);
|
||||
expect(a.b).toBe(2);
|
||||
expect(a.c).toBe(3);
|
||||
expect(a.d).toBe(4);
|
||||
});
|
||||
|
||||
test("inherited setter", () => {
|
||||
class Parent {
|
||||
get x() {
|
||||
return this._x;
|
||||
}
|
||||
|
||||
set x(value) {
|
||||
this._x = value * 2;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {}
|
||||
|
||||
const c = new Child();
|
||||
|
||||
expect(c.x).toBeUndefined();
|
||||
c.x = 10;
|
||||
expect(c.x).toBe(20);
|
||||
});
|
||||
|
||||
test("inherited static setter overriding", () => {
|
||||
class Parent {
|
||||
get x() {
|
||||
return this._x;
|
||||
}
|
||||
|
||||
set x(value) {
|
||||
this._x = value * 2;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {
|
||||
get x() {
|
||||
return this._x;
|
||||
}
|
||||
|
||||
set x(value) {
|
||||
this._x = value * 3;
|
||||
}
|
||||
}
|
||||
|
||||
const c = new Child();
|
||||
expect(c.x).toBeUndefined();
|
||||
c.x = 10;
|
||||
expect(c.x).toBe(30);
|
||||
});
|
|
@ -0,0 +1,87 @@
|
|||
describe("correct behavior", () => {
|
||||
test("basic functionality", () => {
|
||||
class A {
|
||||
static get x() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
expect(A.x).toBe(10);
|
||||
expect(new A()).not.toHaveProperty("x");
|
||||
});
|
||||
|
||||
test("name", () => {
|
||||
class A {
|
||||
static get x() {}
|
||||
}
|
||||
|
||||
const d = Object.getOwnPropertyDescriptor(A, "x");
|
||||
expect(d.get.name).toBe("get x");
|
||||
});
|
||||
|
||||
test("extended name syntax", () => {
|
||||
const s = Symbol("foo");
|
||||
|
||||
class A {
|
||||
static get "method with space"() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static get 12() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
static get [`he${"llo"}`]() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
static get [s]() {
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
expect(A["method with space"]).toBe(1);
|
||||
expect(A[12]).toBe(2);
|
||||
expect(A.hello).toBe(3);
|
||||
expect(A[s]).toBe(4);
|
||||
});
|
||||
|
||||
test("inherited static getter", () => {
|
||||
class Parent {
|
||||
static get x() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {}
|
||||
|
||||
expect(Parent.x).toBe(3);
|
||||
expect(Child.x).toBe(3);
|
||||
});
|
||||
|
||||
test("inherited static getter overriding", () => {
|
||||
class Parent {
|
||||
static get x() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {
|
||||
static get x() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
expect(Parent.x).toBe(3);
|
||||
expect(Child.x).toBe(10);
|
||||
});
|
||||
});
|
||||
|
||||
describe("errors", () => {
|
||||
test('"get static" is a syntax error', () => {
|
||||
expect(`
|
||||
class A {
|
||||
get static foo() {}
|
||||
}`).not.toEval();
|
||||
});
|
||||
});
|
112
Userland/Libraries/LibJS/Tests/classes/class-static-setters.js
Normal file
112
Userland/Libraries/LibJS/Tests/classes/class-static-setters.js
Normal file
|
@ -0,0 +1,112 @@
|
|||
describe("correct behavior", () => {
|
||||
test("basic functionality", () => {
|
||||
class A {
|
||||
static get x() {
|
||||
return this._x;
|
||||
}
|
||||
|
||||
static set x(value) {
|
||||
this._x = value * 2;
|
||||
}
|
||||
}
|
||||
|
||||
expect(A.x).toBeUndefined();
|
||||
expect(A).not.toHaveProperty("_x");
|
||||
A.x = 3;
|
||||
expect(A.x).toBe(6);
|
||||
expect(A).toHaveProperty("_x", 6);
|
||||
});
|
||||
|
||||
test("name", () => {
|
||||
class A {
|
||||
static set x(v) {}
|
||||
}
|
||||
|
||||
const d = Object.getOwnPropertyDescriptor(A, "x");
|
||||
expect(d.set.name).toBe("set x");
|
||||
});
|
||||
|
||||
test("extended name syntax", () => {
|
||||
const s = Symbol("foo");
|
||||
|
||||
class A {
|
||||
static set "method with space"(value) {
|
||||
this.a = value;
|
||||
}
|
||||
|
||||
static set 12(value) {
|
||||
this.b = value;
|
||||
}
|
||||
|
||||
static set [`he${"llo"}`](value) {
|
||||
this.c = value;
|
||||
}
|
||||
|
||||
static set [s](value) {
|
||||
this.d = value;
|
||||
}
|
||||
}
|
||||
|
||||
A["method with space"] = 1;
|
||||
A[12] = 2;
|
||||
A.hello = 3;
|
||||
A[s] = 4;
|
||||
expect(A.a).toBe(1);
|
||||
expect(A.b).toBe(2);
|
||||
expect(A.c).toBe(3);
|
||||
expect(A.d).toBe(4);
|
||||
});
|
||||
|
||||
test("inherited static setter", () => {
|
||||
class Parent {
|
||||
static get x() {
|
||||
return this._x;
|
||||
}
|
||||
|
||||
static set x(value) {
|
||||
this._x = value * 2;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {}
|
||||
|
||||
expect(Child.x).toBeUndefined();
|
||||
Child.x = 10;
|
||||
expect(Child.x).toBe(20);
|
||||
});
|
||||
|
||||
test("inherited static setter overriding", () => {
|
||||
class Parent {
|
||||
static get x() {
|
||||
return this._x;
|
||||
}
|
||||
|
||||
static set x(value) {
|
||||
this._x = value * 2;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {
|
||||
static get x() {
|
||||
return this._x;
|
||||
}
|
||||
|
||||
static set x(value) {
|
||||
this._x = value * 3;
|
||||
}
|
||||
}
|
||||
|
||||
expect(Child.x).toBeUndefined();
|
||||
Child.x = 10;
|
||||
expect(Child.x).toBe(30);
|
||||
});
|
||||
});
|
||||
|
||||
describe("errors", () => {
|
||||
test('"set static" is a syntax error', () => {
|
||||
expect(`
|
||||
class A {
|
||||
set static foo(value) {}
|
||||
}`).not.toEval();
|
||||
});
|
||||
});
|
72
Userland/Libraries/LibJS/Tests/classes/class-static.js
Normal file
72
Userland/Libraries/LibJS/Tests/classes/class-static.js
Normal file
|
@ -0,0 +1,72 @@
|
|||
test("basic functionality", () => {
|
||||
class A {
|
||||
static method() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
expect(A.method()).toBe(10);
|
||||
expect(new A().method).toBeUndefined();
|
||||
});
|
||||
|
||||
test("extended name syntax", () => {
|
||||
class A {
|
||||
static method() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static 12() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
static [`he${"llo"}`]() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
expect(A.method()).toBe(1);
|
||||
expect(A[12]()).toBe(2);
|
||||
expect(A.hello()).toBe(3);
|
||||
});
|
||||
|
||||
test("bound |this|", () => {
|
||||
class A {
|
||||
static method() {
|
||||
expect(this).toBe(A);
|
||||
}
|
||||
}
|
||||
|
||||
A.method();
|
||||
});
|
||||
|
||||
test("inherited static methods", () => {
|
||||
class Parent {
|
||||
static method() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {}
|
||||
|
||||
expect(Parent.method()).toBe(3);
|
||||
expect(Child.method()).toBe(3);
|
||||
expect(new Parent()).not.toHaveProperty("method");
|
||||
expect(new Child()).not.toHaveProperty("method");
|
||||
});
|
||||
|
||||
test("static method overriding", () => {
|
||||
class Parent {
|
||||
static method() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {
|
||||
static method() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
expect(Parent.method()).toBe(3);
|
||||
expect(Child.method()).toBe(10);
|
||||
});
|
19
Userland/Libraries/LibJS/Tests/classes/class-strict-mode.js
Normal file
19
Userland/Libraries/LibJS/Tests/classes/class-strict-mode.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
test("constructors are always strict mode", () => {
|
||||
class A {
|
||||
constructor() {
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
}
|
||||
}
|
||||
|
||||
new A();
|
||||
});
|
||||
|
||||
test("methods are always strict mode", () => {
|
||||
class A {
|
||||
method() {
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
}
|
||||
}
|
||||
|
||||
new A().method();
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue