Skip to content

Commit 397c1df

Browse files
committed
Add updatededDiff function to find only changed difference in lhs/ rhs
1 parent 7ef796d commit 397c1df

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

src/updated/index.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { isEmpty, isObject } from '../utils';
2+
3+
const updatedDiff = (lhs, rhs) => {
4+
5+
if (lhs === rhs) return {};
6+
7+
if (!isObject(lhs) || !isObject(rhs)) return rhs;
8+
9+
return Object.keys(rhs).reduce((acc, key) => {
10+
11+
if (lhs.hasOwnProperty(key)) {
12+
const difference = updatedDiff(lhs[key], rhs[key]);
13+
14+
if (isObject(difference) && isEmpty(difference)) return acc;
15+
16+
return { ...acc, [key]: difference };
17+
}
18+
19+
return acc;
20+
}, {});
21+
};
22+
23+
export default updatedDiff;

src/updated/index.spec.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { expect } from 'chai';
2+
import forEach from 'mocha-each';
3+
4+
import updatedDiff from './';
5+
6+
describe('.updatedDiff', () => {
7+
8+
describe('base case', () => {
9+
describe('equal', () => {
10+
forEach([
11+
['int', 1],
12+
['string', 'a'],
13+
['boolean', true],
14+
['null', null],
15+
['undefined', undefined],
16+
['object', { a: 1 }],
17+
['array', [1]],
18+
['function', () => ({})],
19+
]).it('returns empty object when given values of type %s are equal', (type, value) => {
20+
expect(updatedDiff(value, value)).to.deep.equal({});
21+
});
22+
});
23+
24+
describe('not equal and not object', () => {
25+
forEach([
26+
[1, 2],
27+
['a', 'b'],
28+
[true, false],
29+
['hello', null],
30+
['hello', undefined],
31+
[null, undefined],
32+
[undefined, null],
33+
[null, { a: 1 }],
34+
['872983', { areaCode: '+44', number: '872983' }],
35+
[100, () => ({})],
36+
[() => ({}), 100],
37+
]).it('returns right hand side value when different to left hand side value (%s, %s)', (lhs, rhs) => {
38+
expect(updatedDiff(lhs, rhs)).to.deep.equal(rhs);
39+
});
40+
});
41+
});
42+
43+
describe('recursive case', () => {
44+
describe('object', () => {
45+
it('returns right hand side value when given objects are different at root', () => {
46+
expect(updatedDiff({ a: 1 }, { a: 2 })).to.deep.equal({ a: 2 });
47+
});
48+
49+
it('returns right hand side value when right hand side value is null', () => {
50+
expect(updatedDiff({ a: 1 }, { a: null })).to.deep.equal({ a: null });
51+
});
52+
53+
it('returns subset of right hand side value when sibling objects differ', () => {
54+
expect(updatedDiff({ a: { b: 1 }, c: 2 }, { a: { b: 1 }, c: 3 })).to.deep.equal({ c: 3 });
55+
});
56+
57+
it('returns subset of right hand side value when nested values differ', () => {
58+
expect(updatedDiff({ a: { b: 1, c: 2} }, { a: { b: 1, c: 3 } })).to.deep.equal({ a: { c: 3 } });
59+
});
60+
61+
it('returns subset of right hand side value when nested values differ at multiple paths', () => {
62+
expect(updatedDiff({ a: { b: 1 }, c: 2, d: { e: 100 } }, { a: { b: 99 }, c: 3, d: { e: 100 } })).to.deep.equal({ a: { b: 99 }, c: 3 });
63+
});
64+
65+
it('returns empty object when deleted from right hand side', () => {
66+
expect(updatedDiff({ a: 1, b: { c: 2 }}, { a: 1 })).to.deep.equal({});
67+
});
68+
69+
it('returns empty object when a key value has been added', () => {
70+
expect(updatedDiff({ a: 1 }, { a: 1, b: 2 })).to.deep.equal({});
71+
});
72+
});
73+
74+
describe('arrays', () => {
75+
it('returns right hand side value as object of indices to value when arrays are different', () => {
76+
expect(updatedDiff([1], [2])).to.deep.equal({ 0: 2 });
77+
});
78+
79+
it('returns subset of right hand side array as object of indices to value when arrays differs at multiple indicies', () => {
80+
expect(updatedDiff([1, 2, 3], [9, 8, 3])).to.deep.equal({ 0: 9, 1: 8 });
81+
});
82+
83+
it('returns subset of right hand side array as object of indices to value when right hand side array has deletions', () => {
84+
expect(updatedDiff([1, 2, 3], [1, 3])).to.deep.equal({ 1: 3 });
85+
});
86+
87+
it('returns empty object when right hand side array has additions', () => {
88+
expect(updatedDiff([1, 2, 3], [1, 2, 3, 9])).to.deep.equal({});
89+
});
90+
});
91+
});
92+
});

0 commit comments

Comments
 (0)