2020-11-28 12:19:28 -03:00
|
|
|
test("basic with statement functionality", () => {
|
2020-12-26 12:24:24 -03:00
|
|
|
var object = { foo: 5, bar: 6, baz: 7 };
|
2020-11-28 12:19:28 -03:00
|
|
|
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);
|
2021-09-08 15:46:11 -03:00
|
|
|
expect(() => foo).toThrowWithMessage(ReferenceError, "'foo' is not defined");
|
2020-11-28 12:19:28 -03:00
|
|
|
|
|
|
|
|
expect(bar).toBe(99);
|
|
|
|
|
});
|
2020-11-28 16:17:33 -03:00
|
|
|
|
|
|
|
|
test("syntax error in strict mode", () => {
|
|
|
|
|
expect("'use strict'; with (foo) {}").not.toEval();
|
|
|
|
|
});
|
2021-09-08 15:46:11 -03:00
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
});
|
2026-05-19 06:22:33 -03:00
|
|
|
|
|
|
|
|
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"]);
|
|
|
|
|
});
|
2026-05-21 09:04:39 -03:00
|
|
|
|
2026-05-21 12:41:47 -03:00
|
|
|
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();
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-21 09:04:39 -03:00
|
|
|
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();
|
|
|
|
|
});
|