Skip to content

Commit

Permalink
Merge pull request #516 from alexzurbonsen/fix-mergeObjects-function
Browse files Browse the repository at this point in the history
optimize merge defaults strategy
  • Loading branch information
MariamKhalatova authored Mar 31, 2024
2 parents aeba7ca + 0360edc commit f482eb0
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 20 deletions.
3 changes: 2 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

142 changes: 140 additions & 2 deletions src/__tests__/unit/util/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ jest.mock('../../../util/logger', () => ({
error: mockError,
},
}));

import {andHandle} from '../../../util/helpers';
import {andHandle, mergeObjects} from '../../../util/helpers';
import {ERRORS} from '../../../util/errors';

const {WriteFileError} = ERRORS;
Expand Down Expand Up @@ -38,3 +37,142 @@ describe('util/helpers: ', () => {
});
});
});

describe('util/helpers: ', () => {
describe('mergeObjects(): ', () => {
it('does not override input.', () => {
expect.assertions(1);

const input = {
a: 1,
b: false,
c: 'testInput',
};

const defaults = {
c: 'testDefault',
};
const result = mergeObjects(defaults, input);

expect(result).toEqual(input);
});

it('overrides null/undefined inputs.', () => {
expect.assertions(1);

const input = {
a: 1,
b: false,
c: 'testInput',
d: null,
e: undefined,
};

const defaults = {
c: 'testDefault',
d: 'testDefault',
e: 'testDefault',
};
const result = mergeObjects(defaults, input);
const expectedResult = {
a: 1,
b: false,
c: 'testInput',
d: 'testDefault',
e: 'testDefault',
};

expect(result).toEqual(expectedResult);
});

it('adds only properties missing in input.', () => {
expect.assertions(1);

const input = {
a: 1,
b: false,
c: 'testInput',
};

const defaults = {
b: true,
c: 'testDefault',
d: 25,
};

const result = mergeObjects(defaults, input);
const expectedResult = {
a: 1,
b: false,
c: 'testInput',
d: 25,
};

expect(result).toEqual(expectedResult);
});

it('keeps values from input in case of nested objects.', () => {
expect.assertions(1);

const input = {
a: 1,
b: false,
c: 'testInput',
d: {
e: 1,
},
};

const defaults = {
b: true,
c: 'testDefault1',
d: {
e: 25,
f: 'testDefault2',
},
};

const result = mergeObjects(defaults, input);
const expectedResult = {
a: 1,
b: false,
c: 'testInput',
d: {
e: 1,
},
};

expect(result).toEqual(expectedResult);
});

it('keeps value from input in case of arrays.', () => {
expect.assertions(1);

const input = {
a: 1,
b: false,
c: 'testInput1',
d: [1, 2, 3, 4],
e: 'testInput2',
};

const defaults = {
b: true,
c: 'testDefault1',
d: [5, 6, 7, 8, 9],
e: [1, 2, 3],
};

const result = mergeObjects(defaults, input);
const expectedResult = {
a: 1,
b: false,
c: 'testInput1',
d: [1, 2, 3, 4],
e: 'testInput2',
};

expect(result).toEqual(expectedResult);
});
});
});
2 changes: 1 addition & 1 deletion src/lib/compute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const mergeDefaults = (
) => {
if (inputs) {
const response = defaults
? inputs.map(input => mergeObjects(input, defaults))
? inputs.map(input => mergeObjects(defaults, input))
: inputs;

return response;
Expand Down
29 changes: 13 additions & 16 deletions src/util/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {ERRORS} from './errors';

import {STRINGS} from '../config';
import {ERRORS} from './errors';
import {logger} from './logger';

const {ISSUE_TEMPLATE} = STRINGS;
Expand All @@ -19,22 +18,20 @@ export const andHandle = (error: Error) => {
};

/**
* Mergers two objects, omitting null values.
* Append entries from defaults which are missing from inputs.
*/
export const mergeObjects = (object1: any, object2: any) => {
const merged: Record<string, any> = {};

const keys1 = Object.keys(object1);
keys1.forEach(key1 => {
merged[key1] = object1[key1] || object2[key1];
});

const keys2 = Object.keys(object2);
keys2.forEach(key2 => {
if (!keys1.includes(key2)) {
merged[key2] = object2[key2];
export const mergeObjects = (defaults: any, input: any) => {
const merged: Record<string, any> = structuredClone(input);

for (const key in defaults) {
if (!(key in input)) {
merged[key] = defaults[key];
}
});

if (merged[key] === undefined || merged[key] === null) {
merged[key] = defaults[key];
}
}

return merged;
};

0 comments on commit f482eb0

Please sign in to comment.