ladybird/Tests/LibJS/Runtime/with-basic.js
Andreas Kling a9e54bd745 LibJS: Preserve resolved assignment bindings
Resolve dynamic identifier assignment targets before evaluating the
right hand side, then store through that saved environment record. This
matches the ECMA-262 ordering for simple assignment and var initializers
when a with binding is deleted or direct eval creates a nearer var.

Add runtime coverage for with and direct-eval cases and refresh bytecode
expectations for dynamic assignments that now snapshot the binding
before storing.
2026-05-22 01:56:57 +02:00

90 lines
2.4 KiB
JavaScript

test("basic with statement functionality", () => {
var object = { foo: 5, bar: 6, baz: 7 };
var qux = 1;
var bar = 99;
with (object) {
expect(foo).toBe(5);
expect(bar).toBe(6);
expect(baz).toBe(7);
expect(qux).toBe(1);
expect(typeof quz).toBe("undefined");
bar = 2;
}
expect(object.bar).toBe(2);
expect(() => foo).toThrowWithMessage(ReferenceError, "'foo' is not defined");
expect(bar).toBe(99);
});
test("syntax error in strict mode", () => {
expect("'use strict'; with (foo) {}").not.toEval();
});
test("restores lexical environment even when exception is thrown", () => {
var object = {
foo: 1,
get bar() {
throw Error();
},
};
try {
with (object) {
expect(foo).toBe(1);
bar;
}
expect().fail();
} catch (e) {
expect(() => foo).toThrowWithMessage(ReferenceError, "'foo' is not defined");
}
expect(() => foo).toThrowWithMessage(ReferenceError, "'foo' is not defined");
});
test("with object changes can shadow an outer binding", () => {
let outer = "outer";
let object = {};
let seen = [];
with (object) {
for (let i = 0; i < 2; ++i) {
seen.push(outer);
object.outer = "object";
}
}
expect(seen).toEqual(["outer", "object"]);
});
test("assignment keeps the resolved with binding through RHS side effects", () => {
var outer = 0;
var object = { outer: 1 };
with (object) {
outer = (delete object.outer, 2);
}
expect(object.outer).toBe(2);
expect(outer).toBe(0);
});
test("var initializer keeps the resolved with binding through initializer side effects", () => {
var object = { test262id: 1 };
with (object) {
var test262id = delete object.test262id;
}
expect(object.test262id).toBe(true);
expect(test262id).toBeUndefined();
});
test("with statement updates empty abrupt completions to undefined", () => {
expect(eval("1; do { 2; with ({}) { 3; break; } 4; } while (false);")).toBe(3);
expect(eval("5; do { 6; with ({}) { break; } 7; } while (false);")).toBeUndefined();
expect(eval("8; do { 9; with ({}) { 10; continue; } 11; } while (false);")).toBe(10);
expect(eval("12; do { 13; with ({}) { continue; } 14; } while (false);")).toBeUndefined();
});