diff --git a/src/__tests__/mergeDeep-test.js b/src/__tests__/mergeDeep-test.js new file mode 100644 index 0000000..09e86c3 --- /dev/null +++ b/src/__tests__/mergeDeep-test.js @@ -0,0 +1,82 @@ +import { Map } from 'immutable'; +import mergeDeep from '../mergeDeep'; + +describe('transmute/mergeDeep', () => { + describe('Object', () => { + it('merges with an Object', () => { + expect( + mergeDeep( + { + one: 3, + three: { + a: 0, + b: 1, + }, + }, + { + one: 1, + two: 2, + three: { + a: 1, + }, + } + ) + ).toMatchSnapshot(); + }); + + it('merges with a Map', () => { + expect( + mergeDeep( + Map({ + one: 3, + three: { + a: 1, + }, + }), + { + one: 1, + two: 2, + three: { + a: 0, + b: 1, + }, + } + ) + ).toMatchSnapshot(); + }); + }); + + describe('Iterable', () => { + const merger = mergeDeep({ one: 3, three: 1 }); + + it('merges with an Object', () => { + expect( + merger( + Map({ + one: 1, + two: 2, + three: { + a: 0, + b: 1, + }, + }) + ) + ).toMatchSnapshot(); + }); + + it('merges with a Map', () => { + expect( + merger( + Map({ + one: 1, + two: 2, + three: { + a: 0, + b: 1, + }, + }) + ) + ).toMatchSnapshot(); + }); + }); +}); diff --git a/src/mergeDeep.js b/src/mergeDeep.js new file mode 100644 index 0000000..c9f4428 --- /dev/null +++ b/src/mergeDeep.js @@ -0,0 +1,36 @@ +import _reduce from './internal/_reduce'; +import _set from './internal/_set'; +import curry from './curry'; +import isObject from './isObject'; +import isRecord from './isRecord'; +import isArray from './isArray'; + +function mergeDeep(updates, subject) { + console.log({ updates, subject }); + return _reduce( + subject, + (acc, value, key) => { + if (isObject(value) || isRecord(value)) { + return _set(key, mergeDeep(value, subject[key]), acc); + } + return _set(key, value, acc); + }, + updates + ); +} + +/** + * Takes each entry of `updates` and sets it on `subject`. + * + * @example + * // returns Map { "one" => 3, "two" => 2, "three" => { a: 1, b: 1}} + * merge( + * Map({one: 1, two: 2, three: { a: 1 }}), + * Map({one: 3, three: { a: 0, b: 1}}) + * ); + * + * @param {Iterable} updates key-value pairs to merge in `subject`. + * @param {Iterable} subject the thing to update. + * @return {Iterable} with each key-value of `updates` merged into `subject`. + */ +export default curry(mergeDeep);