Skip to content

Commit

Permalink
Add initial preserve array logic
Browse files Browse the repository at this point in the history
  • Loading branch information
mattphillips committed Dec 29, 2017
1 parent 33fba61 commit a4a53a4
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/preseveArray.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { isObject } from './utils';

const getLargerArray = (l, r) => l.length > r.length ? l : r;

const preserve = (diff, left, right) => {

if (!isObject(diff)) return diff;

return Object.keys(diff).reduce((acc, key) => {

const leftArray = left[key];
const rightArray = right[key];

if (Array.isArray(leftArray) && Array.isArray(rightArray)) {
const array = [...getLargerArray(leftArray, rightArray)];
return {
...acc,
[key]: array.reduce((acc2, item, index) => {
if (diff[key].hasOwnProperty(index)) {
acc2[index] = preserve(diff[key][index], leftArray[index], rightArray[index]); // diff recurse and check for nested arrays
return acc2;
}

delete acc2[index]; // no diff aka empty
return acc2;
}, array)
};
}

return {
...acc,
[key]: diff[key]
};
}, {});
};

export default preserve;
103 changes: 103 additions & 0 deletions src/preseveArray.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import preseveArray from './preseveArray';

describe('.preseveArray', () => {
test('returns diff with nested objects converted back to arrays when property is deleted', () => {
const left = { a: [{ b: ['#', '#', '#', { hello: '' }] }, '#', { c: '', d: ['#', ''] }, '#'] };
const right = { a: [{ b: ['#', '#', '#', { hello: 'world' }] }, '#', { c: 'hello', d: ['#', 'bob'] }] };
const diff = {
a: {
0: {
b: {
3: {
hello: 'world'
}
}
},
2: {
c: 'hello',
d: {
1: 'bob'
}
},
3: undefined
}
};
const expected = {
a: [
{
b: [
'empty',
'empty',
'empty',
{
hello: 'world'
}
]
},
'empty',
{
c: 'hello',
d: ['empty', 'bob']
},
undefined
]
};
delete expected.a[0].b[0];
delete expected.a[0].b[1];
delete expected.a[0].b[2];
delete expected.a[1];
delete expected.a[2].d[0];

expect(preseveArray(diff, left, right)).toEqual(expected);
});

test('returns diff with nested objects converted back to arrays when new property is added', () => {
const left = { a: [{ b: ['#', '#', '#', { hello: '' }] }, '#', { c: '', d: ['#', ''] }] };
const right = { a: [{ b: ['#', '#', '#', { hello: 'world' }] }, '#', { c: 'hello', d: ['#', 'bob'] }, 'foobar'] };
const diff = {
a: {
0: {
b: {
3: {
hello: 'world'
}
}
},
2: {
c: 'hello',
d: {
1: 'bob'
}
},
3: 'foobar'
}
};
const expected = {
a: [
{
b: [
'empty',
'empty',
'empty',
{
hello: 'world'
}
]
},
'empty',
{
c: 'hello',
d: ['empty', 'bob']
},
'foobar'
]
};
delete expected.a[0].b[0];
delete expected.a[0].b[1];
delete expected.a[0].b[2];
delete expected.a[1];
delete expected.a[2].d[0];

expect(preseveArray(diff, left, right)).toEqual(expected);
});
});

0 comments on commit a4a53a4

Please sign in to comment.