ladybird/Libraries/LibJS/Tests/try-finally-continue.js

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]);
});