Skip to content

Commit 6dbc583

Browse files
add patches merging
1 parent fd43d87 commit 6dbc583

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ Applies `patch` on `obj`.
8080

8181
Generates a `patch` Object from source and target Object.
8282

83+
84+
#### jsonmergepatch.merge (`patch1` Object, `patch2` Object) : `patch` Object
85+
86+
Generates a `patch` Object by merging patch1 and patch2.
87+
8388
## Running tests
8489

8590
```sh

lib/merge.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
module.exports = function merge(patch1, patch2) {
4+
if(patch1 === null || patch2 === null ||
5+
typeof patch1 !== 'object' || typeof patch2 !== 'object' ||
6+
Array.isArray(patch1) !== Array.isArray(patch2)) {
7+
return patch2;
8+
}
9+
var patch = JSON.parse(JSON.stringify(patch1));
10+
11+
Object.keys(patch2)
12+
.forEach(function(key) {
13+
if(patch1[key] !== undefined) {
14+
patch[key] = merge(patch1[key], patch2[key]);
15+
} else {
16+
patch[key] = patch2[key];
17+
}
18+
});
19+
return patch;
20+
};

test/lib/merge.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
'use strict';
2+
3+
var assert = require('chai').assert;
4+
5+
var merge = require('../../lib/merge');
6+
7+
describe('merge', function() {
8+
9+
it('should merge 2 patches with different attributes', function() {
10+
assert.deepEqual(
11+
merge({a: 'b'}, {b: 'c'}),
12+
{a: 'b', b: 'c'}
13+
);
14+
});
15+
16+
it('should merge take last patch attributes for rewriting', function() {
17+
assert.deepEqual(
18+
merge({a: 'b'}, {a: 'c'}),
19+
{a: 'c'}
20+
);
21+
});
22+
23+
it('should merge take last patch attributes for rewriting and keep other attributes', function() {
24+
assert.deepEqual(
25+
merge({a: 'b', b: 'd'}, {a: 'c'}),
26+
{a: 'c', b: 'd'}
27+
);
28+
});
29+
30+
it('should keep null attributes for deleting', function() {
31+
assert.deepEqual(
32+
merge({a: null}, {b: 'c'}),
33+
{a: null, b: 'c'}
34+
);
35+
});
36+
37+
it('should replace null with newer attribute', function() {
38+
assert.deepEqual(
39+
merge({a: null}, {a: 'b'}),
40+
{a: 'b'}
41+
);
42+
});
43+
44+
it('should replace an attribute with null if newer', function() {
45+
assert.deepEqual(
46+
merge({a: 'b'}, {a: null}),
47+
{a: null}
48+
);
49+
});
50+
51+
it('should replace an array with an object', function() {
52+
assert.deepEqual(
53+
merge([], {a: 'b'}),
54+
{a: 'b'}
55+
);
56+
});
57+
58+
it('should replace an object with an array', function() {
59+
assert.deepEqual(
60+
merge({a: 'b'}, []),
61+
[]
62+
);
63+
});
64+
65+
it('should merge sub objects', function() {
66+
assert.deepEqual(
67+
merge({a: {b: {c: 'd'}}, d: 'e'}, {a: {b: 'a'}}),
68+
{a: {b: 'a'}, d: 'e'}
69+
);
70+
});
71+
72+
it('should merge recursively', function() {
73+
assert.deepEqual(
74+
merge({a: {b: {c: 'd'}, d: 'e'}}, {a: {b: {c: 'e'}}}),
75+
{a: {b: {c: 'e'}, d: 'e'}}
76+
);
77+
});
78+
79+
it('should replace object with with null value', function() {
80+
assert.deepEqual(
81+
merge({a: 'b'}, null),
82+
null
83+
);
84+
});
85+
});

0 commit comments

Comments
 (0)