From b20538c7442efbf8c1fe8495c3dd11425a2747d7 Mon Sep 17 00:00:00 2001 From: Francesco Trotta Date: Sat, 25 Nov 2023 14:44:42 +0100 Subject: [PATCH] restore current logic --- lib/config/flat-config-schema.js | 23 ++++++++++------ tests/lib/config/flat-config-schema.js | 38 +++++++++++++++----------- tests/lib/eslint/flat-eslint.js | 4 +-- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/lib/config/flat-config-schema.js b/lib/config/flat-config-schema.js index 655c1054143..6e8ddef21b7 100644 --- a/lib/config/flat-config-schema.js +++ b/lib/config/flat-config-schema.js @@ -61,20 +61,23 @@ function isUndefined(value) { return typeof value === "undefined"; } +// A unique empty object to be used internally as a mapping key in `deepMerge`. +const EMPTY_OBJECT = {}; + /** * Deeply merges two objects. * @param {Object} first The base object. - * @param {Object} second The overrides object. + * @param {any} second The overrides value. * @param {Map>} [mergeMap] Maps the combination of first and second arguments to a merged result. * @returns {Object} An object with properties from both first and second. */ -function deepMerge(first, second, mergeMap = new Map()) { +function deepMerge(first, second = {}, mergeMap = new Map()) { /* - * If either argument is an array, just return the second one. We don't merge + * If the second value is an array, just return it. We don't merge * arrays because order matters and we can't know the correct order. */ - if (Array.isArray(first) || Array.isArray(second)) { + if (Array.isArray(second)) { return second; } @@ -94,7 +97,7 @@ function deepMerge(first, second, mergeMap = new Map()) { } /* - * First create a result object where properties from the second object + * First create a result object where properties from the second value * overwrite properties from the first. This sets up a baseline to use * later rather than needing to inspect and change every property * individually. @@ -117,10 +120,14 @@ function deepMerge(first, second, mergeMap = new Map()) { const firstValue = first[key]; const secondValue = second[key]; - if (isNonNullObject(firstValue) && isNonNullObject(secondValue)) { + if (isNonNullObject(firstValue)) { result[key] = deepMerge(firstValue, secondValue, mergeMap); - } else if (isUndefined(secondValue)) { - result[key] = firstValue; + } else if (isUndefined(firstValue)) { + if (isNonNullObject(secondValue)) { + result[key] = deepMerge(EMPTY_OBJECT, secondValue, mergeMap); + } else if (!isUndefined(secondValue)) { + result[key] = secondValue; + } } } diff --git a/tests/lib/config/flat-config-schema.js b/tests/lib/config/flat-config-schema.js index 3d3e463c1bb..1cde41ab16b 100644 --- a/tests/lib/config/flat-config-schema.js +++ b/tests/lib/config/flat-config-schema.js @@ -20,7 +20,7 @@ describe("merge", () => { assert.deepStrictEqual(result, { ...first, ...second }); }); - it("does not merge an object and an array", () => { + it("overrides an object with an array", () => { const first = { foo: 42 }; const second = ["bar", "baz"]; const result = merge(first, second); @@ -28,20 +28,20 @@ describe("merge", () => { assert.strictEqual(result, second); }); - it("does not merge an array with an object", () => { + it("merges an array with an object", () => { const first = ["foo", "bar"]; const second = { baz: 42 }; const result = merge(first, second); - assert.deepStrictEqual(result, second); + assert.deepStrictEqual(result, { 0: "foo", 1: "bar", baz: 42 }); }); - it("does not merge two arrays", () => { + it("overrides an array with another array", () => { const first = ["foo", "bar"]; const second = ["baz", "qux"]; const result = merge(first, second); - assert.deepStrictEqual(result, second); + assert.strictEqual(result, second); }); it("returns an emtpy object if both values are undefined", () => { @@ -74,7 +74,7 @@ describe("merge", () => { assert.deepStrictEqual(result, { foo: { bar: "baz", qux: 42 } }); }); - it("does not overwrite a value in the first object with undefined in the second one", () => { + it("does not override a value in a property with undefined", () => { const first = { foo: { bar: "baz" } }; const second = { foo: void 0 }; const result = merge(first, second); @@ -100,22 +100,28 @@ describe("merge", () => { assert.notStrictEqual(result, second); }); - it("overwrites a value in the first object with null in the second one", () => { + it("throws an error if a value in a property is overriden with null", () => { const first = { foo: { bar: "baz" } }; const second = { foo: null }; - const result = merge(first, second); - assert.deepStrictEqual(result, second); - assert.notStrictEqual(result, second); + assert.throws(() => merge(first, second), TypeError); }); - it("overwrites a value in the first object with a primitive in the second one", () => { + it("does not override a value in a property with a primitive", () => { const first = { foo: { bar: "baz" } }; const second = { foo: 42 }; const result = merge(first, second); - assert.deepStrictEqual(result, second); - assert.notStrictEqual(result, second); + assert.deepStrictEqual(result, first); + assert.notStrictEqual(result, first); + }); + + it("merges an object in a property with a string", () => { + const first = { foo: { bar: "baz" } }; + const second = { foo: "qux" }; + const result = merge(first, second); + + assert.deepStrictEqual(result, { foo: { 0: "q", 1: "u", 2: "x", bar: "baz" } }); }); it("merges objects with self-references", () => { @@ -128,7 +134,7 @@ describe("merge", () => { const result = merge(first, second); assert.strictEqual(result.first, first); - assert.strictEqual(result.second, second); + assert.deepStrictEqual(result.second, second); const expected = { foo: 42, bar: "baz" }; @@ -164,7 +170,7 @@ describe("merge", () => { const result = merge(first, second); - assert.strictEqual(result.first, first); + assert.deepStrictEqual(result.first, first); assert.strictEqual(result.second, second); const expected = { foo: 42, bar: "baz" }; @@ -208,7 +214,7 @@ describe("merge", () => { }; const result = merge(first, second); - assert.strictEqual(result.a, result.d); + assert.deepStrictEqual(result.a, result.d); const expected = { a: { foo: 42, bar: "baz" }, diff --git a/tests/lib/eslint/flat-eslint.js b/tests/lib/eslint/flat-eslint.js index b53323af0ac..263f3ab5008 100644 --- a/tests/lib/eslint/flat-eslint.js +++ b/tests/lib/eslint/flat-eslint.js @@ -6065,7 +6065,7 @@ describe("FlatESLint", () => { await eslint.lintText("debugger;"); - assert.strictEqual(resolvedSettings.sharedData, circular); + assert.deepStrictEqual(resolvedSettings.sharedData, circular); }); it("in 'parserOptions'", async () => { @@ -6093,7 +6093,7 @@ describe("FlatESLint", () => { await eslint.lintText("debugger;"); - assert.strictEqual(resolvedParserOptions.testOption, circular); + assert.deepStrictEqual(resolvedParserOptions.testOption, circular); }); });