mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-22 20:45:14 +00:00
LibJS: Convert remaining top-level tests to new system
This commit is contained in:
parent
6d58c48c2f
commit
918f4affd5
Notes:
sideshowbarker
2024-07-19 05:03:58 +09:00
Author: https://github.com/mattco98 Commit: https://github.com/SerenityOS/serenity/commit/918f4affd51 Pull-request: https://github.com/SerenityOS/serenity/pull/2689 Reviewed-by: https://github.com/linusg
19 changed files with 518 additions and 497 deletions
16
Libraries/LibJS/Tests/const-reassignment.js
Normal file
16
Libraries/LibJS/Tests/const-reassignment.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
test.skip("reassignment to const", () => {
|
||||
const constantValue = 1;
|
||||
expect(() => {
|
||||
constantValue = 2;
|
||||
}).toThrowWithMessage(TypeError, "Invalid assignment to const variable");
|
||||
expect(constantValue).toBe(1);
|
||||
});
|
||||
|
||||
test("const creation in inner scope", () => {
|
||||
const constantValue = 1;
|
||||
do {
|
||||
const constantValue = 2;
|
||||
expect(constantValue).toBe(2);
|
||||
} while (false);
|
||||
expect(constantValue).toBe(1);
|
||||
});
|
|
@ -1,104 +1,149 @@
|
|||
load("test-common.js");
|
||||
describe("correct behavior", () => {
|
||||
test("numeric indexing", () => {
|
||||
const o = { 1: 23 };
|
||||
|
||||
try {
|
||||
var foo = "bar";
|
||||
var computed = "computed";
|
||||
var o = {
|
||||
1: 23,
|
||||
foo,
|
||||
bar: "baz",
|
||||
qux: true ? 10 : 20,
|
||||
hello: "friends",
|
||||
[1 + 2]: 42,
|
||||
["I am a " + computed + " key"]: foo,
|
||||
duplicate: "hello",
|
||||
duplicate: "world",
|
||||
};
|
||||
assert(o[1] === 23);
|
||||
assert(o[1n] === 23);
|
||||
assert(o["1"] === 23);
|
||||
assert(o.foo === "bar");
|
||||
assert(o["foo"] === "bar");
|
||||
assert(o.qux === 10), assert(o.hello === "friends");
|
||||
assert(o["hello"] === "friends");
|
||||
assert(o[3] === 42);
|
||||
assert(o["I am a computed key"] === "bar");
|
||||
assert(o.duplicate === "world");
|
||||
o.baz = "test";
|
||||
assert(o.baz === "test");
|
||||
assert(o["baz"] === "test");
|
||||
o[10] = "123";
|
||||
assert(o[10] === "123");
|
||||
assert(o["10"] === "123");
|
||||
o[10n] = "123";
|
||||
assert(o[10] === "123");
|
||||
assert(o["10"] === "123");
|
||||
o[-1] = "hello friends";
|
||||
assert(o[-1] === "hello friends");
|
||||
assert(o["-1"] === "hello friends");
|
||||
expect(o[1]).toBe(23);
|
||||
expect(o[1n]).toBe(23);
|
||||
expect(o["1"]).toBe(23);
|
||||
|
||||
var math = { 3.14: "pi" };
|
||||
assert(math["3.14"] === "pi");
|
||||
// Note : this test doesn't pass yet due to floating-point literals being coerced to i32 on access
|
||||
// assert(math[3.14] === "pi");
|
||||
o[10] = "123";
|
||||
expect(o[10]).toBe("123");
|
||||
expect(o["10"]).toBe("123");
|
||||
|
||||
// This is also allowed! Watch out for syntax errors.
|
||||
var o2 = { return: 1, yield: 1, for: 1, catch: 1, break: 1 };
|
||||
assert(o2.return === 1);
|
||||
assert(o2.yield === 1);
|
||||
assert(o2.for === 1);
|
||||
assert(o2.catch === 1);
|
||||
assert(o2.break === 1);
|
||||
o[10n] = "1234";
|
||||
expect(o[10]).toBe("1234");
|
||||
expect(o["10"]).toBe("1234");
|
||||
});
|
||||
|
||||
var a;
|
||||
var append = x => {
|
||||
test("string indexing", () => {
|
||||
let foo = "bar";
|
||||
|
||||
const o = {
|
||||
foo,
|
||||
bar: "baz",
|
||||
qux: true ? 10 : 20,
|
||||
hello: "friends",
|
||||
};
|
||||
|
||||
expect(o.foo).toBe("bar");
|
||||
expect(o["foo"]).toBe("bar");
|
||||
expect(o.qux).toBe(10), expect(o.hello).toBe("friends");
|
||||
expect(o["hello"]).toBe("friends");
|
||||
});
|
||||
|
||||
test("computed properties", () => {
|
||||
const foo = "bar";
|
||||
const computed = "computed";
|
||||
const o = {
|
||||
[1 + 2]: 42,
|
||||
[`I am a ${computed} key`]: foo,
|
||||
};
|
||||
|
||||
expect(o[3]).toBe(42);
|
||||
expect(o["I am a computed key"]).toBe("bar");
|
||||
});
|
||||
|
||||
test("duplicate keys", () => {
|
||||
const o = {
|
||||
duplicate: "hello",
|
||||
duplicate: "world",
|
||||
};
|
||||
expect(o.duplicate).toBe("world");
|
||||
});
|
||||
|
||||
test("assigning after creation", () => {
|
||||
const o = {};
|
||||
o.baz = "test";
|
||||
|
||||
expect(o.baz).toBe("test");
|
||||
expect(o["baz"]).toBe("test");
|
||||
|
||||
expect(o[-1]).toBeUndefined();
|
||||
o[-1] = "hello friends";
|
||||
expect(o[-1]).toBe("hello friends");
|
||||
expect(o["-1"]).toBe("hello friends");
|
||||
});
|
||||
|
||||
test("floating point keys", () => {
|
||||
const math = { 3.14: "pi" };
|
||||
expect(math["3.14"]).toBe("pi");
|
||||
// FIXME: Floating point literals are coerced to i32
|
||||
// expect(math[3.14]).toBe("pi");
|
||||
});
|
||||
|
||||
test("keywords as property keys", () => {
|
||||
const o2 = {
|
||||
return: 1,
|
||||
yield: 1,
|
||||
for: 1,
|
||||
catch: 1,
|
||||
break: 1,
|
||||
};
|
||||
|
||||
expect(o2.return).toBe(1);
|
||||
expect(o2.yield).toBe(1);
|
||||
expect(o2.for).toBe(1);
|
||||
expect(o2.catch).toBe(1);
|
||||
expect(o2.break).toBe(1);
|
||||
});
|
||||
|
||||
test("prototypical inheritance", () => {
|
||||
var base = {
|
||||
getNumber() {
|
||||
return 10;
|
||||
},
|
||||
};
|
||||
|
||||
var derived = {
|
||||
getNumber() {
|
||||
return 20 + super.getNumber();
|
||||
},
|
||||
};
|
||||
|
||||
Object.setPrototypeOf(derived, base);
|
||||
expect(derived.getNumber()).toBe(30);
|
||||
});
|
||||
});
|
||||
|
||||
describe("side effects", () => {
|
||||
let a;
|
||||
const append = x => {
|
||||
a.push(x);
|
||||
};
|
||||
|
||||
a = [];
|
||||
var o3 = { [append(1)]: 1, [append(2)]: 2, [append(3)]: 3 };
|
||||
assert(a.length === 3);
|
||||
assert(a[0] === 1);
|
||||
assert(a[1] === 2);
|
||||
assert(a[2] === 3);
|
||||
assert(o3.undefined === 3);
|
||||
test("computed key side effects", () => {
|
||||
a = [];
|
||||
const o3 = { [append(1)]: 1, [append(2)]: 2, [append(3)]: 3 };
|
||||
expect(a).toHaveLength(3);
|
||||
expect(a[0]).toBe(1);
|
||||
expect(a[1]).toBe(2);
|
||||
expect(a[2]).toBe(3);
|
||||
expect(o3.undefined).toBe(3);
|
||||
});
|
||||
|
||||
a = [];
|
||||
var o4 = { test: append(1), test: append(2), test: append(3) };
|
||||
assert(a.length === 3);
|
||||
assert(a[0] === 1);
|
||||
assert(a[1] === 2);
|
||||
assert(a[2] === 3);
|
||||
assert(o4.test === undefined);
|
||||
test("value side effects", () => {
|
||||
a = [];
|
||||
const o4 = { test: append(1), test: append(2), test: append(3) };
|
||||
expect(a).toHaveLength(3);
|
||||
expect(a[0]).toBe(1);
|
||||
expect(a[1]).toBe(2);
|
||||
expect(a[2]).toBe(3);
|
||||
expect(o4.test).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
var base = {
|
||||
getNumber() {
|
||||
return 10;
|
||||
},
|
||||
};
|
||||
|
||||
var derived = {
|
||||
getNumber() {
|
||||
return 20 + super.getNumber();
|
||||
},
|
||||
};
|
||||
|
||||
Object.setPrototypeOf(derived, base);
|
||||
assert(derived.getNumber() === 30);
|
||||
|
||||
assertIsSyntaxError("({ foo: function() { super.bar; } })");
|
||||
assertIsSyntaxError("({ get ...foo })");
|
||||
assertIsSyntaxError("({ get... foo })");
|
||||
assertIsSyntaxError("({ get foo })");
|
||||
assertIsSyntaxError("({ get foo: bar })");
|
||||
assertIsSyntaxError("({ get [foo]: bar })");
|
||||
assertIsSyntaxError("({ get ...[foo] })");
|
||||
assertIsSyntaxError("({ get foo(bar) {} })");
|
||||
assertIsSyntaxError("({ set foo() {} })");
|
||||
assertIsSyntaxError("({ set foo(bar, baz) {} })");
|
||||
assertIsSyntaxError("({ ...foo: bar })");
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
||||
describe("errors", () => {
|
||||
test("syntax errors", () => {
|
||||
expect("({ foo: function() { super.bar; } })").not.toEval();
|
||||
expect("({ get ...foo })").not.toEval();
|
||||
expect("({ get... foo })").not.toEval();
|
||||
expect("({ get foo })").not.toEval();
|
||||
expect("({ get foo: bar })").not.toEval();
|
||||
expect("({ get [foo]: bar })").not.toEval();
|
||||
expect("({ get ...[foo] })").not.toEval();
|
||||
expect("({ get foo(bar) {} })").not.toEval();
|
||||
expect("({ set foo() {} })").not.toEval();
|
||||
expect("({ set foo(bar, baz) {} })").not.toEval();
|
||||
expect("({ ...foo: bar })").not.toEval();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
load("test-common.js");
|
||||
|
||||
try {
|
||||
var o = {};
|
||||
test("basic functionality", () => {
|
||||
const o = {};
|
||||
o.a = 1;
|
||||
|
||||
assert(o.a === 1);
|
||||
assert(!o.a === false);
|
||||
assert(!o.a === !o.a);
|
||||
assert(~o.a === ~o.a);
|
||||
assert(+o.a === +o.a);
|
||||
assert(-o.a === -o.a);
|
||||
expect(o.a === 1).toBeTrue();
|
||||
expect(!o.a === false).toBeTrue();
|
||||
expect(!o.a === !o.a).toBeTrue();
|
||||
expect(~o.a === ~o.a).toBeTrue();
|
||||
expect(+o.a === +o.a).toBeTrue();
|
||||
expect(-o.a === -o.a).toBeTrue();
|
||||
|
||||
assert((typeof "x" === "string") === true);
|
||||
assert(!(typeof "x" === "string") === false);
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
||||
expect((typeof "x" === "string") === true).toBeTrue();
|
||||
expect(!(typeof "x" === "string") === false).toBeTrue();
|
||||
});
|
||||
|
|
|
@ -1,29 +1,18 @@
|
|||
"use strict";
|
||||
|
||||
load("test-common.js");
|
||||
|
||||
try {
|
||||
assert(isStrictMode());
|
||||
test("basic functionality", () => {
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
|
||||
(function () {
|
||||
assert(isStrictMode());
|
||||
})();
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
assert(isStrictMode());
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
})();
|
||||
|
||||
(() => {
|
||||
assert(isStrictMode());
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
})();
|
||||
|
||||
(() => {
|
||||
"use strict";
|
||||
assert(isStrictMode());
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
})();
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,21 +1,9 @@
|
|||
"use strict";
|
||||
|
||||
load("test-common.js");
|
||||
|
||||
try {
|
||||
test("basic functionality", () => {
|
||||
[true, false, "foo", 123].forEach(primitive => {
|
||||
assertThrowsError(
|
||||
() => {
|
||||
primitive.foo = "bar";
|
||||
},
|
||||
{
|
||||
error: TypeError,
|
||||
message: "Cannot assign property foo to primitive value",
|
||||
}
|
||||
);
|
||||
expect(() => {
|
||||
primitive.foo = "bar";
|
||||
}).toThrowWithMessage(TypeError, "Cannot assign property foo to primitive value");
|
||||
});
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
load("test-common.js");
|
||||
test("hex escapes", () => {
|
||||
expect("\x55").toBe("U");
|
||||
expect("X55").toBe("X55");
|
||||
expect(`\x55`).toBe("U");
|
||||
expect(`\X55`).toBe("X55");
|
||||
});
|
||||
|
||||
try {
|
||||
assert("\x55" === "U");
|
||||
assert("X55" === "X55");
|
||||
assert(`\x55` === "U");
|
||||
assert(`\X55` === "X55");
|
||||
|
||||
assert("\u26a0" === "⚠");
|
||||
assert(`\u26a0` === "⚠");
|
||||
assert("\u{1f41e}" === "🐞");
|
||||
assert(`\u{1f41e}` === "🐞");
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
||||
test("unicode escapes", () => {
|
||||
expect("\u26a0").toBe("⚠");
|
||||
expect(`\u26a0`).toBe("⚠");
|
||||
expect("\u{1f41e}").toBe("🐞");
|
||||
expect(`\u{1f41e}`).toBe("🐞");
|
||||
});
|
||||
|
|
|
@ -1,27 +1,25 @@
|
|||
load("test-common.js");
|
||||
|
||||
function testArray(arr) {
|
||||
return arr.length === 4 && arr[0] === "a" && arr[1] === "b" && arr[2] === "c" && arr[3] === "d";
|
||||
}
|
||||
|
||||
try {
|
||||
var arr;
|
||||
test("spreading string literal", () => {
|
||||
expect(["a", ..."bc", "d"]).toEqual(["a", "b", "c", "d"]);
|
||||
});
|
||||
|
||||
arr = ["a", ..."bc", "d"];
|
||||
assert(testArray(arr));
|
||||
test("spreading string variable", () => {
|
||||
const s = "bc";
|
||||
expect(["a", ...s, "d"]).toEqual(["a", "b", "c", "d"]);
|
||||
});
|
||||
|
||||
let s = "bc";
|
||||
arr = ["a", ...s, "d"];
|
||||
assert(testArray(arr));
|
||||
test("spreading string in object", () => {
|
||||
const obj = { a: "bc" };
|
||||
expect(["a", ...obj.a, "d"]).toEqual(["a", "b", "c", "d"]);
|
||||
});
|
||||
|
||||
let obj = { a: "bc" };
|
||||
arr = ["a", ...obj.a, "d"];
|
||||
assert(testArray(arr));
|
||||
test("spreading empty string", () => {
|
||||
expect([..."", "a", ..."bc", ..."", "d", ...""]).toEqual(["a", "b", "c", "d"]);
|
||||
});
|
||||
|
||||
arr = [..."", ...[...new String("abc")], "d"];
|
||||
assert(testArray(arr));
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
||||
test("spreading string objects", () => {
|
||||
expect([..."", ...[...new String("abc")], "d"]).toEqual(["a", "b", "c", "d"]);
|
||||
});
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
load("test-common.js");
|
||||
|
||||
try {
|
||||
var i = 0;
|
||||
var three;
|
||||
var five;
|
||||
test("basic functionality", () => {
|
||||
let i = 0;
|
||||
let three;
|
||||
let five;
|
||||
|
||||
for (; i < 9; ) {
|
||||
switch (i) {
|
||||
|
@ -16,8 +14,7 @@ try {
|
|||
}
|
||||
++i;
|
||||
}
|
||||
assert(three === 3);
|
||||
assert(five === 5);
|
||||
|
||||
console.log("PASS");
|
||||
} catch {}
|
||||
expect(three).toBe(3);
|
||||
expect(five).toBe(5);
|
||||
});
|
||||
|
|
|
@ -1,50 +1,58 @@
|
|||
load("test-common.js");
|
||||
test("plain literals with expression-like characters", () => {
|
||||
expect(`foo`).toBe("foo");
|
||||
expect(`foo{`).toBe("foo{");
|
||||
expect(`foo}`).toBe("foo}");
|
||||
expect(`foo$`).toBe("foo$");
|
||||
});
|
||||
|
||||
try {
|
||||
assert(`foo` === "foo");
|
||||
assert(`foo{` === "foo{");
|
||||
assert(`foo}` === "foo}");
|
||||
assert(`foo$` === "foo$");
|
||||
assert(`foo\`` === "foo`");
|
||||
assert(`foo\$` === "foo$");
|
||||
test("plain literals with escaped special characters", () => {
|
||||
expect(`foo\``).toBe("foo`");
|
||||
expect(`foo\$`).toBe("foo$");
|
||||
expect(`foo \${"bar"}`).toBe('foo ${"bar"}');
|
||||
});
|
||||
|
||||
assert(`foo ${undefined}` === "foo undefined");
|
||||
assert(`foo ${null}` === "foo null");
|
||||
assert(`foo ${5}` === "foo 5");
|
||||
assert(`foo ${true}` === "foo true");
|
||||
assert(`foo ${"bar"}` === "foo bar");
|
||||
assert(`foo \${"bar"}` === 'foo ${"bar"}');
|
||||
test("literals in expressions", () => {
|
||||
expect(`foo ${undefined}`).toBe("foo undefined");
|
||||
expect(`foo ${null}`).toBe("foo null");
|
||||
expect(`foo ${5}`).toBe("foo 5");
|
||||
expect(`foo ${true}`).toBe("foo true");
|
||||
expect(`foo ${"bar"}`).toBe("foo bar");
|
||||
});
|
||||
|
||||
assert(`foo ${{}}` === "foo [object Object]");
|
||||
assert(`foo ${{ bar: { baz: "qux" } }}` === "foo [object Object]");
|
||||
assert(`foo ${"bar"} ${"baz"}` === "foo bar baz");
|
||||
assert(`${"foo"} bar baz` === "foo bar baz");
|
||||
assert(`${"foo bar baz"}` === "foo bar baz");
|
||||
test("objects in expressions", () => {
|
||||
expect(`foo ${{}}`).toBe("foo [object Object]");
|
||||
expect(`foo ${{ bar: { baz: "qux" } }}`).toBe("foo [object Object]");
|
||||
});
|
||||
|
||||
test("expressions at beginning of template literal", () => {
|
||||
expect(`${"foo"} bar baz`).toBe("foo bar baz");
|
||||
expect(`${"foo bar baz"}`).toBe("foo bar baz");
|
||||
});
|
||||
|
||||
test("multiple template literals", () => {
|
||||
expect(`foo ${"bar"} ${"baz"}`).toBe("foo bar baz");
|
||||
});
|
||||
|
||||
test("variables in expressions", () => {
|
||||
let a = 27;
|
||||
assert(`${a}` === "27");
|
||||
assert(`foo ${a}` === "foo 27");
|
||||
assert(`foo ${a ? "bar" : "baz"}` === "foo bar");
|
||||
assert(`foo ${(() => a)()}` === "foo 27");
|
||||
expect(`${a}`).toBe("27");
|
||||
expect(`foo ${a}`).toBe("foo 27");
|
||||
expect(`foo ${a ? "bar" : "baz"}`).toBe("foo bar");
|
||||
expect(`foo ${(() => a)()}`).toBe("foo 27");
|
||||
});
|
||||
|
||||
assert(`foo ${`bar`}` === "foo bar");
|
||||
assert(`${`${`${`${"foo"}`} bar`}`}` === "foo bar");
|
||||
assert(
|
||||
test("template literals in expressions", () => {
|
||||
expect(`foo ${`bar`}`).toBe("foo bar");
|
||||
expect(`${`${`${`${"foo"}`} bar`}`}`).toBe("foo bar");
|
||||
});
|
||||
|
||||
test("newline literals (not characters)", () => {
|
||||
expect(
|
||||
`foo
|
||||
bar` === "foo\n bar"
|
||||
);
|
||||
bar`
|
||||
).toBe("foo\n bar");
|
||||
});
|
||||
|
||||
assertThrowsError(
|
||||
() => {
|
||||
`${b}`;
|
||||
},
|
||||
{
|
||||
error: ReferenceError,
|
||||
message: "'b' is not defined",
|
||||
}
|
||||
);
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
||||
test("reference error from expressions", () => {
|
||||
expect(() => `${b}`).toThrowWithMessage(ReferenceError, "'b' is not defined");
|
||||
});
|
||||
|
|
|
@ -1,30 +1,34 @@
|
|||
load("test-common.js");
|
||||
test("throw literal", () => {
|
||||
try {
|
||||
throw 1;
|
||||
expect().fail();
|
||||
} catch (e) {
|
||||
if (e.name === "ExpectationError") throw e;
|
||||
expect(e).toBe(1);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
throw 1;
|
||||
assertNotReached();
|
||||
} catch (e) {
|
||||
assert(e === 1);
|
||||
}
|
||||
test("throw array", () => {
|
||||
try {
|
||||
throw [99];
|
||||
expect().fail();
|
||||
} catch (e) {
|
||||
if (e.name === "ExpectationError") throw e;
|
||||
expect(e).toEqual([99]);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
throw [99];
|
||||
assertNotReached();
|
||||
} catch (e) {
|
||||
assert(typeof e === "object");
|
||||
assert(e.length === 1);
|
||||
}
|
||||
test("call function that throws", () => {
|
||||
function foo() {
|
||||
throw "hello";
|
||||
expect().fail();
|
||||
}
|
||||
|
||||
function foo() {
|
||||
throw "hello";
|
||||
assertNotReached();
|
||||
}
|
||||
|
||||
try {
|
||||
foo();
|
||||
assertNotReached();
|
||||
} catch (e) {
|
||||
assert(e === "hello");
|
||||
}
|
||||
|
||||
console.log("PASS");
|
||||
try {
|
||||
foo();
|
||||
expect().fail();
|
||||
} catch (e) {
|
||||
if (e.name === "ExpectationError") throw e;
|
||||
expect(e).toBe("hello");
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,62 +1,75 @@
|
|||
load("test-common.js");
|
||||
test("non-numeric primitives", () => {
|
||||
expect(+false).toBe(0);
|
||||
expect(-false).toBe(-0);
|
||||
expect(+true).toBe(1);
|
||||
expect(-true).toBe(-1);
|
||||
expect(+null).toBe(0);
|
||||
expect(-null).toBe(-0);
|
||||
expect(+undefined).toBeNaN();
|
||||
expect(-undefined).toBeNaN();
|
||||
});
|
||||
|
||||
try {
|
||||
assert(+false === 0);
|
||||
assert(-false === 0);
|
||||
assert(+true === 1);
|
||||
assert(-true === -1);
|
||||
assert(+null === 0);
|
||||
assert(-null === 0);
|
||||
assert(+[] === 0);
|
||||
assert(-[] === 0);
|
||||
assert(+[,] === 0);
|
||||
assert(-[,] === 0);
|
||||
assert(+[null] === 0);
|
||||
assert(-[null] === 0);
|
||||
assert(+[undefined] === 0);
|
||||
assert(-[undefined] === 0);
|
||||
assert(+[[[[[]]]]] === 0);
|
||||
assert(-[[[[[]]]]] === 0);
|
||||
assert(+[[[[[42]]]]] === 42);
|
||||
assert(-[[[[[42]]]]] === -42);
|
||||
assert(+"" === 0);
|
||||
assert(-"" === 0);
|
||||
assert(+"42" === 42);
|
||||
assert(-"42" === -42);
|
||||
assert(+42 === 42);
|
||||
assert(-42 === -42);
|
||||
assert(+1.23 === 1.23);
|
||||
assert(-1.23 === -1.23);
|
||||
assert(+"1.23" === 1.23);
|
||||
assert(-"1.23" === -1.23);
|
||||
assert(+"Infinity" === Infinity);
|
||||
assert(+"+Infinity" === Infinity);
|
||||
assert(+"-Infinity" === -Infinity);
|
||||
assert(-"Infinity" === -Infinity);
|
||||
assert(-"+Infinity" === -Infinity);
|
||||
assert(-"-Infinity" === Infinity);
|
||||
assert(+" \r \t \n " === 0);
|
||||
assert(+" \n \t Infinity \r " === Infinity);
|
||||
assert(+"\r \n1.23 \t\t\t \n" === 1.23);
|
||||
test("arrays", () => {
|
||||
expect(+[]).toBe(0);
|
||||
expect(-[]).toBe(-0);
|
||||
expect(+[,]).toBe(0);
|
||||
expect(-[,]).toBe(-0);
|
||||
expect(+[null]).toBe(0);
|
||||
expect(-[null]).toBe(-0);
|
||||
expect(+[undefined]).toBe(0);
|
||||
expect(-[undefined]).toBe(-0);
|
||||
expect(+[[[[[]]]]]).toBe(0);
|
||||
expect(-[[[[[]]]]]).toBe(-0);
|
||||
expect(+[[[[[42]]]]]).toBe(42);
|
||||
expect(-[[[[[42]]]]]).toBe(-42);
|
||||
|
||||
assert(isNaN(+undefined));
|
||||
assert(isNaN(-undefined));
|
||||
assert(isNaN(+{}));
|
||||
assert(isNaN(-{}));
|
||||
assert(isNaN(+{ a: 1 }));
|
||||
assert(isNaN(-{ a: 1 }));
|
||||
assert(isNaN(+[, , ,]));
|
||||
assert(isNaN(-[, , ,]));
|
||||
assert(isNaN(+[undefined, undefined]));
|
||||
assert(isNaN(-[undefined, undefined]));
|
||||
assert(isNaN(+[1, 2, 3]));
|
||||
assert(isNaN(-[1, 2, 3]));
|
||||
assert(isNaN(+[[[["foo"]]]]));
|
||||
assert(isNaN(-[[[["foo"]]]]));
|
||||
assert(isNaN(+"foo"));
|
||||
assert(isNaN(-"foo"));
|
||||
expect(+[, , ,]).toBeNaN();
|
||||
expect(-[, , ,]).toBeNaN();
|
||||
expect(+[undefined, undefined]).toBeNaN();
|
||||
expect(-[undefined, undefined]).toBeNaN();
|
||||
expect(+[1, 2, 3]).toBeNaN();
|
||||
expect(-[1, 2, 3]).toBeNaN();
|
||||
expect(+[[[["foo"]]]]).toBeNaN();
|
||||
expect(-[[[["foo"]]]]).toBeNaN();
|
||||
});
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
||||
test("strings", () => {
|
||||
expect(+"").toBe(0);
|
||||
expect(-"").toBe(-0);
|
||||
expect(+"42").toBe(42);
|
||||
expect(-"42").toBe(-42);
|
||||
expect(+"1.23").toBe(1.23);
|
||||
expect(-"1.23").toBe(-1.23);
|
||||
|
||||
expect(+"foo").toBeNaN();
|
||||
expect(-"foo").toBeNaN();
|
||||
});
|
||||
|
||||
test("numbers", () => {
|
||||
expect(+42).toBe(42);
|
||||
expect(-42).toBe(-42);
|
||||
expect(+1.23).toBe(1.23);
|
||||
expect(-1.23).toBe(-1.23);
|
||||
});
|
||||
|
||||
test("infinity", () => {
|
||||
expect(+"Infinity").toBe(Infinity);
|
||||
expect(+"+Infinity").toBe(Infinity);
|
||||
expect(+"-Infinity").toBe(-Infinity);
|
||||
expect(-"Infinity").toBe(-Infinity);
|
||||
expect(-"+Infinity").toBe(-Infinity);
|
||||
expect(-"-Infinity").toBe(Infinity);
|
||||
});
|
||||
|
||||
test("space and space-like escapes", () => {
|
||||
expect(+" \r \t \n ").toBe(0);
|
||||
expect(+" \n \t Infinity \r ").toBe(Infinity);
|
||||
expect(+"\r \n1.23 \t\t\t \n").toBe(1.23);
|
||||
});
|
||||
|
||||
test("object literals", () => {
|
||||
expect(+{}).toBeNaN();
|
||||
expect(-{}).toBeNaN();
|
||||
expect(+{ a: 1 }).toBeNaN();
|
||||
expect(-{ a: 1 }).toBeNaN();
|
||||
});
|
||||
|
|
|
@ -1,54 +1,25 @@
|
|||
load("test-common.js");
|
||||
const message = "oops, Value::to_number() failed";
|
||||
|
||||
try {
|
||||
const message = "oops, Value::to_number() failed";
|
||||
const o = {
|
||||
toString() {
|
||||
throw new Error(message);
|
||||
},
|
||||
};
|
||||
const o = {
|
||||
toString() {
|
||||
throw new Error(message);
|
||||
},
|
||||
};
|
||||
|
||||
assertThrowsError(
|
||||
() => {
|
||||
+o;
|
||||
},
|
||||
{
|
||||
error: Error,
|
||||
message,
|
||||
}
|
||||
);
|
||||
test("basic functionality", () => {
|
||||
expect(() => {
|
||||
+o;
|
||||
}).toThrowWithMessage(Error, message);
|
||||
|
||||
assertThrowsError(
|
||||
() => {
|
||||
o - 1;
|
||||
},
|
||||
{
|
||||
error: Error,
|
||||
message,
|
||||
}
|
||||
);
|
||||
expect(() => {
|
||||
o - 1;
|
||||
}).toThrowWithMessage(Error, message);
|
||||
|
||||
assertThrowsError(
|
||||
() => {
|
||||
"foo".charAt(o);
|
||||
},
|
||||
{
|
||||
error: Error,
|
||||
message,
|
||||
}
|
||||
);
|
||||
expect(() => {
|
||||
"foo".charAt(o);
|
||||
}).toThrowWithMessage(Error, message);
|
||||
|
||||
assertThrowsError(
|
||||
() => {
|
||||
"bar".repeat(o);
|
||||
},
|
||||
{
|
||||
error: Error,
|
||||
message,
|
||||
}
|
||||
);
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
||||
expect(() => {
|
||||
"bar".repeat(o);
|
||||
}).toThrowWithMessage(Error, message);
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
test("basic update expression", () => {
|
||||
var o = {};
|
||||
const o = {};
|
||||
o.f = 1;
|
||||
|
||||
expect(o.f++).toBe(1);
|
||||
|
|
|
@ -1,57 +1,53 @@
|
|||
load("test-common.js");
|
||||
describe("correct behavior", () => {
|
||||
test("basic functionality", () => {
|
||||
let n = 0;
|
||||
expect(++n).toBe(1);
|
||||
expect(n).toBe(1);
|
||||
|
||||
try {
|
||||
assertThrowsError(
|
||||
() => {
|
||||
n = 0;
|
||||
expect(n++).toBe(0);
|
||||
expect(n).toBe(1);
|
||||
|
||||
n = 0;
|
||||
expect(--n).toBe(-1);
|
||||
expect(n).toBe(-1);
|
||||
|
||||
n = 0;
|
||||
expect(n--).toBe(0);
|
||||
expect(n).toBe(-1);
|
||||
|
||||
let a = [];
|
||||
expect(a++).toBe(0);
|
||||
expect(a).toBe(1);
|
||||
|
||||
let b = true;
|
||||
expect(b--).toBe(1);
|
||||
expect(b).toBe(0);
|
||||
});
|
||||
|
||||
test("updates that produce NaN", () => {
|
||||
let s = "foo";
|
||||
expect(++s).toBeNaN();
|
||||
expect(s).toBeNaN();
|
||||
|
||||
s = "foo";
|
||||
expect(s++).toBeNaN();
|
||||
expect(s).toBeNaN();
|
||||
|
||||
s = "foo";
|
||||
expect(--s).toBeNaN();
|
||||
expect(s).toBeNaN();
|
||||
|
||||
s = "foo";
|
||||
expect(s--).toBeNaN();
|
||||
expect(s).toBeNaN();
|
||||
});
|
||||
});
|
||||
|
||||
describe("errors", () => {
|
||||
test("update expression throws reference error", () => {
|
||||
expect(() => {
|
||||
++x;
|
||||
},
|
||||
{
|
||||
error: ReferenceError,
|
||||
message: "'x' is not defined",
|
||||
}
|
||||
);
|
||||
|
||||
var n = 0;
|
||||
assert(++n === 1);
|
||||
assert(n === 1);
|
||||
|
||||
var n = 0;
|
||||
assert(n++ === 0);
|
||||
assert(n === 1);
|
||||
|
||||
var n = 0;
|
||||
assert(--n === -1);
|
||||
assert(n === -1);
|
||||
|
||||
var n = 0;
|
||||
assert(n-- === 0);
|
||||
assert(n === -1);
|
||||
|
||||
var a = [];
|
||||
assert(a++ === 0);
|
||||
assert(a === 1);
|
||||
|
||||
var b = true;
|
||||
assert(b-- === 1);
|
||||
assert(b === 0);
|
||||
|
||||
var s = "foo";
|
||||
assert(isNaN(++s));
|
||||
assert(isNaN(s));
|
||||
|
||||
var s = "foo";
|
||||
assert(isNaN(s++));
|
||||
assert(isNaN(s));
|
||||
|
||||
var s = "foo";
|
||||
assert(isNaN(--s));
|
||||
assert(isNaN(s));
|
||||
|
||||
var s = "foo";
|
||||
assert(isNaN(s--));
|
||||
assert(isNaN(s));
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
||||
}).toThrowWithMessage(ReferenceError, "'x' is not defined");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
load("test-common.js");
|
||||
|
||||
try {
|
||||
test("basic functionality", () => {
|
||||
var a = 1,
|
||||
b = 2,
|
||||
c = a + b;
|
||||
assert(a === 1);
|
||||
assert(b === 2);
|
||||
assert(c === 3);
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
||||
expect(a).toBe(1);
|
||||
expect(b).toBe(2);
|
||||
expect(c).toBe(3);
|
||||
});
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
load("test-common.js");
|
||||
|
||||
try {
|
||||
test("basic functionality", () => {
|
||||
function foo() {
|
||||
i = 3;
|
||||
assert(i === 3);
|
||||
expect(i).toBe(3);
|
||||
var i;
|
||||
}
|
||||
|
||||
|
@ -15,9 +13,5 @@ try {
|
|||
} catch (e) {
|
||||
caught_exception = e;
|
||||
}
|
||||
assert(caught_exception !== undefined);
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
||||
expect(caught_exception).not.toBeUndefined();
|
||||
});
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
load("test-common.js");
|
||||
|
||||
try {
|
||||
const constantValue = 1;
|
||||
assertThrowsError(
|
||||
() => {
|
||||
constantValue = 2;
|
||||
},
|
||||
{
|
||||
error: TypeError,
|
||||
message: "Invalid assignment to const variable",
|
||||
}
|
||||
);
|
||||
assert(constantValue === 1);
|
||||
|
||||
// Make sure we can define new constants in inner scopes.
|
||||
const constantValue2 = 1;
|
||||
do {
|
||||
const constantValue2 = 2;
|
||||
assert(constantValue2 === 2);
|
||||
} while (false);
|
||||
assert(constantValue2 === 1);
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
|
@ -1,19 +1,14 @@
|
|||
load("test-common.js");
|
||||
test("basic functionality", () => {
|
||||
function foo(a) {
|
||||
return a;
|
||||
}
|
||||
|
||||
function foo(a) {
|
||||
return a;
|
||||
}
|
||||
|
||||
try {
|
||||
var x = undefined;
|
||||
assert(x === undefined);
|
||||
assert(foo(x) === undefined);
|
||||
expect(x).toBeUndefined();
|
||||
expect(foo(x)).toBeUndefined();
|
||||
|
||||
var o = {};
|
||||
o.x = x;
|
||||
assert(o.x === undefined);
|
||||
assert(o.x === x);
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
||||
expect(o.x).toBeUndefined();
|
||||
expect(o.x).toBe(x);
|
||||
});
|
||||
|
|
|
@ -172,6 +172,7 @@ Vector<String> tests_to_run = {
|
|||
"add-values-to-primitive.js",
|
||||
"automatic-semicolon-insertion.js",
|
||||
"comments-basic.js",
|
||||
"const-reassignment.js",
|
||||
"debugger-statement.js",
|
||||
"empty-statements.js",
|
||||
"exception-ReferenceError.js",
|
||||
|
@ -181,13 +182,28 @@ Vector<String> tests_to_run = {
|
|||
"let-scoping.js",
|
||||
"new-expression.js",
|
||||
"numeric-literals-basic.js",
|
||||
"object-basic.js",
|
||||
"object-getter-setter-shorthand.js",
|
||||
"object-method-shorthand.js",
|
||||
"object-spread.js",
|
||||
"tagged-template-literals.js",
|
||||
"test-common-tests.js",
|
||||
"parser-unary-associativity.js",
|
||||
"program-strict-mode.js",
|
||||
"strict-mode-errors.js",
|
||||
"string-escapes.js",
|
||||
"string-spread.js",
|
||||
"switch-basic.js",
|
||||
"switch-break.js",
|
||||
"tagged-template-literals.js",
|
||||
"template-literals.js",
|
||||
"test-common-tests.js",
|
||||
"throw-basic.js",
|
||||
"to-number-basic.js",
|
||||
"to-number-exception.js",
|
||||
"update-expression-on-member-expression.js",
|
||||
"update-expressions-basic.js",
|
||||
"var-multiple-declarator.js",
|
||||
"var-scoping.js",
|
||||
"variable-undefined.js",
|
||||
};
|
||||
|
||||
enum class TestResult {
|
||||
|
@ -236,15 +252,6 @@ struct JSTestRunnerCounts {
|
|||
|
||||
using JSTestRunnerResult = Vector<JSFileResult>;
|
||||
|
||||
double get_time()
|
||||
{
|
||||
struct timeval tv1;
|
||||
struct timezone tz1;
|
||||
auto return_code = gettimeofday(&tv1, &tz1);
|
||||
ASSERT(return_code >= 0);
|
||||
return static_cast<double>(tv1.tv_sec) * 1000.0 + static_cast<double>(tv1.tv_usec) / 1000.0;
|
||||
}
|
||||
|
||||
class TestRunner {
|
||||
public:
|
||||
TestRunner(String test_root, bool print_times)
|
||||
|
@ -269,6 +276,48 @@ private:
|
|||
RefPtr<JS::Program> m_test_program;
|
||||
};
|
||||
|
||||
class TestRunnerGlobalObject : public JS::GlobalObject {
|
||||
public:
|
||||
TestRunnerGlobalObject();
|
||||
virtual ~TestRunnerGlobalObject() override;
|
||||
|
||||
virtual void initialize() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "TestRunnerGlobalObject"; }
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(is_strict_mode);
|
||||
};
|
||||
|
||||
TestRunnerGlobalObject::TestRunnerGlobalObject()
|
||||
{
|
||||
}
|
||||
|
||||
TestRunnerGlobalObject::~TestRunnerGlobalObject()
|
||||
{
|
||||
}
|
||||
|
||||
void TestRunnerGlobalObject::initialize()
|
||||
{
|
||||
JS::GlobalObject::initialize();
|
||||
define_property("global", this, JS::Attribute::Enumerable);
|
||||
define_native_function("isStrictMode", is_strict_mode);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(TestRunnerGlobalObject::is_strict_mode)
|
||||
{
|
||||
return JS::Value(interpreter.in_strict_mode());
|
||||
}
|
||||
|
||||
double get_time()
|
||||
{
|
||||
struct timeval tv1;
|
||||
struct timezone tz1;
|
||||
auto return_code = gettimeofday(&tv1, &tz1);
|
||||
ASSERT(return_code >= 0);
|
||||
return static_cast<double>(tv1.tv_sec) * 1000.0 + static_cast<double>(tv1.tv_usec) / 1000.0;
|
||||
}
|
||||
|
||||
void TestRunner::run()
|
||||
{
|
||||
for (auto& test_path : tests_to_run)
|
||||
|
@ -316,7 +365,7 @@ Optional<JsonValue> get_test_results(JS::Interpreter& interpreter)
|
|||
JSFileResult TestRunner::run_file_test(const String& test_path)
|
||||
{
|
||||
double start_time = get_time();
|
||||
auto interpreter = JS::Interpreter::create<JS::GlobalObject>();
|
||||
auto interpreter = JS::Interpreter::create<TestRunnerGlobalObject>();
|
||||
|
||||
if (!m_test_program) {
|
||||
auto result = parse_file(String::format("%s/test-common.js", m_test_root.characters()));
|
||||
|
|
Loading…
Add table
Reference in a new issue