Skip to content

Commit

Permalink
test(helper): update mergeDeep tests to more closely reflect actual…
Browse files Browse the repository at this point in the history
… usage

We only use `mergeDeep` in one scenario currently: combine the default `<Flowbite theme>` with
custom overrides provided in `<Flowbite theme={{ theme }}>`. The default theme contains all keys. We
only need to test one scenario: given one object with all the keys, and a second object with any of
those keys, use the second (overriding) object's values.
  • Loading branch information
tulup-conner committed Aug 20, 2022
1 parent 5908e0b commit 7b2d112
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 80 deletions.
105 changes: 29 additions & 76 deletions src/lib/helpers/mergeDeep.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,83 +2,36 @@ import { describe, expect, it } from 'vitest';
import { mergeDeep } from './mergeDeep';

describe.concurrent('Helper / mergeDeep (Deeply merge two objects)', () => {
describe.concurrent('given two objects', () => {
it('should combine unique shallow properties', () => {
const combineMe = {
a: 'a',
b: 'b',
c: 'c',
};
const withThis = {
d: 'd',
e: 'e',
};
it('should use the overriding value given an identical key in both inputs', () => {
const defaultTheme = {
base: 'base',
content: {
base: 'content',
},
flush: {
off: 'no-flush',
on: 'flush',
},
};
const overrides = {
content: {
base: 'new-content',
},
flush: {
off: 'new-no-flush',
on: 'new-flush',
},
};

expect(mergeDeep(combineMe, withThis)).toEqual({
a: 'a',
b: 'b',
c: 'c',
d: 'd',
e: 'e',
});
});

describe.concurrent('with identical key', () => {
it("should use overriding object's value", () => {
const combineMe = {
base: 'base',
content: {
base: 'content',
},
flush: {
off: 'no-flush',
on: 'flush',
},
};
const withThis = {
base: 'new-base',
content: {
base: 'new-content',
},
flush: {
off: 'new-no-flush',
on: 'new-flush',
},
};

expect(mergeDeep(combineMe, withThis)).toEqual({
base: 'new-base',
content: {
base: 'new-content',
},
flush: {
off: 'new-no-flush',
on: 'new-flush',
},
});
});

describe.concurrent('that is an object', () => {
it('should combine keys from both objects', () => {
const combineMe = {
content: {
base: 'base',
},
};
const withThis = {
content: {
primary: 'primary',
},
};

expect(mergeDeep(combineMe, withThis)).toEqual({
content: {
base: 'base',
primary: 'primary',
},
});
});
});
expect(mergeDeep(defaultTheme, overrides)).toEqual({
base: 'base',
content: {
base: 'new-content',
},
flush: {
off: 'new-no-flush',
on: 'new-flush',
},
});
});
});
7 changes: 3 additions & 4 deletions src/lib/helpers/mergeDeep.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// source: https://stackoverflow.com/questions/27936772/how-to-deep-merge-instead-of-shallow-merge

import { DeepPartial } from '../components';

/**
* Simple object check.
* @param item
Expand All @@ -14,10 +16,7 @@ export function isObject(item: unknown) {
* @param target
* @param ...sources
*/
export function mergeDeep(
target: Record<string, unknown>,
...sources: Record<string, unknown>[]
): Record<string, unknown> {
export function mergeDeep<T extends Record<string, unknown>>(target: T, ...sources: DeepPartial<T>[]): T {
if (!sources.length) return target;
const source = sources.shift();

Expand Down

0 comments on commit 7b2d112

Please sign in to comment.