diff --git a/Userland/Libraries/LibJS/Tests/functions/function-destructuring-parameters.js b/Userland/Libraries/LibJS/Tests/functions/function-destructuring-parameters.js new file mode 100644 index 0000000000..717c70c14f --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/functions/function-destructuring-parameters.js @@ -0,0 +1,155 @@ +describe("parsing", () => { + test("single parameter, single name", () => { + expect(`function testFunction({ a }) { }`).toEval(); + }); + + test("single parameter, single name with rest values", () => { + expect(`function testFunction({ a, ...b }) { }`).toEval(); + }); + + test("single parameter, single aliased name", () => { + expect(`function testFunction({ a: b }) { }`).toEval(); + }); + + test("single parameter, single aliased name with rest values", () => { + expect(`function testFunction({ a: b, ...c }) { }`).toEval(); + }); + + test("multiple parameters, single destructuring parameter", () => { + expect(`function testFunction(a, { b }) { }`).toEval(); + }); + + test("multiple destructuring parameters", () => { + expect(`function testFunction({ a }, { b }) { }`).toEval(); + }); + + test("multiple destructuring parameters with rest parameters", () => { + expect(`function testFunction({ a }, { bar, ...b }) { }`).toEval(); + }); + + test("multiple destructuring parameters with rest parameters 2", () => { + expect(`function testFunction({ bar, ...a }, { bar, ...b }) { }`).toEval(); + }); + + test("multiple destructuring parameters, array patterns", () => { + expect(`function testFunction({ bar, ...a }, [ b ]) { }`).toEval(); + }); + + test("multiple destructuring parameters with rest parameters, array patterns", () => { + expect(`function testFunction({ bar, ...a }, [ b, ...rest ]) { }`).toEval(); + }); + + test("multiple destructuring parameters with rest parameters, array patterns with recursive patterns", () => { + expect(`function testFunction({ bar, ...a }, [ b, [ c ] ]) { }`).toEval(); + }); + + test("multiple destructuring parameters with rest parameters, array patterns with recursive patterns 2", () => { + expect(`function testFunction({ bar, ...a }, [ b, [ c, ...{ d } ] ]) { }`).toEval(); + }); +}); + +describe("evaluating", () => { + test("single parameter, single name", () => { + function testFunction({ a }) { + return a; + } + + expect(testFunction({ a: 42 })).toBe(42); + }); + + test("single parameter, single name with rest values", () => { + function testFunction({ a, ...b }) { + return b.foo; + } + + expect(testFunction({ a: 42, foo: "yoinks" })).toBe("yoinks"); + }); + + test("single parameter, single aliased name", () => { + function testFunction({ a: b }) { + return b; + } + + expect(testFunction({ a: 42, foo: "yoinks" })).toBe(42); + }); + + test("single parameter, single aliased name with rest values", () => { + function testFunction({ a: b, ...c }) { + return b + c.foo; + } + + expect(testFunction({ a: 42, foo: "yoinks" })).toBe("42yoinks"); + }); + + test("multiple parameters, single destructuring parameter", () => { + function testFunction(a, { b }) { + return a + b; + } + + expect(testFunction("27", { b: 42 })).toBe("2742"); + }); + + test("multiple destructuring parameters", () => { + function testFunction({ a }, { b }) { + return a + b; + } + + expect(testFunction({ a: "27" }, { b: 42 })).toBe("2742"); + }); + + test("multiple destructuring parameters with rest parameters", () => { + function testFunction({ a }, { bar, ...b }) { + return bar; + } + + expect(testFunction({ a: "27" }, { b: 42 })).toBeUndefined(); + }); + + test("multiple destructuring parameters with rest parameters 2", () => { + function testFunction({ bar, ...a }, { bar, ...b }) { + return a.foo + b.foo; + } + + expect(testFunction({ foo: "27" }, { foo: 42 })).toBe("2742"); + }); + + test("multiple destructuring parameters, array patterns", () => { + function testFunction({ bar, ...a }, [b]) { + return a.foo + b; + } + + expect(testFunction({ foo: "27" }, [42])).toBe("2742"); + }); + + test("multiple destructuring parameters with rest parameters, array patterns", () => { + function testFunction({ bar, ...a }, [b, ...rest]) { + return rest.length + a.foo; + } + + expect(testFunction({ foo: "20" }, [0, 1, 2, 3, 4])).toBe("420"); + }); + + test("multiple destructuring parameters with rest parameters, array patterns with recursive patterns", () => { + function testFunction({ bar, ...a }, [b, [c]]) { + return a.foo + b + c; + } + + expect(testFunction({ foo: "20" }, [0, [1, 2, 3, 4]])).toBe("2001"); + }); + + test("multiple destructuring parameters with rest parameters, array patterns with recursive patterns 2", () => { + function testFunction({ bar, ...a }, [b, [c, ...{ length }]]) { + return a.foo + b + c + length; + } + + expect(testFunction({ foo: "20" }, [0, [1, 2, 3, 4]])).toBe("20013"); + }); + + test("patterns with default", () => { + function testFunction({ a = "27", b: bar }) { + return a + bar; + } + + expect(testFunction({ b: 42 })).toBe("2742"); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/syntax/destructuring-assignment.js b/Userland/Libraries/LibJS/Tests/syntax/destructuring-assignment.js new file mode 100644 index 0000000000..c01b420b7f --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/syntax/destructuring-assignment.js @@ -0,0 +1,207 @@ +describe("parsing", () => { + test("single name", () => { + expect(`var { a } = {};`).toEval(); + expect(`const { a } = {};`).toEval(); + expect(`let { a } = {};`).toEval(); + }); + + test("single name with rest values", () => { + expect(`var { a, ...rest } = {};`).toEval(); + expect(`const { a, ...rest } = {};`).toEval(); + expect(`let { a, ...rest } = {};`).toEval(); + }); + + test("single aliased name", () => { + expect(`var { a: b } = {};`).toEval(); + expect(`const { a: b } = {};`).toEval(); + expect(`let { a: b } = {};`).toEval(); + }); + + test("single aliased name with rest values", () => { + expect(`var { a: b, ...rest } = {};`).toEval(); + expect(`const { a: b, ...rest } = {};`).toEval(); + expect(`let { a: b, ...rest } = {};`).toEval(); + }); + + test("array destructuring patterns", () => { + expect(`var [ a ] = [];`).toEval(); + expect(`const [ a ] = [];`).toEval(); + expect(`let [ a ] = [];`).toEval(); + }); + + test("destructuring assignment with rest assignments, array patterns", () => { + expect(`var [ a, ...rest ] = [];`).toEval(); + expect(`const [ a, ...rest ] = [];`).toEval(); + expect(`let [ a, ...rest ] = [];`).toEval(); + }); + + test("destructuring assignment with rest names, array patterns with recursive patterns", () => { + expect(`var [ a, [ ...rest ] ] = [];`).toEval(); + expect(`const [ a, [ ...rest ] ] = [];`).toEval(); + expect(`let [ a, [ ...rest ] ] = [];`).toEval(); + }); + + test("destructuring assignment with rest names, array patterns with recursive patterns 2", () => { + expect(`var [ a, [ ...{length} ] ] = [];`).toEval(); + expect(`const [ a, [ ...{length} ] ] = [];`).toEval(); + expect(`let [ a, [ ...{length} ] ] = [];`).toEval(); + }); +}); + +describe("evaluating", () => { + test("single name", () => { + let o = { a: 1 }; + { + var { a } = o; + expect(a).toBe(o.a); + } + { + const { a } = o; + expect(a).toBe(o.a); + } + { + let { a } = o; + expect(a).toBe(o.a); + } + }); + + test("single name with rest values", () => { + let o = { a: 1, b: 2 }; + { + var { a, ...b } = o; + expect(a).toBe(o.a); + expect(b).toEqual({ b: 2 }); + } + { + const { a, ...b } = o; + expect(a).toBe(o.a); + expect(b).toEqual({ b: 2 }); + } + { + let { a, ...b } = o; + expect(a).toBe(o.a); + expect(b).toEqual({ b: 2 }); + } + }); + + test("single aliased name", () => { + let o = { a: 1 }; + { + var { a: x } = o; + expect(x).toBe(o.a); + } + { + const { a: x } = o; + expect(x).toBe(o.a); + } + { + let { a: x } = o; + expect(x).toBe(o.a); + } + }); + + test("single aliased name with rest values", () => { + let o = { a: 1, b: 2 }; + { + var { a: x, ...b } = o; + expect(x).toBe(o.a); + expect(b).toEqual({ b: 2 }); + } + { + const { a: x, ...b } = o; + expect(x).toBe(o.a); + expect(b).toEqual({ b: 2 }); + } + { + let { a: x, ...b } = o; + expect(x).toBe(o.a); + expect(b).toEqual({ b: 2 }); + } + }); + + test("array patterns", () => { + let o = [1, 2, 3, 4]; + { + var [a, b] = o; + expect(a).toBe(o[0]); + expect(b).toBe(o[1]); + } + { + const [a, b] = o; + expect(a).toBe(o[0]); + expect(b).toBe(o[1]); + } + { + let [a, b] = o; + expect(a).toBe(o[0]); + expect(b).toBe(o[1]); + } + }); + + test("destructuring assignment with rest names, array patterns", () => { + let o = [1, 2, 3, 4]; + { + var [a, ...b] = o; + expect(a).toBe(o[0]); + expect(b).toEqual(o.slice(1)); + } + { + const [a, ...b] = o; + expect(a).toBe(o[0]); + expect(b).toEqual(o.slice(1)); + } + { + let [a, ...b] = o; + expect(a).toBe(o[0]); + expect(b).toEqual(o.slice(1)); + } + }); + + test("destructuring assignment with rest names, array patterns with recursive patterns", () => { + let o = [1, [2, 3, 4]]; + { + var [a, [b, ...c]] = o; + expect(a).toBe(o[0]); + expect(b).toBe(o[1][0]); + expect(c).toEqual(o[1].slice(1)); + } + { + const [a, [b, ...c]] = o; + expect(a).toBe(o[0]); + expect(b).toBe(o[1][0]); + expect(c).toEqual(o[1].slice(1)); + } + { + let [a, [b, ...c]] = o; + expect(a).toBe(o[0]); + expect(b).toBe(o[1][0]); + expect(c).toEqual(o[1].slice(1)); + } + }); + + test("destructuring assignment with rest names, array patterns with recursive patterns 2", () => { + let o = [1, [2, 3, 4]]; + { + var [a, [...{ length }]] = o; + expect(a).toBe(o[0]); + expect(length).toBe(o[1].length); + } + { + const [a, [...{ length }]] = o; + expect(a).toBe(o[0]); + expect(length).toBe(o[1].length); + } + { + let [a, [...{ length }]] = o; + expect(a).toBe(o[0]); + expect(length).toBe(o[1].length); + } + }); + + test("patterns with default", () => { + let o = { a: 1 }; + let { x = "foo", a = "bar" } = o; + expect(x).toBe("foo"); + expect(a).toBe(o.a); + }); +});