mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
679 lines
21 KiB
JavaScript
679 lines
21 KiB
JavaScript
test("Nested try/catch/finally with continue", () => {
|
|
const executionOrder = [];
|
|
|
|
function callFromUpdateBlock(i) {
|
|
expect(i).toBe(2);
|
|
executionOrder.push(4);
|
|
}
|
|
|
|
function callFromTestBlock(i) {
|
|
expect(i).toBe(2);
|
|
executionOrder.push(5);
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
const foo = 0;
|
|
|
|
expect(foo).toBe(0);
|
|
|
|
for (let i = 1; i >= 2 ? callFromTestBlock(i) : true; ++i, callFromUpdateBlock(i)) {
|
|
const bar = 2;
|
|
|
|
expect(foo).toBe(0);
|
|
expect(i).toBe(1);
|
|
expect(bar).toBe(2);
|
|
|
|
try {
|
|
const baz = 3;
|
|
|
|
expect(foo).toBe(0);
|
|
expect(i).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(baz).toBe(3);
|
|
|
|
try {
|
|
const serenity = 4;
|
|
|
|
expect(foo).toBe(0);
|
|
expect(i).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(baz).toBe(3);
|
|
expect(serenity).toBe(4);
|
|
|
|
try {
|
|
const whf = 5;
|
|
|
|
expect(foo).toBe(0);
|
|
expect(i).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(baz).toBe(3);
|
|
expect(serenity).toBe(4);
|
|
expect(whf).toBe(5);
|
|
|
|
continue;
|
|
} finally {
|
|
const innerFinally1 = 6;
|
|
|
|
expect(() => {
|
|
whf;
|
|
}).toThrowWithMessage(ReferenceError, "'whf' is not defined");
|
|
|
|
expect(foo).toBe(0);
|
|
expect(i).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(baz).toBe(3);
|
|
expect(serenity).toBe(4);
|
|
expect(innerFinally1).toBe(6);
|
|
|
|
executionOrder.push(1);
|
|
}
|
|
|
|
expect().fail("Running code after most inner try in for loop");
|
|
} finally {
|
|
const innerFinally2 = 7;
|
|
|
|
expect(() => {
|
|
serenity;
|
|
}).toThrowWithMessage(ReferenceError, "'serenity' is not defined");
|
|
|
|
expect(() => {
|
|
whf;
|
|
}).toThrowWithMessage(ReferenceError, "'whf' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally1;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally1' is not defined");
|
|
|
|
expect(foo).toBe(0);
|
|
expect(i).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(baz).toBe(3);
|
|
expect(innerFinally2).toBe(7);
|
|
|
|
executionOrder.push(2);
|
|
}
|
|
|
|
expect().fail("Running code from after the middle try in for loop");
|
|
} finally {
|
|
const innerFinally3 = 8;
|
|
|
|
expect(() => {
|
|
baz;
|
|
}).toThrowWithMessage(ReferenceError, "'baz' is not defined");
|
|
|
|
expect(() => {
|
|
serenity;
|
|
}).toThrowWithMessage(ReferenceError, "'serenity' is not defined");
|
|
|
|
expect(() => {
|
|
whf;
|
|
}).toThrowWithMessage(ReferenceError, "'whf' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally1;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally1' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally2;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally2' is not defined");
|
|
|
|
expect(foo).toBe(0);
|
|
expect(i).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(innerFinally3).toBe(8);
|
|
|
|
executionOrder.push(3);
|
|
}
|
|
|
|
expect().fail("Running code from after the outer try in for loop");
|
|
}
|
|
|
|
executionOrder.push(6);
|
|
|
|
expect(() => {
|
|
i;
|
|
}).toThrowWithMessage(ReferenceError, "'i' is not defined");
|
|
|
|
expect(() => {
|
|
bar;
|
|
}).toThrowWithMessage(ReferenceError, "'bar' is not defined");
|
|
|
|
expect(() => {
|
|
baz;
|
|
}).toThrowWithMessage(ReferenceError, "'baz' is not defined");
|
|
|
|
expect(() => {
|
|
serenity;
|
|
}).toThrowWithMessage(ReferenceError, "'serenity' is not defined");
|
|
|
|
expect(() => {
|
|
whf;
|
|
}).toThrowWithMessage(ReferenceError, "'whf' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally1;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally1' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally2;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally2' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally3;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally3' is not defined");
|
|
|
|
expect(foo).toBe(0);
|
|
} finally {
|
|
const innerFinally4 = 9;
|
|
|
|
expect(() => {
|
|
foo;
|
|
}).toThrowWithMessage(ReferenceError, "'foo' is not defined");
|
|
|
|
expect(() => {
|
|
i;
|
|
}).toThrowWithMessage(ReferenceError, "'i' is not defined");
|
|
|
|
expect(() => {
|
|
bar;
|
|
}).toThrowWithMessage(ReferenceError, "'bar' is not defined");
|
|
|
|
expect(() => {
|
|
baz;
|
|
}).toThrowWithMessage(ReferenceError, "'baz' is not defined");
|
|
|
|
expect(() => {
|
|
serenity;
|
|
}).toThrowWithMessage(ReferenceError, "'serenity' is not defined");
|
|
|
|
expect(() => {
|
|
whf;
|
|
}).toThrowWithMessage(ReferenceError, "'whf' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally1;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally1' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally2;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally2' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally3;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally3' is not defined");
|
|
|
|
expect(innerFinally4).toBe(9);
|
|
|
|
executionOrder.push(7);
|
|
}
|
|
|
|
expect(() => {
|
|
foo;
|
|
}).toThrowWithMessage(ReferenceError, "'foo' is not defined");
|
|
|
|
expect(() => {
|
|
i;
|
|
}).toThrowWithMessage(ReferenceError, "'i' is not defined");
|
|
|
|
expect(() => {
|
|
bar;
|
|
}).toThrowWithMessage(ReferenceError, "'bar' is not defined");
|
|
|
|
expect(() => {
|
|
baz;
|
|
}).toThrowWithMessage(ReferenceError, "'baz' is not defined");
|
|
|
|
expect(() => {
|
|
serenity;
|
|
}).toThrowWithMessage(ReferenceError, "'serenity' is not defined");
|
|
|
|
expect(() => {
|
|
whf;
|
|
}).toThrowWithMessage(ReferenceError, "'whf' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally1;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally1' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally2;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally2' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally3;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally3' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally4;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally4' is not defined");
|
|
|
|
expect(executionOrder).toEqual([1, 2, 3, 4, 5, 6, 7]);
|
|
});
|
|
|
|
test("Nested try/catch/finally with labelled continue", () => {
|
|
const executionOrder = [];
|
|
|
|
function callFromUpdateBlock(j) {
|
|
expect(j).toBe(2);
|
|
executionOrder.push(5);
|
|
}
|
|
|
|
function callFromTestBlock(j) {
|
|
expect(j).toBe(2);
|
|
executionOrder.push(6);
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
const foo = 0;
|
|
|
|
expect(foo).toBe(0);
|
|
|
|
outer: for (let j = 1; j >= 2 ? callFromTestBlock(j) : true; ++j, callFromUpdateBlock(j)) {
|
|
const bar = 2;
|
|
|
|
expect(foo).toBe(0);
|
|
expect(j).toBe(1);
|
|
expect(bar).toBe(2);
|
|
|
|
try {
|
|
const baz = 3;
|
|
|
|
expect(foo).toBe(0);
|
|
expect(j).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(baz).toBe(3);
|
|
|
|
for (const i = 4; ; expect().fail("Jumped to inner for loop update block")) {
|
|
const serenity = 5;
|
|
|
|
expect(foo).toBe(0);
|
|
expect(j).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(baz).toBe(3);
|
|
expect(i).toBe(4);
|
|
expect(serenity).toBe(5);
|
|
|
|
try {
|
|
const whf = 6;
|
|
|
|
expect(foo).toBe(0);
|
|
expect(j).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(baz).toBe(3);
|
|
expect(i).toBe(4);
|
|
expect(serenity).toBe(5);
|
|
expect(whf).toBe(6);
|
|
|
|
try {
|
|
const beforeContinueTry = 7;
|
|
|
|
expect(foo).toBe(0);
|
|
expect(j).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(baz).toBe(3);
|
|
expect(i).toBe(4);
|
|
expect(serenity).toBe(5);
|
|
expect(whf).toBe(6);
|
|
expect(beforeContinueTry).toBe(7);
|
|
|
|
try {
|
|
const continueTry = 8;
|
|
|
|
expect(foo).toBe(0);
|
|
expect(j).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(baz).toBe(3);
|
|
expect(i).toBe(4);
|
|
expect(serenity).toBe(5);
|
|
expect(whf).toBe(6);
|
|
expect(beforeContinueTry).toBe(7);
|
|
expect(continueTry).toBe(8);
|
|
|
|
continue outer;
|
|
} finally {
|
|
const innerFinally1 = 9;
|
|
|
|
expect(() => {
|
|
continueTry;
|
|
}).toThrowWithMessage(
|
|
ReferenceError,
|
|
"'continueTry' is not defined"
|
|
);
|
|
|
|
expect(foo).toBe(0);
|
|
expect(j).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(baz).toBe(3);
|
|
expect(i).toBe(4);
|
|
expect(serenity).toBe(5);
|
|
expect(whf).toBe(6);
|
|
expect(beforeContinueTry).toBe(7);
|
|
expect(innerFinally1).toBe(9);
|
|
|
|
executionOrder.push(1);
|
|
}
|
|
|
|
expect().fail("Running code after most inner try");
|
|
} finally {
|
|
const innerFinally2 = 10;
|
|
|
|
expect(() => {
|
|
beforeContinueTry;
|
|
}).toThrowWithMessage(
|
|
ReferenceError,
|
|
"'beforeContinueTry' is not defined"
|
|
);
|
|
|
|
expect(() => {
|
|
continueTry;
|
|
}).toThrowWithMessage(ReferenceError, "'continueTry' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally1;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally1' is not defined");
|
|
|
|
expect(foo).toBe(0);
|
|
expect(j).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(baz).toBe(3);
|
|
expect(i).toBe(4);
|
|
expect(serenity).toBe(5);
|
|
expect(whf).toBe(6);
|
|
expect(innerFinally2).toBe(10);
|
|
|
|
executionOrder.push(2);
|
|
}
|
|
|
|
expect().fail("Running code after second to most inner try");
|
|
} finally {
|
|
const innerFinally3 = 11;
|
|
|
|
expect(() => {
|
|
whf;
|
|
}).toThrowWithMessage(ReferenceError, "'whf' is not defined");
|
|
|
|
expect(() => {
|
|
beforeContinueTry;
|
|
}).toThrowWithMessage(ReferenceError, "'beforeContinueTry' is not defined");
|
|
|
|
expect(() => {
|
|
continueTry;
|
|
}).toThrowWithMessage(ReferenceError, "'continueTry' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally1;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally1' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally2;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally2' is not defined");
|
|
|
|
expect(foo).toBe(0);
|
|
expect(j).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(baz).toBe(3);
|
|
expect(i).toBe(4);
|
|
expect(serenity).toBe(5);
|
|
expect(innerFinally3).toBe(11);
|
|
|
|
executionOrder.push(3);
|
|
}
|
|
|
|
expect().fail("Running code after third to most inner try");
|
|
}
|
|
|
|
expect().fail("Running code after inner for loop");
|
|
} finally {
|
|
const innerFinally4 = 12;
|
|
|
|
expect(() => {
|
|
baz;
|
|
}).toThrowWithMessage(ReferenceError, "'baz' is not defined");
|
|
|
|
expect(() => {
|
|
i;
|
|
}).toThrowWithMessage(ReferenceError, "'i' is not defined");
|
|
|
|
expect(() => {
|
|
serenity;
|
|
}).toThrowWithMessage(ReferenceError, "'serenity' is not defined");
|
|
|
|
expect(() => {
|
|
whf;
|
|
}).toThrowWithMessage(ReferenceError, "'whf' is not defined");
|
|
|
|
expect(() => {
|
|
beforeContinueTry;
|
|
}).toThrowWithMessage(ReferenceError, "'beforeContinueTry' is not defined");
|
|
|
|
expect(() => {
|
|
continueTry;
|
|
}).toThrowWithMessage(ReferenceError, "'continueTry' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally1;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally1' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally2;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally2' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally3;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally3' is not defined");
|
|
|
|
expect(foo).toBe(0);
|
|
expect(j).toBe(1);
|
|
expect(bar).toBe(2);
|
|
expect(innerFinally4).toBe(12);
|
|
|
|
executionOrder.push(4);
|
|
}
|
|
|
|
expect().fail("Running code after try in outer for loop");
|
|
}
|
|
|
|
expect(() => {
|
|
j;
|
|
}).toThrowWithMessage(ReferenceError, "'j' is not defined");
|
|
|
|
expect(() => {
|
|
bar;
|
|
}).toThrowWithMessage(ReferenceError, "'bar' is not defined");
|
|
|
|
expect(() => {
|
|
baz;
|
|
}).toThrowWithMessage(ReferenceError, "'baz' is not defined");
|
|
|
|
expect(() => {
|
|
i;
|
|
}).toThrowWithMessage(ReferenceError, "'i' is not defined");
|
|
|
|
expect(() => {
|
|
serenity;
|
|
}).toThrowWithMessage(ReferenceError, "'serenity' is not defined");
|
|
|
|
expect(() => {
|
|
whf;
|
|
}).toThrowWithMessage(ReferenceError, "'whf' is not defined");
|
|
|
|
expect(() => {
|
|
beforeContinueTry;
|
|
}).toThrowWithMessage(ReferenceError, "'beforeContinueTry' is not defined");
|
|
|
|
expect(() => {
|
|
continueTry;
|
|
}).toThrowWithMessage(ReferenceError, "'continueTry' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally1;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally1' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally2;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally2' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally3;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally3' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally4;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally4' is not defined");
|
|
|
|
expect(foo).toBe(0);
|
|
|
|
executionOrder.push(7);
|
|
} finally {
|
|
const innerFinally5 = 13;
|
|
|
|
expect(() => {
|
|
foo;
|
|
}).toThrowWithMessage(ReferenceError, "'foo' is not defined");
|
|
|
|
expect(() => {
|
|
j;
|
|
}).toThrowWithMessage(ReferenceError, "'j' is not defined");
|
|
|
|
expect(() => {
|
|
bar;
|
|
}).toThrowWithMessage(ReferenceError, "'bar' is not defined");
|
|
|
|
expect(() => {
|
|
baz;
|
|
}).toThrowWithMessage(ReferenceError, "'baz' is not defined");
|
|
|
|
expect(() => {
|
|
i;
|
|
}).toThrowWithMessage(ReferenceError, "'i' is not defined");
|
|
|
|
expect(() => {
|
|
serenity;
|
|
}).toThrowWithMessage(ReferenceError, "'serenity' is not defined");
|
|
|
|
expect(() => {
|
|
whf;
|
|
}).toThrowWithMessage(ReferenceError, "'whf' is not defined");
|
|
|
|
expect(() => {
|
|
beforeContinueTry;
|
|
}).toThrowWithMessage(ReferenceError, "'beforeContinueTry' is not defined");
|
|
|
|
expect(() => {
|
|
continueTry;
|
|
}).toThrowWithMessage(ReferenceError, "'continueTry' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally1;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally1' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally2;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally2' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally3;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally3' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally4;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally4' is not defined");
|
|
|
|
expect(innerFinally5).toBe(13);
|
|
|
|
executionOrder.push(8);
|
|
}
|
|
|
|
expect(() => {
|
|
foo;
|
|
}).toThrowWithMessage(ReferenceError, "'foo' is not defined");
|
|
|
|
expect(() => {
|
|
j;
|
|
}).toThrowWithMessage(ReferenceError, "'j' is not defined");
|
|
|
|
expect(() => {
|
|
bar;
|
|
}).toThrowWithMessage(ReferenceError, "'bar' is not defined");
|
|
|
|
expect(() => {
|
|
baz;
|
|
}).toThrowWithMessage(ReferenceError, "'baz' is not defined");
|
|
|
|
expect(() => {
|
|
i;
|
|
}).toThrowWithMessage(ReferenceError, "'i' is not defined");
|
|
|
|
expect(() => {
|
|
serenity;
|
|
}).toThrowWithMessage(ReferenceError, "'serenity' is not defined");
|
|
|
|
expect(() => {
|
|
whf;
|
|
}).toThrowWithMessage(ReferenceError, "'whf' is not defined");
|
|
|
|
expect(() => {
|
|
beforeContinueTry;
|
|
}).toThrowWithMessage(ReferenceError, "'beforeContinueTry' is not defined");
|
|
|
|
expect(() => {
|
|
continueTry;
|
|
}).toThrowWithMessage(ReferenceError, "'continueTry' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally1;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally1' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally2;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally2' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally3;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally3' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally4;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally4' is not defined");
|
|
|
|
expect(() => {
|
|
innerFinally5;
|
|
}).toThrowWithMessage(ReferenceError, "'innerFinally5' is not defined");
|
|
|
|
expect(executionOrder).toEqual([1, 2, 3, 4, 5, 6, 7, 8]);
|
|
});
|
|
|
|
test("labelled continue in finally overrides labelled continue in try", () => {
|
|
const executionOrder = [];
|
|
|
|
function callFromUpdateBlock(i) {
|
|
expect(i).toBe(2);
|
|
executionOrder.push(3);
|
|
}
|
|
|
|
function callFromTestBlock(i) {
|
|
expect(i).toBe(2);
|
|
executionOrder.push(4);
|
|
return false;
|
|
}
|
|
|
|
outer: for (let i = 1; i >= 2 ? callFromTestBlock(i) : true; ++i, callFromUpdateBlock(i)) {
|
|
inner: for (const j = 2; ; expect().fail("Jumped to inner for loop update block")) {
|
|
try {
|
|
executionOrder.push(1);
|
|
continue inner;
|
|
} finally {
|
|
executionOrder.push(2);
|
|
continue outer;
|
|
}
|
|
|
|
expect().fail("Running code after try block");
|
|
}
|
|
|
|
expect().fail("Running code after inner for loop");
|
|
}
|
|
|
|
expect(executionOrder).toEqual([1, 2, 3, 4]);
|
|
});
|