mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 14:28:12 +00:00
LibJS: Convert some top-level tests to the new system
First test conversions! These look really good :)
This commit is contained in:
parent
4b8a3e6d78
commit
eea6041302
22 changed files with 464 additions and 451 deletions
|
@ -1,12 +1,6 @@
|
||||||
load("test-common.js");
|
test("adding objects", () => {
|
||||||
|
expect([] + []).toBe("");
|
||||||
try {
|
expect([] + {}).toBe("[object Object]");
|
||||||
// Note that these will give different results in the REPL due to parsing behavior.
|
expect({} + {}).toBe("[object Object][object Object]");
|
||||||
assert([] + [] === "");
|
expect({} + []).toBe("[object Object]");
|
||||||
assert([] + {} === "[object Object]");
|
});
|
||||||
assert({} + {} === "[object Object][object Object]");
|
|
||||||
assert({} + [] === "[object Object]");
|
|
||||||
console.log("PASS");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("FAIL: " + e);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
/**
|
if (1)
|
||||||
* This file tests automatic semicolon insertion rules.
|
return 1
|
||||||
* If this file produces syntax errors, something is wrong.
|
else
|
||||||
*/
|
return 0
|
||||||
|
|
||||||
function bar() {
|
if (1)
|
||||||
// https://github.com/SerenityOS/serenity/issues/1829
|
return 1
|
||||||
if (1)
|
else
|
||||||
return 1;
|
return 0;`;
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (1)
|
expect(source).toEval();
|
||||||
return 1
|
});
|
||||||
else
|
|
||||||
return 0
|
|
||||||
|
|
||||||
if (1)
|
test("break/continue, variable declaration, do-while, and return asi", () => {
|
||||||
return 1
|
const source =
|
||||||
else
|
`function foo() {
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function foo() {
|
|
||||||
label:
|
label:
|
||||||
for (var i = 0; i < 4; i++) {
|
for (var i = 0; i < 4; i++) {
|
||||||
break // semicolon inserted here
|
break // semicolon inserted here
|
||||||
|
@ -43,30 +39,30 @@ function foo() {
|
||||||
1;
|
1;
|
||||||
var curly/* semicolon inserted here */}
|
var curly/* semicolon inserted here */}
|
||||||
|
|
||||||
function baz() {
|
return foo();`;
|
||||||
let counter = 0;
|
|
||||||
let outer;
|
|
||||||
|
|
||||||
outer:
|
expect(source).toEvalTo(undefined);
|
||||||
for (let i = 0; i < 5; ++i) {
|
});
|
||||||
for (let j = 0; j < 5; ++j) {
|
|
||||||
continue // semicolon inserted here
|
test("more break and continue asi", () => {
|
||||||
outer // semicolon inserted here
|
const source =
|
||||||
}
|
`let counter = 0;
|
||||||
counter++;
|
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
|
||||||
}
|
}
|
||||||
|
counter++;
|
||||||
return counter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return counter;`;
|
||||||
assert(foo() === undefined);
|
|
||||||
assert(baz() === 5);
|
|
||||||
|
|
||||||
console.log("PASS");
|
expect(source).toEvalTo(5);
|
||||||
} catch (e) {
|
});
|
||||||
console.log("FAIL: " + e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This vardecl must appear exactly at the end of the file (no newline or whitespace after it)
|
test("eof with no semicolon", () => {
|
||||||
var eof
|
expect("var eof").toEval();
|
||||||
|
});
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
load("test-common.js")
|
test("regular comments", () => {
|
||||||
|
const source =
|
||||||
|
`var i = 0;
|
||||||
|
|
||||||
try {
|
// i++;
|
||||||
var i = 0;
|
/* i++; */
|
||||||
|
/*
|
||||||
|
i++;
|
||||||
|
*/
|
||||||
|
return i;`;
|
||||||
|
|
||||||
// i++;
|
expect(source).toEvalTo(0);
|
||||||
/* i++; */
|
});
|
||||||
/*
|
|
||||||
i++;
|
|
||||||
*/
|
|
||||||
<!-- i++; --> i++;
|
|
||||||
<!-- i++;
|
|
||||||
i++;
|
|
||||||
--> i++;
|
|
||||||
|
|
||||||
assert(i === 1);
|
test("html comments", () => {
|
||||||
|
const source =
|
||||||
console.log('PASS');
|
`var i = 0;
|
||||||
} catch (e) {
|
<!-- i++; --> i++;
|
||||||
console.log('FAIL: ' + e);
|
<!-- i++;
|
||||||
}
|
i++;
|
||||||
|
--> i++;
|
||||||
|
return i;`
|
||||||
|
|
||||||
|
expect(source).toEvalTo(1);
|
||||||
|
});
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
load("test-common.js");
|
test("debugger keyword", () => {
|
||||||
|
expect("debugger").toEval();
|
||||||
try {
|
});
|
||||||
debugger;
|
|
||||||
|
|
||||||
console.log("PASS");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("FAIL: " + e);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
try {
|
test("empty semicolon statements", () => {
|
||||||
;;;
|
expect(";;;").toEval();
|
||||||
if (true);
|
});
|
||||||
if (false); else if (false); else;
|
|
||||||
while (false);
|
|
||||||
do; while (false);
|
|
||||||
|
|
||||||
console.log("PASS");
|
test("if with no body", () => {
|
||||||
} catch (e) {
|
expect("if (true);").toEval();
|
||||||
console.log("FAIL: " + e);
|
});
|
||||||
}
|
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
load("test-common.js");
|
test("unknown variable produces ReferenceError", () => {
|
||||||
|
expect(new Function("i < 3")).toThrow(ReferenceError);
|
||||||
try {
|
});
|
||||||
i < 3;
|
|
||||||
} catch (e) {
|
|
||||||
assert(e.name === "ReferenceError");
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("PASS");
|
|
||||||
|
|
|
@ -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 {
|
test("exponentation with negatives", () => {
|
||||||
assert(2 ** 0 === 1);
|
expect(2 ** -3).toBe(0.125);
|
||||||
assert(2 ** 1 === 2);
|
expect((-2) ** 3).toBe(-8);
|
||||||
assert(2 ** 2 === 4);
|
|
||||||
assert(2 ** 3 === 8);
|
// FIXME: This should fail :)
|
||||||
assert(2 ** -3 === 0.125);
|
// expect("-2 ** 3").not.toEval();
|
||||||
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));
|
|
||||||
|
|
||||||
console.log("PASS");
|
test("exponentation with non-numeric primitives", () => {
|
||||||
} catch (e) {
|
expect("2" ** "3").toBe(8);
|
||||||
console.log("FAIL: " + e);
|
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();
|
||||||
|
});
|
||||||
|
|
|
@ -1,19 +1,15 @@
|
||||||
load("test-common.js");
|
test("string literal indexing", () => {
|
||||||
|
|
||||||
try {
|
|
||||||
var s = "foo";
|
var s = "foo";
|
||||||
assert(s[0] === "f");
|
expect(s[0]).toBe("f");
|
||||||
assert(s[1] === "o");
|
expect(s[1]).toBe("o");
|
||||||
assert(s[2] === "o");
|
expect(s[2]).toBe("o");
|
||||||
assert(s[3] === undefined);
|
expect(s[3]).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
var o = new String("bar");
|
test("string object indexing", () => {
|
||||||
assert(o[0] === "b");
|
var s = new String("bar");
|
||||||
assert(o[1] === "a");
|
expect(s[0]).toBe("b");
|
||||||
assert(o[2] === "r");
|
expect(s[1]).toBe("a");
|
||||||
assert(o[3] === undefined);
|
expect(s[2]).toBe("r");
|
||||||
|
expect(s[3]).toBeUndefined();
|
||||||
console.log("PASS");
|
});
|
||||||
} catch (e) {
|
|
||||||
console.log("FAIL: " + e);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,23 +1,13 @@
|
||||||
load("test-common.js");
|
|
||||||
|
|
||||||
try {
|
test("assignment to function call", () => {
|
||||||
function foo() { }
|
expect(() => {
|
||||||
|
function foo() {};
|
||||||
assertThrowsError(() => {
|
|
||||||
foo() = "foo";
|
foo() = "foo";
|
||||||
}, {
|
}).toThrowWithMessage(ReferenceError, "Invalid left-hand side in assignment");
|
||||||
error: ReferenceError,
|
});
|
||||||
message: "Invalid left-hand side in assignment"
|
|
||||||
});
|
|
||||||
|
|
||||||
assertThrowsError(() => {
|
test("assignment to inline function call", () => {
|
||||||
|
expect(() => {
|
||||||
(function () { })() = "foo";
|
(function () { })() = "foo";
|
||||||
}, {
|
}).toThrowWithMessage(ReferenceError, "Invalid left-hand side in assignment");
|
||||||
error: ReferenceError,
|
});
|
||||||
message: "Invalid left-hand side in assignment"
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("PASS");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("FAIL: " + e);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
load("test-common.js");
|
test("labeled plain scope", () => {
|
||||||
|
|
||||||
try {
|
|
||||||
test: {
|
test: {
|
||||||
let o = 1;
|
let o = 1;
|
||||||
assert(o === 1);
|
expect(o).toBe(1);
|
||||||
break test;
|
break test;
|
||||||
assertNotReached();
|
expect().fail();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("break on plain scope from inner scope", () => {
|
||||||
outer: {
|
outer: {
|
||||||
{
|
{
|
||||||
break outer;
|
break outer;
|
||||||
}
|
}
|
||||||
assertNotReached();
|
expect().fail();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("labeled for loop with break", () => {
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
outer:
|
outer:
|
||||||
for (a of [1, 2, 3]) {
|
for (a of [1, 2, 3]) {
|
||||||
|
@ -24,8 +26,10 @@ try {
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(counter === 4);
|
expect(counter).toBe(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("labeled for loop with continue", () => {
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
outer:
|
outer:
|
||||||
for (a of [1, 2, 3]) {
|
for (a of [1, 2, 3]) {
|
||||||
|
@ -35,9 +39,5 @@ try {
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(counter === 6);
|
expect(counter).toBe(6);
|
||||||
|
});
|
||||||
console.log("PASS");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("FAIL: " + e);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,23 +1,14 @@
|
||||||
load("test-common.js");
|
test("let scoping", () => {
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
let i = 1;
|
let i = 1;
|
||||||
{
|
{
|
||||||
let i = 3;
|
let i = 3;
|
||||||
assert(i === 3);
|
expect(i).toBe(3);
|
||||||
}
|
}
|
||||||
|
expect(i).toBe(1);
|
||||||
assert(i === 1);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const i = 2;
|
const i = 2;
|
||||||
assert(i === 2);
|
expect(i).toBe(2);
|
||||||
}
|
}
|
||||||
|
expect(i).toBe(1);
|
||||||
assert(i === 1);
|
});
|
||||||
|
|
||||||
console.log("PASS");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("FAIL: " + e);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,51 +1,49 @@
|
||||||
load("test-common.js");
|
test("new-expression parsing", () => {
|
||||||
|
|
||||||
try {
|
|
||||||
function Foo() { this.x = 1; }
|
function Foo() { this.x = 1; }
|
||||||
|
|
||||||
let foo = new Foo();
|
let foo = new Foo();
|
||||||
assert(foo.x === 1);
|
expect(foo.x).toBe(1);
|
||||||
|
|
||||||
foo = new Foo
|
foo = new Foo
|
||||||
assert(foo.x === 1);
|
expect(foo.x).toBe(1);
|
||||||
|
|
||||||
foo = new
|
foo = new
|
||||||
Foo
|
Foo
|
||||||
()
|
()
|
||||||
assert(foo.x === 1);
|
expect(foo.x).toBe(1);
|
||||||
|
|
||||||
foo = new Foo + 2
|
foo = new Foo + 2
|
||||||
assert(foo === "[object Object]2");
|
expect(foo).toBe("[object Object]2");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("new-expressions with object keys", () => {
|
||||||
let a = {
|
let a = {
|
||||||
b: function() {
|
b: function() {
|
||||||
this.x = 2;
|
this.x = 2;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
foo = new a.b();
|
foo = new a.b();
|
||||||
assert(foo.x === 2);
|
expect(foo.x).toBe(2);
|
||||||
|
|
||||||
foo = new a.b;
|
foo = new a.b;
|
||||||
assert(foo.x === 2);
|
expect(foo.x).toBe(2);
|
||||||
|
|
||||||
foo = new
|
foo = new
|
||||||
a.b();
|
a.b();
|
||||||
assert(foo.x === 2);
|
expect(foo.x).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("new-expressions with function calls", () => {
|
||||||
function funcGetter() {
|
function funcGetter() {
|
||||||
return function(a, b) {
|
return function(a, b) {
|
||||||
this.x = a + b;
|
this.x = a + b;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
foo = new funcGetter()(1, 5);
|
foo = new funcGetter()(1, 5);
|
||||||
assert(foo === undefined);
|
expect(foo).toBeUndefined();
|
||||||
|
|
||||||
foo = new (funcGetter())(1, 5);
|
foo = new (funcGetter())(1, 5);
|
||||||
assert(foo.x === 6);
|
expect(foo.x).toBe(6);
|
||||||
|
});
|
||||||
console.log("PASS");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("FAIL: " + e);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,29 +1,37 @@
|
||||||
load("test-common.js");
|
test("hex literals", () => {
|
||||||
|
expect(0xff).toBe(255);
|
||||||
|
expect(0xFF).toBe(255);
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
test("octal literals", () => {
|
||||||
assert(0xff === 255);
|
expect(0o10).toBe(8);
|
||||||
assert(0XFF === 255);
|
expect(0O10).toBe(8);
|
||||||
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);
|
|
||||||
|
|
||||||
Number.prototype.foo = 'LOL';
|
test("binary literals", () => {
|
||||||
assert(1..foo === 'LOL');
|
expect(0b10).toBe(2);
|
||||||
assert(1.1.foo === 'LOL');
|
expect(0B10).toBe(2);
|
||||||
assert(.1.foo === 'LOL');
|
});
|
||||||
|
|
||||||
console.log("PASS");
|
test("exponential literals", () => {
|
||||||
} catch (e) {
|
expect(1e3).toBe(1000);
|
||||||
console.log("FAIL: " + e);
|
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");
|
||||||
|
});
|
||||||
|
|
|
@ -1,22 +1,24 @@
|
||||||
load("test-common.js")
|
test("normal methods named get and set", () => {
|
||||||
|
|
||||||
try {
|
|
||||||
let o = {
|
let o = {
|
||||||
get() { return 5; },
|
get() { return 5; },
|
||||||
set() { return 10; },
|
set() { return 10; },
|
||||||
};
|
};
|
||||||
assert(o.get() === 5);
|
expect(o.get()).toBe(5);
|
||||||
assert(o.set() === 10);
|
expect(o.set()).toBe(10);
|
||||||
|
});
|
||||||
|
|
||||||
o = {
|
test("basic get and set", () => {
|
||||||
|
let o = {
|
||||||
get x() { return 5; },
|
get x() { return 5; },
|
||||||
set x(_) { },
|
set x(_) { },
|
||||||
};
|
};
|
||||||
assert(o.x === 5);
|
expect(o.x).toBe(5);
|
||||||
o.x = 10;
|
o.x = 10;
|
||||||
assert(o.x === 5);
|
expect(o.x).toBe(5);
|
||||||
|
});
|
||||||
|
|
||||||
o = {
|
test("get and set with 'this'", () => {
|
||||||
|
let o = {
|
||||||
get x() {
|
get x() {
|
||||||
return this._x + 1;
|
return this._x + 1;
|
||||||
},
|
},
|
||||||
|
@ -25,26 +27,24 @@ try {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
assert(isNaN(o.x));
|
expect(o.x).toBeNaN();
|
||||||
o.x = 10;
|
o.x = 10;
|
||||||
assert(o.x === 12);
|
expect(o.x).toBe(12);
|
||||||
o.x = 20;
|
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 5; },
|
||||||
get x() { return 10; },
|
get x() { return 10; },
|
||||||
};
|
};
|
||||||
|
expect(o.x).toBe(10);
|
||||||
|
});
|
||||||
|
|
||||||
assert(o.x === 10);
|
test("setter return value", () => {
|
||||||
|
|
||||||
o = {
|
o = {
|
||||||
set x(value) { return 10; },
|
set x(value) { return 10; },
|
||||||
};
|
};
|
||||||
|
expect(o.x = 20).toBe(20);
|
||||||
assert((o.x = 20) === 20);
|
});
|
||||||
|
|
||||||
console.log("PASS");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("FAIL: " + e);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,29 +1,39 @@
|
||||||
load("test-common.js");
|
test("basic method shorthand", () => {
|
||||||
|
|
||||||
try {
|
|
||||||
const o = {
|
const o = {
|
||||||
foo: "bar",
|
foo: "bar",
|
||||||
getFoo() {
|
getFoo() {
|
||||||
return this.foo;
|
return this.foo;
|
||||||
},
|
},
|
||||||
12() {
|
};
|
||||||
return this.getFoo();
|
expect(o.getFoo()).toBe("bar");
|
||||||
},
|
});
|
||||||
"hello friends"() {
|
|
||||||
return this.getFoo();
|
test("numeric literal method shorthand", () => {
|
||||||
},
|
const o = {
|
||||||
[4 + 10]() {
|
foo: "bar",
|
||||||
return this.getFoo();
|
12() {
|
||||||
|
return this.foo;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
expect(o[12]()).toBe("bar");
|
||||||
|
});
|
||||||
|
|
||||||
assert(o.foo === "bar");
|
test("string literal method shorthand", () => {
|
||||||
assert(o.getFoo() === "bar");
|
const o = {
|
||||||
assert(o[12]() === "bar");
|
foo: "bar",
|
||||||
assert(o["hello friends"]() === "bar");
|
"hello friends"() {
|
||||||
assert(o[14]() === "bar");
|
return this.foo;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
expect(o["hello friends"]()).toBe("bar");
|
||||||
|
});
|
||||||
|
|
||||||
console.log("PASS");
|
test("computed property method shorthand", () => {
|
||||||
} catch (e) {
|
const o = {
|
||||||
console.log("FAIL: " + e);
|
foo: "bar",
|
||||||
}
|
[4 + 10]() {
|
||||||
|
return this.foo;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
expect(o[14]()).toBe("bar");
|
||||||
|
});
|
||||||
|
|
|
@ -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) {
|
const testObjStrSpread = obj => {
|
||||||
return obj.foo === 0 &&
|
expect(obj).toEqual(["a", "b", "c", "d"]);
|
||||||
obj.bar === 1 &&
|
};
|
||||||
obj.baz === 2 &&
|
|
||||||
obj.qux === 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
function testObjStrSpread(obj) {
|
test("spread object literal inside object literal", () => {
|
||||||
return obj[0] === "a" &&
|
|
||||||
obj[1] === "b" &&
|
|
||||||
obj[2] === "c" &&
|
|
||||||
obj[3] === "d";
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
let obj = {
|
let obj = {
|
||||||
foo: 0,
|
foo: 0,
|
||||||
...{ bar: 1, baz: 2 },
|
...{ bar: 1, baz: 2 },
|
||||||
qux: 3,
|
qux: 3,
|
||||||
};
|
};
|
||||||
assert(testObjSpread(obj));
|
testObjSpread(obj);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("spread object with assigned property inside object literal", () => {
|
||||||
obj = { foo: 0, bar: 1, baz: 2 };
|
obj = { foo: 0, bar: 1, baz: 2 };
|
||||||
obj.qux = 3;
|
obj.qux = 3;
|
||||||
assert(testObjSpread({ ...obj }));
|
testObjSpread({ ...obj });
|
||||||
|
});
|
||||||
|
|
||||||
|
test("spread object inside object literal", () => {
|
||||||
let a = { bar: 1, baz: 2 };
|
let a = { bar: 1, baz: 2 };
|
||||||
obj = { foo: 0, ...a, qux: 3 };
|
obj = { foo: 0, ...a, qux: 3 };
|
||||||
assert(testObjSpread(obj));
|
testObjSpread(obj);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("complex nested object spreading", () => {
|
||||||
obj = {
|
obj = {
|
||||||
...{},
|
...{},
|
||||||
...{
|
...{
|
||||||
|
@ -37,25 +40,36 @@ try {
|
||||||
},
|
},
|
||||||
qux: 3,
|
qux: 3,
|
||||||
};
|
};
|
||||||
assert(testObjSpread(obj));
|
testObjSpread(obj);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("spread string in object literal", () => {
|
||||||
obj = { ..."abcd" };
|
obj = { ..."abcd" };
|
||||||
assert(testObjStrSpread(obj));
|
testObjStrSpread(obj);
|
||||||
|
});
|
||||||
obj = { ...["a", "b", "c", "d"] };
|
|
||||||
assert(testObjStrSpread(obj));
|
|
||||||
|
|
||||||
obj = { ...String("abcd") };
|
|
||||||
assert(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 };
|
a = { foo: 0 };
|
||||||
Object.defineProperty(a, 'bar', {
|
Object.defineProperty(a, "bar", {
|
||||||
value: 1,
|
value: 1,
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
});
|
});
|
||||||
obj = { ...a };
|
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 = ({
|
let empty = ({
|
||||||
...undefined,
|
...undefined,
|
||||||
...null,
|
...null,
|
||||||
|
@ -64,9 +78,5 @@ try {
|
||||||
...function(){},
|
...function(){},
|
||||||
...Date,
|
...Date,
|
||||||
});
|
});
|
||||||
assert(Object.getOwnPropertyNames(empty).length === 0);
|
expect(Object.getOwnPropertyNames(empty)).toHaveLength(0);
|
||||||
|
});
|
||||||
console.log("PASS");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("FAIL: " + e);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
var a = "foo";
|
|
||||||
|
|
||||||
switch (a + "bar") {
|
|
||||||
case 1:
|
|
||||||
assertNotReached();
|
|
||||||
break;
|
|
||||||
case "foobar":
|
|
||||||
case 2:
|
|
||||||
console.log("PASS");
|
|
||||||
break;
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
var a = "foo";
|
|
||||||
|
|
||||||
switch (100) {
|
|
||||||
default:
|
|
||||||
console.log("PASS");
|
|
||||||
}
|
|
|
@ -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) {
|
expect().fail();
|
||||||
case '3':
|
});
|
||||||
assertNotReached();
|
|
||||||
case 3:
|
test("string concatenation in target", () => {
|
||||||
console.log("PASS");
|
var a = "foo";
|
||||||
break;
|
|
||||||
case 5:
|
switch (a + "bar") {
|
||||||
case 1:
|
case 1:
|
||||||
break;
|
expect().fail();
|
||||||
default:
|
case "foobar":
|
||||||
break;
|
case 2:
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
expect().fail();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("default", () => {
|
||||||
|
switch (100) {
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect().fail();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -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 {
|
expect(() => {
|
||||||
assertThrowsError(() => {
|
function foo() {};
|
||||||
foo`bar${baz}`;
|
foo`bar${baz}`;
|
||||||
}, {
|
}).toThrowWithMessage(ReferenceError, "'baz' is not defined");
|
||||||
error: ReferenceError,
|
|
||||||
message: "'foo' is not defined"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assertThrowsError(() => {
|
test("cannot tag a non-function", () => {
|
||||||
function foo() { }
|
expect(() => {
|
||||||
foo`bar${baz}`;
|
undefined``;
|
||||||
}, {
|
}).toThrowWithMessage(TypeError, "undefined is not a function");
|
||||||
error: ReferenceError,
|
|
||||||
message: "'baz' is not defined"
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
assertThrowsError(() => {
|
describe("tagged template literal functionality", () => {
|
||||||
undefined``````;
|
test("empty template tag", () => {
|
||||||
}, {
|
function test1(strings) {
|
||||||
error: TypeError,
|
expect(strings).toBeInstanceOf(Array);
|
||||||
message: "undefined is not a function"
|
expect(strings).toHaveLength(1);
|
||||||
});
|
expect(strings[0]).toBe("");
|
||||||
|
return 42;
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
}
|
expect(test1``).toBe(42);
|
||||||
assert(test2("foo")`bar` === "foobar");
|
});
|
||||||
|
|
||||||
var test3 = {
|
test("tagging a template literal", () => {
|
||||||
foo(strings, p1) {
|
function test2(s) {
|
||||||
assert(strings instanceof Array);
|
return function (strings) {
|
||||||
assert(strings.length === 2);
|
expect(strings).toBeInstanceOf(Array);
|
||||||
assert(strings[0] === "");
|
expect(strings).toHaveLength(1);
|
||||||
assert(strings[1] === "");
|
expect(strings[0]).toBe("bar");
|
||||||
assert(p1 === "bar");
|
return s + strings[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
expect(test2("foo")`bar`).toBe("foobar");
|
||||||
test3.foo`${"bar"}`;
|
});
|
||||||
|
|
||||||
function test4(strings, p1) {
|
test("tagging an object function key", () => {
|
||||||
assert(strings instanceof Array);
|
var test3 = {
|
||||||
assert(strings.length === 2);
|
foo(strings, p1) {
|
||||||
assert(strings[0] === "foo");
|
expect(strings).toBeInstanceOf(Array);
|
||||||
assert(strings[1] === "");
|
expect(strings).toHaveLength(2);
|
||||||
assert(p1 === 42);
|
expect(strings[0]).toBe("");
|
||||||
}
|
expect(strings[1]).toBe("");
|
||||||
var bar = 42;
|
expect(p1).toBe("bar");
|
||||||
test4`foo${bar}`;
|
}
|
||||||
|
};
|
||||||
|
test3.foo`${"bar"}`;
|
||||||
|
});
|
||||||
|
|
||||||
function test5(strings, p1, p2) {
|
test("tagging with a variable in a template expression", () => {
|
||||||
assert(strings instanceof Array);
|
function test4(strings, p1) {
|
||||||
assert(strings.length === 3);
|
expect(strings).toBeInstanceOf(Array);
|
||||||
assert(strings[0] === "foo");
|
expect(strings).toHaveLength(2);
|
||||||
assert(strings[1] === "baz");
|
expect(strings[0]).toBe("foo");
|
||||||
assert(strings[2] === "");
|
expect(strings[1]).toBe("");
|
||||||
assert(p1 === 42);
|
expect(p1).toBe(42);
|
||||||
assert(p2 === "qux");
|
}
|
||||||
return (strings, value) => `${value}${strings[0]}`;
|
var bar = 42;
|
||||||
}
|
test4`foo${bar}`;
|
||||||
var bar = 42;
|
});
|
||||||
assert(test5`foo${bar}baz${"qux"}``test${123}` === "123test");
|
|
||||||
|
|
||||||
function review(strings, name, rating) {
|
test("template tag result of another template tag", () => {
|
||||||
return `${strings[0]}**${name}**${strings[1]}_${rating}_${strings[2]}`;
|
function test5(strings, p1, p2) {
|
||||||
}
|
expect(strings).toBeInstanceOf(Array);
|
||||||
var name = "SerenityOS";
|
expect(strings).toHaveLength(3);
|
||||||
var rating = "great";
|
expect(strings[0]).toBe("foo");
|
||||||
assert(review`${name} is a ${rating} project!` === "**SerenityOS** is a _great_ project!");
|
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;
|
test("general test", () => {
|
||||||
const getRawTemplateStrings = arr => arr.raw;
|
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`;
|
test("template object structure", () => {
|
||||||
assert(Object.getOwnPropertyNames(o[0]).includes('raw'));
|
const getTemplateObject = (...rest) => rest;
|
||||||
|
const getRawTemplateStrings = arr => arr.raw;
|
||||||
let raw = getRawTemplateStrings`foo${1 + 3}\nbar`;
|
|
||||||
assert(!Object.getOwnPropertyNames(raw).includes('raw'));
|
let o = getTemplateObject`foo\nbar`;
|
||||||
assert(raw.length === 2);
|
expect(Object.getOwnPropertyNames(o[0])).toContain("raw");
|
||||||
assert(raw[0] === 'foo');
|
|
||||||
assert(raw[1].length === 5 && raw[1] === '\\nbar');
|
let raw = getRawTemplateStrings`foo${1 + 3}\nbar`;
|
||||||
|
expect(Object.getOwnPropertyNames(raw)).not.toContain("raw");
|
||||||
console.log("PASS");
|
expect(raw).toHaveLength(2);
|
||||||
} catch (e) {
|
expect(raw[0]).toBe("foo");
|
||||||
console.log("FAIL: " + e);
|
expect(raw[1]).toHaveLength(5);
|
||||||
}
|
expect(raw[1]).toBe("\\nbar");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
load("test-common.js");
|
test("basic update expression", () => {
|
||||||
|
|
||||||
try {
|
|
||||||
var o = {};
|
var o = {};
|
||||||
o.f = 1;
|
o.f = 1;
|
||||||
|
|
||||||
assert(o.f++ === 1);
|
expect(o.f++).toBe(1);
|
||||||
assert(++o.f === 3);
|
expect(++o.f).toBe(3);
|
||||||
assert(isNaN(++o.missing));
|
expect(++o.missing).toBeNaN();
|
||||||
|
});
|
||||||
console.log("PASS");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("FAIL: " + e);
|
|
||||||
}
|
|
||||||
|
|
|
@ -51,6 +51,12 @@ Vector<String> tests_to_run = {
|
||||||
"exponentiation-basic.js",
|
"exponentiation-basic.js",
|
||||||
"indexed-access-string-object.js",
|
"indexed-access-string-object.js",
|
||||||
"invalid-lhs-in-assignment.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",
|
"tagged-template-literals.js",
|
||||||
"switch-basic.js",
|
"switch-basic.js",
|
||||||
"update-expression-on-member-expression.js",
|
"update-expression-on-member-expression.js",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue