Sfoglia il codice sorgente

LibJS: Convert some top-level tests to the new system

First test conversions! These look really good :)
Matthew Olsson 5 anni fa
parent
commit
eea6041302

+ 6 - 12
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]");
+});

+ 40 - 44
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;
 
-    return counter;
+outer:
+for (let i = 0; i < 5; ++i) {
+    for (let j = 0; j < 5; ++j) {
+        continue // semicolon inserted here
+        outer // semicolon inserted here
+    }
+    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();
+});

+ 21 - 18
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++;
-    <!-- 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++;
+<!-- i++;
+i++;
+--> i++;
+return i;`
 
+    expect(source).toEvalTo(1);
+});

+ 3 - 9
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();
+});

+ 19 - 11
Libraries/LibJS/Tests/empty-statements.js

@@ -1,11 +1,19 @@
-try {
-    ;;;
-    if (true);
-    if (false); else if (false); else;
-    while (false);
-    do; while (false);
-
-    console.log("PASS");
-} catch (e) {
-    console.log("FAIL: " + e);
-}
+test("empty semicolon statements", () => {
+    expect(";;;").toEval();
+});
+
+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();
+});

+ 3 - 9
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);
+});

+ 35 - 28
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();
+});

+ 13 - 17
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);
-
-    var o = new String("bar");
-    assert(o[0] === "b");
-    assert(o[1] === "a");
-    assert(o[2] === "r");
-    assert(o[3] === undefined);
+    expect(s[0]).toBe("f");
+    expect(s[1]).toBe("o");
+    expect(s[2]).toBe("o");
+    expect(s[3]).toBeUndefined();
+});
 
-    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();
+});

+ 9 - 19
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");
+});

+ 13 - 13
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);
+});

+ 6 - 15
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);
+});

+ 24 - 26
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);
+});

+ 34 - 26
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");
+});

+ 22 - 22
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);
+});

+ 31 - 21
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");
+});

+ 42 - 32
Libraries/LibJS/Tests/object-spread.js

@@ -1,35 +1,38 @@
-load("test-common.js");
-
-function testObjSpread(obj) {
-    return obj.foo === 0 && 
-        obj.bar === 1 &&
-        obj.baz === 2 &&
-        obj.qux === 3;
-}
+const testObjSpread = obj => {
+    expect(obj).toEqual({
+        foo: 0,
+        bar: 1,
+        baz: 2,
+        qux: 3
+    });
+};
 
-function testObjStrSpread(obj) {
-    return obj[0] === "a" && 
-        obj[1] === "b" && 
-        obj[2] === "c" &&
-        obj[3] === "d";
-}
+const testObjStrSpread = obj => {
+    expect(obj).toEqual(["a", "b", "c", "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));
-    
+    testObjStrSpread(obj);
+});
+
+test("spread array in object literal", () => {
     obj = { ...["a", "b", "c", "d"] };
-    assert(testObjStrSpread(obj));
-    
+    testObjStrSpread(obj);
+});
+
+test("spread string object in object literal", () => {
     obj = { ...String("abcd") };
-    assert(testObjStrSpread(obj));
+    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);
-}
+    expect(Object.getOwnPropertyNames(empty)).toHaveLength(0);
+});

+ 0 - 11
Libraries/LibJS/Tests/switch-basic-2.js

@@ -1,11 +0,0 @@
-var a = "foo";
-
-switch (a + "bar") {
-case 1:
-    assertNotReached();
-    break;
-case "foobar":
-case 2:
-    console.log("PASS");
-    break;
-}

+ 0 - 6
Libraries/LibJS/Tests/switch-basic-3.js

@@ -1,6 +0,0 @@
-var a = "foo";
-
-switch (100) {
-default:
-    console.log("PASS");
-}

+ 39 - 14
Libraries/LibJS/Tests/switch-basic.js

@@ -1,14 +1,39 @@
-load("test-common.js");
-
-switch (1 + 2) {
-case '3':
-    assertNotReached();
-case 3:
-    console.log("PASS");
-    break;
-case 5:
-case 1:
-    break;
-default:
-    break;
-}
+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;
+        }
+
+        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();
+    });
+});

+ 93 - 87
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"}`;
-
-    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}`;
-
-    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");
+        expect(test2("foo")`bar`).toBe("foobar");
+    });
 
-    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("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"}`;
+    });
 
-    const getTemplateObject = (...rest) => rest;
-    const getRawTemplateStrings = arr => arr.raw;
+    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}`;
+    });
 
-    let o = getTemplateObject`foo\nbar`;
-    assert(Object.getOwnPropertyNames(o[0]).includes('raw'));
+    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");
+    });
 
-    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');
+    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!");
+    });
 
-    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");
+    });
+});

+ 5 - 11
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();
+});

+ 6 - 0
Userland/test-js.cpp

@@ -51,6 +51,12 @@ Vector<String> 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",