Skip to content

Commit

Permalink
restore current logic
Browse files Browse the repository at this point in the history
  • Loading branch information
fasttime committed Nov 25, 2023
1 parent df7524a commit b20538c
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 26 deletions.
23 changes: 15 additions & 8 deletions lib/config/flat-config-schema.js
Expand Up @@ -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<string, Map<string, Object>>} [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;
}

Expand All @@ -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.
Expand All @@ -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;
}
}
}

Expand Down
38 changes: 22 additions & 16 deletions tests/lib/config/flat-config-schema.js
Expand Up @@ -20,28 +20,28 @@ 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);

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", () => {
Expand Down Expand Up @@ -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);
Expand All @@ -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", () => {
Expand All @@ -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" };

Expand Down Expand Up @@ -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" };
Expand Down Expand Up @@ -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" },
Expand Down
4 changes: 2 additions & 2 deletions tests/lib/eslint/flat-eslint.js
Expand Up @@ -6065,7 +6065,7 @@ describe("FlatESLint", () => {

await eslint.lintText("debugger;");

assert.strictEqual(resolvedSettings.sharedData, circular);
assert.deepStrictEqual(resolvedSettings.sharedData, circular);
});

it("in 'parserOptions'", async () => {
Expand Down Expand Up @@ -6093,7 +6093,7 @@ describe("FlatESLint", () => {

await eslint.lintText("debugger;");

assert.strictEqual(resolvedParserOptions.testOption, circular);
assert.deepStrictEqual(resolvedParserOptions.testOption, circular);
});
});

Expand Down

0 comments on commit b20538c

Please sign in to comment.