diff --git a/Libraries/LibJS/Tests/add-values-to-primitive.js b/Libraries/LibJS/Tests/add-values-to-primitive.js index c42f94d4a6..3bef2209ba 100644 --- a/Libraries/LibJS/Tests/add-values-to-primitive.js +++ b/Libraries/LibJS/Tests/add-values-to-primitive.js @@ -1,12 +1,6 @@ -load("test-common.js"); - -try { - // Note that these will give different results in the REPL due to parsing behavior. - assert([] + [] === ""); - assert([] + {} === "[object Object]"); - assert({} + {} === "[object Object][object Object]"); - assert({} + [] === "[object Object]"); - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} +test("adding objects", () => { + expect([] + []).toBe(""); + expect([] + {}).toBe("[object Object]"); + expect({} + {}).toBe("[object Object][object Object]"); + expect({} + []).toBe("[object Object]"); +}); diff --git a/Libraries/LibJS/Tests/automatic-semicolon-insertion.js b/Libraries/LibJS/Tests/automatic-semicolon-insertion.js index f3c4d3bc00..92ba35a3e5 100644 --- a/Libraries/LibJS/Tests/automatic-semicolon-insertion.js +++ b/Libraries/LibJS/Tests/automatic-semicolon-insertion.js @@ -1,30 +1,26 @@ -load("test-common.js"); +test("Issue #1829, if-else without braces or semicolons", () => { + const source = +`if (1) + return 1; +else + return 0; -/** - * This file tests automatic semicolon insertion rules. - * If this file produces syntax errors, something is wrong. - */ +if (1) + return 1 +else + return 0 -function bar() { - // https://github.com/SerenityOS/serenity/issues/1829 - if (1) - return 1; - else - return 0; +if (1) + return 1 +else + return 0;`; - if (1) - return 1 - else - return 0 + expect(source).toEval(); +}); - if (1) - return 1 - else - return 0; - -} - -function foo() { +test("break/continue, variable declaration, do-while, and return asi", () => { + const source = +`function foo() { label: for (var i = 0; i < 4; i++) { break // semicolon inserted here @@ -43,30 +39,30 @@ function foo() { 1; var curly/* semicolon inserted here */} -function baz() { - let counter = 0; - let outer; +return foo();`; - outer: - for (let i = 0; i < 5; ++i) { - for (let j = 0; j < 5; ++j) { - continue // semicolon inserted here - outer // semicolon inserted here - } - counter++; + expect(source).toEvalTo(undefined); +}); + +test("more break and continue asi", () => { + const source = +`let counter = 0; +let outer; + +outer: +for (let i = 0; i < 5; ++i) { + for (let j = 0; j < 5; ++j) { + continue // semicolon inserted here + outer // semicolon inserted here } - - return counter; + counter++; } -try { - assert(foo() === undefined); - assert(baz() === 5); +return counter;`; - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} + expect(source).toEvalTo(5); +}); -// This vardecl must appear exactly at the end of the file (no newline or whitespace after it) -var eof +test("eof with no semicolon", () => { + expect("var eof").toEval(); +}); diff --git a/Libraries/LibJS/Tests/comments-basic.js b/Libraries/LibJS/Tests/comments-basic.js index 1fc068681b..48f7c27c79 100644 --- a/Libraries/LibJS/Tests/comments-basic.js +++ b/Libraries/LibJS/Tests/comments-basic.js @@ -1,22 +1,25 @@ -load("test-common.js") +test("regular comments", () => { + const source = +`var i = 0; -try { - var i = 0; +// i++; +/* i++; */ +/* +i++; +*/ +return i;`; - // i++; - /* i++; */ - /* - i++; - */ - i++; - i++; + expect(source).toEvalTo(0); +}); - assert(i === 1); - - console.log('PASS'); -} catch (e) { - console.log('FAIL: ' + e); -} +test("html comments", () => { + const source = +`var i = 0; + i++; + i++; +return i;` + expect(source).toEvalTo(1); +}); diff --git a/Libraries/LibJS/Tests/debugger-statement.js b/Libraries/LibJS/Tests/debugger-statement.js index cf94b79084..e5b0b14761 100644 --- a/Libraries/LibJS/Tests/debugger-statement.js +++ b/Libraries/LibJS/Tests/debugger-statement.js @@ -1,9 +1,3 @@ -load("test-common.js"); - -try { - debugger; - - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} +test("debugger keyword", () => { + expect("debugger").toEval(); +}); diff --git a/Libraries/LibJS/Tests/empty-statements.js b/Libraries/LibJS/Tests/empty-statements.js index 9cde4241b7..1c8fe467b8 100644 --- a/Libraries/LibJS/Tests/empty-statements.js +++ b/Libraries/LibJS/Tests/empty-statements.js @@ -1,11 +1,19 @@ -try { - ;;; - if (true); - if (false); else if (false); else; - while (false); - do; while (false); +test("empty semicolon statements", () => { + expect(";;;").toEval(); +}); - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} +test("if with no body", () => { + expect("if (true);").toEval(); +}); + +test("chained ifs with no bodies", () => { + expect("if (false); else if (false); else;").toEval(); +}); + +test("while with no body", () => { + expect("while (false);").toEval(); +}); + +test("do while with no body", () => { + expect("do; while (false);").toEval(); +}); diff --git a/Libraries/LibJS/Tests/exception-ReferenceError.js b/Libraries/LibJS/Tests/exception-ReferenceError.js index 1bbf506bdc..5cd436d0bf 100644 --- a/Libraries/LibJS/Tests/exception-ReferenceError.js +++ b/Libraries/LibJS/Tests/exception-ReferenceError.js @@ -1,9 +1,3 @@ -load("test-common.js"); - -try { - i < 3; -} catch (e) { - assert(e.name === "ReferenceError"); -} - -console.log("PASS"); +test("unknown variable produces ReferenceError", () => { + expect(new Function("i < 3")).toThrow(ReferenceError); +}); diff --git a/Libraries/LibJS/Tests/exponentiation-basic.js b/Libraries/LibJS/Tests/exponentiation-basic.js index 0684c46889..a49781ce04 100644 --- a/Libraries/LibJS/Tests/exponentiation-basic.js +++ b/Libraries/LibJS/Tests/exponentiation-basic.js @@ -1,30 +1,37 @@ -load("test-common.js"); +test("regular exponentiation", () => { + expect(2 ** 0).toBe(1); + expect(2 ** 1).toBe(2); + expect(2 ** 2).toBe(4); + expect(2 ** 3).toBe(8); + expect(3 ** 2).toBe(9); + expect(0 ** 0).toBe(1); + expect(2 ** 3 ** 2).toBe(512); + expect(2 ** (3 ** 2)).toBe(512); + expect((2 ** 3) ** 2).toBe(64); +}); -try { - assert(2 ** 0 === 1); - assert(2 ** 1 === 2); - assert(2 ** 2 === 4); - assert(2 ** 3 === 8); - assert(2 ** -3 === 0.125); - assert(3 ** 2 === 9); - assert(0 ** 0 === 1); - assert(2 ** 3 ** 2 === 512); - assert(2 ** (3 ** 2) === 512); - assert((2 ** 3) ** 2 === 64); - assert("2" ** "3" === 8); - assert("" ** [] === 1); - assert([] ** null === 1); - assert(null ** null === 1); - assert(undefined ** null === 1); - assert(isNaN(NaN ** 2)); - assert(isNaN(2 ** NaN)); - assert(isNaN(undefined ** 2)); - assert(isNaN(2 ** undefined)); - assert(isNaN(null ** undefined)); - assert(isNaN(2 ** "foo")); - assert(isNaN("foo" ** 2)); +test("exponentation with negatives", () => { + expect(2 ** -3).toBe(0.125); + expect((-2) ** 3).toBe(-8); + + // FIXME: This should fail :) + // expect("-2 ** 3").not.toEval(); +}); - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} +test("exponentation with non-numeric primitives", () => { + expect("2" ** "3").toBe(8); + expect("" ** []).toBe(1); + expect([] ** null).toBe(1); + expect(null ** null).toBe(1); + expect(undefined ** null).toBe(1); +}) + +test("exponentation that produces NaN", () => { + expect(NaN ** 2).toBeNaN(); + expect(2 ** NaN).toBeNaN(); + expect(undefined ** 2).toBeNaN(); + expect(2 ** undefined).toBeNaN(); + expect(null ** undefined).toBeNaN(); + expect(2 ** "foo").toBeNaN(); + expect("foo" ** 2).toBeNaN(); +}); diff --git a/Libraries/LibJS/Tests/indexed-access-string-object.js b/Libraries/LibJS/Tests/indexed-access-string-object.js index 114594e542..7946cbfbf4 100644 --- a/Libraries/LibJS/Tests/indexed-access-string-object.js +++ b/Libraries/LibJS/Tests/indexed-access-string-object.js @@ -1,19 +1,15 @@ -load("test-common.js"); - -try { +test("string literal indexing", () => { var s = "foo"; - assert(s[0] === "f"); - assert(s[1] === "o"); - assert(s[2] === "o"); - assert(s[3] === undefined); + expect(s[0]).toBe("f"); + expect(s[1]).toBe("o"); + expect(s[2]).toBe("o"); + expect(s[3]).toBeUndefined(); +}); - var o = new String("bar"); - assert(o[0] === "b"); - assert(o[1] === "a"); - assert(o[2] === "r"); - assert(o[3] === undefined); - - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} +test("string object indexing", () => { + var s = new String("bar"); + expect(s[0]).toBe("b"); + expect(s[1]).toBe("a"); + expect(s[2]).toBe("r"); + expect(s[3]).toBeUndefined(); +}); diff --git a/Libraries/LibJS/Tests/invalid-lhs-in-assignment.js b/Libraries/LibJS/Tests/invalid-lhs-in-assignment.js index e758ac767f..4b402c3fc7 100644 --- a/Libraries/LibJS/Tests/invalid-lhs-in-assignment.js +++ b/Libraries/LibJS/Tests/invalid-lhs-in-assignment.js @@ -1,23 +1,13 @@ -load("test-common.js"); -try { - function foo() { } - - assertThrowsError(() => { +test("assignment to function call", () => { + expect(() => { + function foo() {}; foo() = "foo"; - }, { - error: ReferenceError, - message: "Invalid left-hand side in assignment" - }); + }).toThrowWithMessage(ReferenceError, "Invalid left-hand side in assignment"); +}); - assertThrowsError(() => { +test("assignment to inline function call", () => { + expect(() => { (function () { })() = "foo"; - }, { - error: ReferenceError, - message: "Invalid left-hand side in assignment" - }); - - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} + }).toThrowWithMessage(ReferenceError, "Invalid left-hand side in assignment"); +}); diff --git a/Libraries/LibJS/Tests/labels.js b/Libraries/LibJS/Tests/labels.js index 4388cac823..5ae9e4ee38 100644 --- a/Libraries/LibJS/Tests/labels.js +++ b/Libraries/LibJS/Tests/labels.js @@ -1,20 +1,22 @@ -load("test-common.js"); - -try { +test("labeled plain scope", () => { test: { let o = 1; - assert(o === 1); + expect(o).toBe(1); break test; - assertNotReached(); + expect().fail(); } +}); +test("break on plain scope from inner scope", () => { outer: { { break outer; } - assertNotReached(); + expect().fail(); } +}); +test("labeled for loop with break", () => { let counter = 0; outer: for (a of [1, 2, 3]) { @@ -24,8 +26,10 @@ try { counter++; } } - assert(counter === 4); + expect(counter).toBe(4); +}); +test("labeled for loop with continue", () => { let counter = 0; outer: for (a of [1, 2, 3]) { @@ -35,9 +39,5 @@ try { counter++; } } - assert(counter === 6); - - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} + expect(counter).toBe(6); +}); diff --git a/Libraries/LibJS/Tests/let-scoping.js b/Libraries/LibJS/Tests/let-scoping.js index a47c2bb202..27c92e23f9 100644 --- a/Libraries/LibJS/Tests/let-scoping.js +++ b/Libraries/LibJS/Tests/let-scoping.js @@ -1,23 +1,14 @@ -load("test-common.js"); - -try { - +test("let scoping", () => { let i = 1; { let i = 3; - assert(i === 3); + expect(i).toBe(3); } - - assert(i === 1); + expect(i).toBe(1); { const i = 2; - assert(i === 2); + expect(i).toBe(2); } - - assert(i === 1); - - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} + expect(i).toBe(1); +}); diff --git a/Libraries/LibJS/Tests/new-expression.js b/Libraries/LibJS/Tests/new-expression.js index 7b1f6917fb..d4ee3c0b0c 100644 --- a/Libraries/LibJS/Tests/new-expression.js +++ b/Libraries/LibJS/Tests/new-expression.js @@ -1,51 +1,49 @@ -load("test-common.js"); - -try { +test("new-expression parsing", () => { function Foo() { this.x = 1; } - + let foo = new Foo(); - assert(foo.x === 1); - + expect(foo.x).toBe(1); + foo = new Foo - assert(foo.x === 1); - + expect(foo.x).toBe(1); + foo = new Foo () - assert(foo.x === 1); - + expect(foo.x).toBe(1); + foo = new Foo + 2 - assert(foo === "[object Object]2"); + expect(foo).toBe("[object Object]2"); +}); +test("new-expressions with object keys", () => { let a = { b: function() { this.x = 2; }, }; - + foo = new a.b(); - assert(foo.x === 2); - + expect(foo.x).toBe(2); + foo = new a.b; - assert(foo.x === 2); - + expect(foo.x).toBe(2); + foo = new a.b(); - assert(foo.x === 2); + expect(foo.x).toBe(2); +}); +test("new-expressions with function calls", () => { function funcGetter() { return function(a, b) { this.x = a + b; }; }; - + foo = new funcGetter()(1, 5); - assert(foo === undefined); - + expect(foo).toBeUndefined(); + foo = new (funcGetter())(1, 5); - assert(foo.x === 6); - - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} + expect(foo.x).toBe(6); +}); diff --git a/Libraries/LibJS/Tests/numeric-literals-basic.js b/Libraries/LibJS/Tests/numeric-literals-basic.js index 0b1f6249d6..8209431953 100644 --- a/Libraries/LibJS/Tests/numeric-literals-basic.js +++ b/Libraries/LibJS/Tests/numeric-literals-basic.js @@ -1,29 +1,37 @@ -load("test-common.js"); +test("hex literals", () => { + expect(0xff).toBe(255); + expect(0xFF).toBe(255); +}); -try { - assert(0xff === 255); - assert(0XFF === 255); - assert(0o10 === 8); - assert(0O10 === 8); - assert(0b10 === 2); - assert(0B10 === 2); - assert(1e3 === 1000); - assert(1e+3 === 1000); - assert(1e-3 === 0.001); - assert(1. === 1); - assert(1.e1 === 10); - assert(.1 === 0.1); - assert(.1e1 === 1); - assert(0.1e1 === 1); - assert(.1e+1 === 1); - assert(0.1e+1 === 1); +test("octal literals", () => { + expect(0o10).toBe(8); + expect(0O10).toBe(8); +}); - Number.prototype.foo = 'LOL'; - assert(1..foo === 'LOL'); - assert(1.1.foo === 'LOL'); - assert(.1.foo === 'LOL'); +test("binary literals", () => { + expect(0b10).toBe(2); + expect(0B10).toBe(2); +}); - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} +test("exponential literals", () => { + expect(1e3).toBe(1000); + expect(1e+3).toBe(1000); + expect(1e-3).toBe(0.001); + expect(1.e1).toBe(10); + expect(.1e1).toBe(1); + expect(0.1e1).toBe(1); + expect(.1e+1).toBe(1); + expect(0.1e+1).toBe(1); +}); + +test("decimal numbers", () => { + expect(1.).toBe(1); + expect(.1).toBe(0.1); +}); + +test("accessing properties of decimal numbers", () => { + Number.prototype.foo = "foo"; + expect(1..foo).toBe("foo"); + expect(1.1.foo).toBe("foo"); + expect(.1.foo).toBe("foo"); +}); diff --git a/Libraries/LibJS/Tests/object-getter-setter-shorthand.js b/Libraries/LibJS/Tests/object-getter-setter-shorthand.js index e0ca209fa5..3849bc5343 100644 --- a/Libraries/LibJS/Tests/object-getter-setter-shorthand.js +++ b/Libraries/LibJS/Tests/object-getter-setter-shorthand.js @@ -1,22 +1,24 @@ -load("test-common.js") - -try { +test("normal methods named get and set", () => { let o = { get() { return 5; }, set() { return 10; }, }; - assert(o.get() === 5); - assert(o.set() === 10); + expect(o.get()).toBe(5); + expect(o.set()).toBe(10); +}); - o = { +test("basic get and set", () => { + let o = { get x() { return 5; }, set x(_) { }, }; - assert(o.x === 5); + expect(o.x).toBe(5); o.x = 10; - assert(o.x === 5); + expect(o.x).toBe(5); +}); - o = { +test("get and set with 'this'", () => { + let o = { get x() { return this._x + 1; }, @@ -25,26 +27,24 @@ try { }, }; - assert(isNaN(o.x)); + expect(o.x).toBeNaN(); o.x = 10; - assert(o.x === 12); + expect(o.x).toBe(12); o.x = 20; - assert(o.x === 22); + expect(o.x).toBe(22); +}); - o = { +test("multiple getters", () => { + let o = { get x() { return 5; }, get x() { return 10; }, }; + expect(o.x).toBe(10); +}); - assert(o.x === 10); - +test("setter return value", () => { o = { set x(value) { return 10; }, }; - - assert((o.x = 20) === 20); - - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} + expect(o.x = 20).toBe(20); +}); diff --git a/Libraries/LibJS/Tests/object-method-shorthand.js b/Libraries/LibJS/Tests/object-method-shorthand.js index 94c3454d84..66b659d054 100644 --- a/Libraries/LibJS/Tests/object-method-shorthand.js +++ b/Libraries/LibJS/Tests/object-method-shorthand.js @@ -1,29 +1,39 @@ -load("test-common.js"); - -try { +test("basic method shorthand", () => { const o = { foo: "bar", - getFoo() { + getFoo() { return this.foo; }, - 12() { - return this.getFoo(); - }, - "hello friends"() { - return this.getFoo(); - }, - [4 + 10]() { - return this.getFoo(); + }; + expect(o.getFoo()).toBe("bar"); +}); + +test("numeric literal method shorthand", () => { + const o = { + foo: "bar", + 12() { + return this.foo; }, }; + expect(o[12]()).toBe("bar"); +}); - assert(o.foo === "bar"); - assert(o.getFoo() === "bar"); - assert(o[12]() === "bar"); - assert(o["hello friends"]() === "bar"); - assert(o[14]() === "bar"); +test("string literal method shorthand", () => { + const o = { + foo: "bar", + "hello friends"() { + return this.foo; + }, + }; + expect(o["hello friends"]()).toBe("bar"); +}); - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} +test("computed property method shorthand", () => { + const o = { + foo: "bar", + [4 + 10]() { + return this.foo; + }, + }; + expect(o[14]()).toBe("bar"); +}); diff --git a/Libraries/LibJS/Tests/object-spread.js b/Libraries/LibJS/Tests/object-spread.js index 18fab7abb8..1c3e5b3134 100644 --- a/Libraries/LibJS/Tests/object-spread.js +++ b/Libraries/LibJS/Tests/object-spread.js @@ -1,35 +1,38 @@ -load("test-common.js"); +const testObjSpread = obj => { + expect(obj).toEqual({ + foo: 0, + bar: 1, + baz: 2, + qux: 3 + }); +}; -function testObjSpread(obj) { - return obj.foo === 0 && - obj.bar === 1 && - obj.baz === 2 && - obj.qux === 3; -} +const testObjStrSpread = obj => { + expect(obj).toEqual(["a", "b", "c", "d"]); +}; -function testObjStrSpread(obj) { - return obj[0] === "a" && - obj[1] === "b" && - obj[2] === "c" && - obj[3] === "d"; -} - -try { +test("spread object literal inside object literal", () => { let obj = { foo: 0, ...{ bar: 1, baz: 2 }, qux: 3, }; - assert(testObjSpread(obj)); + testObjSpread(obj); +}); +test("spread object with assigned property inside object literal", () => { obj = { foo: 0, bar: 1, baz: 2 }; obj.qux = 3; - assert(testObjSpread({ ...obj })); + testObjSpread({ ...obj }); +}); +test("spread object inside object literal", () => { let a = { bar: 1, baz: 2 }; obj = { foo: 0, ...a, qux: 3 }; - assert(testObjSpread(obj)); + testObjSpread(obj); +}); +test("complex nested object spreading", () => { obj = { ...{}, ...{ @@ -37,25 +40,36 @@ try { }, qux: 3, }; - assert(testObjSpread(obj)); + testObjSpread(obj); +}); +test("spread string in object literal", () => { obj = { ..."abcd" }; - assert(testObjStrSpread(obj)); - - obj = { ...["a", "b", "c", "d"] }; - assert(testObjStrSpread(obj)); - - obj = { ...String("abcd") }; - assert(testObjStrSpread(obj)); + testObjStrSpread(obj); +}); +test("spread array in object literal", () => { + obj = { ...["a", "b", "c", "d"] }; + testObjStrSpread(obj); +}); + +test("spread string object in object literal", () => { + obj = { ...String("abcd") }; + testObjStrSpread(obj); +}); + +test("spread object with non-enumerable property", () => { a = { foo: 0 }; - Object.defineProperty(a, 'bar', { + Object.defineProperty(a, "bar", { value: 1, enumerable: false, }); obj = { ...a }; - assert(obj.foo === 0 && obj.bar === undefined); + expect(obj.foo).toBe(0); + expect(obj).not.toHaveProperty("bar"); +}); +test("spreading non-spreadable values", () => { let empty = ({ ...undefined, ...null, @@ -64,9 +78,5 @@ try { ...function(){}, ...Date, }); - assert(Object.getOwnPropertyNames(empty).length === 0); - - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} \ No newline at end of file + expect(Object.getOwnPropertyNames(empty)).toHaveLength(0); +}); diff --git a/Libraries/LibJS/Tests/switch-basic-2.js b/Libraries/LibJS/Tests/switch-basic-2.js deleted file mode 100644 index d492b1d3ab..0000000000 --- a/Libraries/LibJS/Tests/switch-basic-2.js +++ /dev/null @@ -1,11 +0,0 @@ -var a = "foo"; - -switch (a + "bar") { -case 1: - assertNotReached(); - break; -case "foobar": -case 2: - console.log("PASS"); - break; -} diff --git a/Libraries/LibJS/Tests/switch-basic-3.js b/Libraries/LibJS/Tests/switch-basic-3.js deleted file mode 100644 index 7fe22742a8..0000000000 --- a/Libraries/LibJS/Tests/switch-basic-3.js +++ /dev/null @@ -1,6 +0,0 @@ -var a = "foo"; - -switch (100) { -default: - console.log("PASS"); -} diff --git a/Libraries/LibJS/Tests/switch-basic.js b/Libraries/LibJS/Tests/switch-basic.js index 1fba80f9f0..c848293ac5 100644 --- a/Libraries/LibJS/Tests/switch-basic.js +++ b/Libraries/LibJS/Tests/switch-basic.js @@ -1,14 +1,39 @@ -load("test-common.js"); +describe("basic switch tests", () => { + test("string case does not match number target", () => { + switch (1 + 2) { + case '3': + expect().fail(); + case 3: + return; + case 5: + case 1: + break; + default: + break; + } -switch (1 + 2) { -case '3': - assertNotReached(); -case 3: - console.log("PASS"); - break; -case 5: -case 1: - break; -default: - break; -} + expect().fail(); + }); + + test("string concatenation in target", () => { + var a = "foo"; + + switch (a + "bar") { + case 1: + expect().fail(); + case "foobar": + case 2: + return; + } + expect().fail(); + }); + + test("default", () => { + switch (100) { + default: + return; + } + + expect().fail(); + }); +}); diff --git a/Libraries/LibJS/Tests/tagged-template-literals.js b/Libraries/LibJS/Tests/tagged-template-literals.js index 614c7f413a..31e7c1629d 100644 --- a/Libraries/LibJS/Tests/tagged-template-literals.js +++ b/Libraries/LibJS/Tests/tagged-template-literals.js @@ -1,100 +1,106 @@ -load("test-common.js"); +describe("tagged template literal errors", () => { + test("undefined variables in template expression throw a ReferenceError", () => { + expect(() => { + foo`bar${baz}`; + }).toThrowWithMessage(ReferenceError, "'foo' is not defined"); -try { - assertThrowsError(() => { - foo`bar${baz}`; - }, { - error: ReferenceError, - message: "'foo' is not defined" + expect(() => { + function foo() {}; + foo`bar${baz}`; + }).toThrowWithMessage(ReferenceError, "'baz' is not defined"); }); - assertThrowsError(() => { - function foo() { } - foo`bar${baz}`; - }, { - error: ReferenceError, - message: "'baz' is not defined" + test("cannot tag a non-function", () => { + expect(() => { + undefined``; + }).toThrowWithMessage(TypeError, "undefined is not a function"); }); +}); - assertThrowsError(() => { - undefined``````; - }, { - error: TypeError, - message: "undefined is not a function" - }); - - function test1(strings) { - assert(strings instanceof Array); - assert(strings.length === 1); - assert(strings[0] === ""); - return 42; - } - assert(test1`` === 42); - - function test2(s) { - return function (strings) { - assert(strings instanceof Array); - assert(strings.length === 1); - assert(strings[0] === "bar"); - return s + strings[0]; +describe("tagged template literal functionality", () => { + test("empty template tag", () => { + function test1(strings) { + expect(strings).toBeInstanceOf(Array); + expect(strings).toHaveLength(1); + expect(strings[0]).toBe(""); + return 42; } - } - assert(test2("foo")`bar` === "foobar"); + expect(test1``).toBe(42); + }); - var test3 = { - foo(strings, p1) { - assert(strings instanceof Array); - assert(strings.length === 2); - assert(strings[0] === ""); - assert(strings[1] === ""); - assert(p1 === "bar"); + test("tagging a template literal", () => { + function test2(s) { + return function (strings) { + expect(strings).toBeInstanceOf(Array); + expect(strings).toHaveLength(1); + expect(strings[0]).toBe("bar"); + return s + strings[0]; + } } - }; - test3.foo`${"bar"}`; + expect(test2("foo")`bar`).toBe("foobar"); + }); - function test4(strings, p1) { - assert(strings instanceof Array); - assert(strings.length === 2); - assert(strings[0] === "foo"); - assert(strings[1] === ""); - assert(p1 === 42); - } - var bar = 42; - test4`foo${bar}`; + test("tagging an object function key", () => { + var test3 = { + foo(strings, p1) { + expect(strings).toBeInstanceOf(Array); + expect(strings).toHaveLength(2); + expect(strings[0]).toBe(""); + expect(strings[1]).toBe(""); + expect(p1).toBe("bar"); + } + }; + test3.foo`${"bar"}`; + }); - function test5(strings, p1, p2) { - assert(strings instanceof Array); - assert(strings.length === 3); - assert(strings[0] === "foo"); - assert(strings[1] === "baz"); - assert(strings[2] === ""); - assert(p1 === 42); - assert(p2 === "qux"); - return (strings, value) => `${value}${strings[0]}`; - } - var bar = 42; - assert(test5`foo${bar}baz${"qux"}``test${123}` === "123test"); + test("tagging with a variable in a template expression", () => { + function test4(strings, p1) { + expect(strings).toBeInstanceOf(Array); + expect(strings).toHaveLength(2); + expect(strings[0]).toBe("foo"); + expect(strings[1]).toBe(""); + expect(p1).toBe(42); + } + var bar = 42; + test4`foo${bar}`; + }); - function review(strings, name, rating) { - return `${strings[0]}**${name}**${strings[1]}_${rating}_${strings[2]}`; - } - var name = "SerenityOS"; - var rating = "great"; - assert(review`${name} is a ${rating} project!` === "**SerenityOS** is a _great_ project!"); + test("template tag result of another template tag", () => { + function test5(strings, p1, p2) { + expect(strings).toBeInstanceOf(Array); + expect(strings).toHaveLength(3); + expect(strings[0]).toBe("foo"); + expect(strings[1]).toBe("baz"); + expect(strings[2]).toBe(""); + expect(p1).toBe(42); + expect(p2).toBe("qux"); + return (strings, value) => `${value}${strings[0]}`; + } + var bar = 42; + expect(test5`foo${bar}baz${"qux"}``test${123}`).toBe("123test"); + }); - const getTemplateObject = (...rest) => rest; - const getRawTemplateStrings = arr => arr.raw; + test("general test", () => { + function review(strings, name, rating) { + return `${strings[0]}**${name}**${strings[1]}_${rating}_${strings[2]}`; + } + var name = "SerenityOS"; + var rating = "great"; + expect(review`${name} is a ${rating} project!`).toBe("**SerenityOS** is a _great_ project!"); + }); - let o = getTemplateObject`foo\nbar`; - assert(Object.getOwnPropertyNames(o[0]).includes('raw')); - - let raw = getRawTemplateStrings`foo${1 + 3}\nbar`; - assert(!Object.getOwnPropertyNames(raw).includes('raw')); - assert(raw.length === 2); - assert(raw[0] === 'foo'); - assert(raw[1].length === 5 && raw[1] === '\\nbar'); - - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} + test("template object structure", () => { + const getTemplateObject = (...rest) => rest; + const getRawTemplateStrings = arr => arr.raw; + + let o = getTemplateObject`foo\nbar`; + expect(Object.getOwnPropertyNames(o[0])).toContain("raw"); + + let raw = getRawTemplateStrings`foo${1 + 3}\nbar`; + expect(Object.getOwnPropertyNames(raw)).not.toContain("raw"); + expect(raw).toHaveLength(2); + expect(raw[0]).toBe("foo"); + expect(raw[1]).toHaveLength(5); + expect(raw[1]).toBe("\\nbar"); + }); +}); diff --git a/Libraries/LibJS/Tests/update-expression-on-member-expression.js b/Libraries/LibJS/Tests/update-expression-on-member-expression.js index c3e0a75337..1d199152b2 100644 --- a/Libraries/LibJS/Tests/update-expression-on-member-expression.js +++ b/Libraries/LibJS/Tests/update-expression-on-member-expression.js @@ -1,14 +1,8 @@ -load("test-common.js"); - -try { +test("basic update expression", () => { var o = {}; o.f = 1; - assert(o.f++ === 1); - assert(++o.f === 3); - assert(isNaN(++o.missing)); - - console.log("PASS"); -} catch (e) { - console.log("FAIL: " + e); -} + expect(o.f++).toBe(1); + expect(++o.f).toBe(3); + expect(++o.missing).toBeNaN(); +}); diff --git a/Userland/test-js.cpp b/Userland/test-js.cpp index 6eeb615a8e..108a1f10cf 100644 --- a/Userland/test-js.cpp +++ b/Userland/test-js.cpp @@ -51,6 +51,12 @@ Vector tests_to_run = { "exponentiation-basic.js", "indexed-access-string-object.js", "invalid-lhs-in-assignment.js", + "let-scoping.js", + "new-expression.js", + "numeric-literals-basic.js", + "object-getter-setter-shorthand.js", + "object-method-shorthand.js", + "object-spread.js", "tagged-template-literals.js", "switch-basic.js", "update-expression-on-member-expression.js",