Skip to content

Commit a4a53a4

Browse files
committed
Add initial preserve array logic
1 parent 33fba61 commit a4a53a4

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed

src/preseveArray.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { isObject } from './utils';
2+
3+
const getLargerArray = (l, r) => l.length > r.length ? l : r;
4+
5+
const preserve = (diff, left, right) => {
6+
7+
if (!isObject(diff)) return diff;
8+
9+
return Object.keys(diff).reduce((acc, key) => {
10+
11+
const leftArray = left[key];
12+
const rightArray = right[key];
13+
14+
if (Array.isArray(leftArray) && Array.isArray(rightArray)) {
15+
const array = [...getLargerArray(leftArray, rightArray)];
16+
return {
17+
...acc,
18+
[key]: array.reduce((acc2, item, index) => {
19+
if (diff[key].hasOwnProperty(index)) {
20+
acc2[index] = preserve(diff[key][index], leftArray[index], rightArray[index]); // diff recurse and check for nested arrays
21+
return acc2;
22+
}
23+
24+
delete acc2[index]; // no diff aka empty
25+
return acc2;
26+
}, array)
27+
};
28+
}
29+
30+
return {
31+
...acc,
32+
[key]: diff[key]
33+
};
34+
}, {});
35+
};
36+
37+
export default preserve;

src/preseveArray.test.js

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import preseveArray from './preseveArray';
2+
3+
describe('.preseveArray', () => {
4+
test('returns diff with nested objects converted back to arrays when property is deleted', () => {
5+
const left = { a: [{ b: ['#', '#', '#', { hello: '' }] }, '#', { c: '', d: ['#', ''] }, '#'] };
6+
const right = { a: [{ b: ['#', '#', '#', { hello: 'world' }] }, '#', { c: 'hello', d: ['#', 'bob'] }] };
7+
const diff = {
8+
a: {
9+
0: {
10+
b: {
11+
3: {
12+
hello: 'world'
13+
}
14+
}
15+
},
16+
2: {
17+
c: 'hello',
18+
d: {
19+
1: 'bob'
20+
}
21+
},
22+
3: undefined
23+
}
24+
};
25+
const expected = {
26+
a: [
27+
{
28+
b: [
29+
'empty',
30+
'empty',
31+
'empty',
32+
{
33+
hello: 'world'
34+
}
35+
]
36+
},
37+
'empty',
38+
{
39+
c: 'hello',
40+
d: ['empty', 'bob']
41+
},
42+
undefined
43+
]
44+
};
45+
delete expected.a[0].b[0];
46+
delete expected.a[0].b[1];
47+
delete expected.a[0].b[2];
48+
delete expected.a[1];
49+
delete expected.a[2].d[0];
50+
51+
expect(preseveArray(diff, left, right)).toEqual(expected);
52+
});
53+
54+
test('returns diff with nested objects converted back to arrays when new property is added', () => {
55+
const left = { a: [{ b: ['#', '#', '#', { hello: '' }] }, '#', { c: '', d: ['#', ''] }] };
56+
const right = { a: [{ b: ['#', '#', '#', { hello: 'world' }] }, '#', { c: 'hello', d: ['#', 'bob'] }, 'foobar'] };
57+
const diff = {
58+
a: {
59+
0: {
60+
b: {
61+
3: {
62+
hello: 'world'
63+
}
64+
}
65+
},
66+
2: {
67+
c: 'hello',
68+
d: {
69+
1: 'bob'
70+
}
71+
},
72+
3: 'foobar'
73+
}
74+
};
75+
const expected = {
76+
a: [
77+
{
78+
b: [
79+
'empty',
80+
'empty',
81+
'empty',
82+
{
83+
hello: 'world'
84+
}
85+
]
86+
},
87+
'empty',
88+
{
89+
c: 'hello',
90+
d: ['empty', 'bob']
91+
},
92+
'foobar'
93+
]
94+
};
95+
delete expected.a[0].b[0];
96+
delete expected.a[0].b[1];
97+
delete expected.a[0].b[2];
98+
delete expected.a[1];
99+
delete expected.a[2].d[0];
100+
101+
expect(preseveArray(diff, left, right)).toEqual(expected);
102+
});
103+
});

0 commit comments

Comments
 (0)