Skip to content

Commit dea80f2

Browse files
author
Phillip Clark
committed
fix #17, fix #19, close #21
1 parent 2b04b39 commit dea80f2

8 files changed

+632
-494
lines changed

Readme.md

+27-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111

1212
## ChangeLog
1313

14+
`0.2.0` - [Fixes Bug #17](https://github.com/flitbit/diff/issues/17), [Fixes Bug #19](https://github.com/flitbit/diff/issues/19), [Enhancement #21](https://github.com/flitbit/diff/issues/21) Applying changes that are properly structured can now be applied as a change (no longer requires typeof Diff) - supports differences being applied after round-trip serialization to JSON format. Prefilter now reports the path of all changes - it was not showing a path for arrays and anything in the structure below (reported by @ravishvt).
15+
16+
*Breaking Change* – The structure of change records for differences below an array element has changed. Array indexes are now reported as numeric elements in the `path` if the changes is merely edited (an `E` kind). Changes of kind `A` (array) are only reported for changes in the terminal array itself and will have a nested `N` (new) item or a nested `D` (deleted) item.
17+
1418
`0.1.7` - [Enhancement #11](https://github.com/flitbit/diff/issues/11) Added the ability to filter properties that should not be analyzed while calculating differences. Makes `deep-diff` more usable with frameworks that attach housekeeping properties to existing objects. AngularJS does this, and the new filter ability should ease working with it.
1519

1620
`0.1.6` - Changed objects within nested arrays can now be applied. They were previously recording the changes appropriately but `applyDiff` would error. Comparison of `NaN` works more sanely - comparison to number shows difference, comparison to another `Nan` does not.
@@ -55,7 +59,7 @@ var deep = require('deep-diff')
5559

5660
**browser**
5761
```html
58-
<script src="deep-diff-0.1.3.min.js"></script>
62+
<script src="deep-diff-0.2.0.min.js"></script>
5963
```
6064
> Minified, browser release of the current version of the module is under the `releases` folder.
6165
> In a browser, `deep-diff` defines a global variable `DeepDiff`. If there is a conflict in the global namesapce you can restore the conflicting definition and assign `deep-diff` to another variable like this: `var deep = DeepDiff.noConflict();`.
@@ -89,8 +93,9 @@ var rhs = {
8993

9094
var differences = diff(lhs, rhs);
9195
```
92-
The code snippet above would result in the following structure describing the differences:
96+
*up to v 0.1.7* The code snippet above would result in the following structure describing the differences:
9397
``` javascript
98+
// Versions < 0.2.0
9499
[ { kind: 'E',
95100
path: [ 'name' ],
96101
lhs: 'my object',
@@ -109,6 +114,26 @@ The code snippet above would result in the following structure describing the di
109114
item: { kind: 'N', rhs: { than: 'before' } } } ]
110115
```
111116

117+
*v 0.2.0 and above* The code snippet above would result in the following structure describing the differences:
118+
``` javascript
119+
[ { kind: 'E',
120+
path: [ 'name' ],
121+
lhs: 'my object',
122+
rhs: 'updated object' },
123+
{ kind: 'E',
124+
path: [ 'details', 'with', 2 ],
125+
lhs: 'elements',
126+
rhs: 'more' },
127+
{ kind: 'A',
128+
path: [ 'details', 'with' ],
129+
index: 3,
130+
item: { kind: 'N', rhs: 'elements' } },
131+
{ kind: 'A',
132+
path: [ 'details', 'with' ],
133+
index: 4,
134+
item: { kind: 'N', rhs: { than: 'before' } } } ]
135+
```
136+
112137
### Differences
113138

114139
Differences are reported as one or more change records. Change records have the following structure:

bower.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "deep-diff",
33
"main": "index.js",
4-
"version": "0.1.6",
4+
"version": "0.2.0",
55
"homepage": "https://github.com/flitbit/diff",
66
"authors": [
77
"Phillip Clark <[email protected]>"

examples/apply-diff-from-any.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*jshint indent:2, laxcomma:true, laxbreak:true*/
2+
var util = require('util')
3+
, diff = require('..')
4+
, data = require('./practice-data')
5+
;
6+
7+
var cycle = -1
8+
, i
9+
, len = data.length
10+
, prior = {}
11+
, comparand
12+
, records
13+
, ch
14+
;
15+
16+
var applyEachChange = function (ch) {
17+
diff.applyChange(prior, comparand, ch);
18+
};
19+
20+
while (++cycle < 10) {
21+
i = -1;
22+
while (++i < len) {
23+
24+
comparand = data[i];
25+
26+
27+
// get the difference...
28+
records = diff(prior, comparand);
29+
30+
// round-trip serialize to prune the underlying types...
31+
var serialized = JSON.stringify(records);
32+
var desierialized = JSON.parse(serialized);
33+
34+
if (desierialized) {
35+
desierialized.forEach(applyEachChange);
36+
37+
prior = comparand;
38+
}
39+
}
40+
}

examples/array-change.js

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*jshint indent:2, laxcomma:true, laxbreak:true*/
2+
var util = require('util')
3+
, expect = require('expect.js')
4+
, eql = require('deep-equal')
5+
, deep = require('..')
6+
;
7+
8+
var lhs = {
9+
"id": "Release",
10+
"phases": [{
11+
"id": "Phase1",
12+
"tasks": [
13+
{"id": "Task1"},
14+
{"id": "Task2"}
15+
]
16+
}, {
17+
"id": "Phase2",
18+
"tasks": [
19+
{"id": "Task3"}
20+
]
21+
}]
22+
};
23+
var rhs = {
24+
"id": "Release",
25+
"phases": [{
26+
// E: Phase1 -> Phase2
27+
"id": "Phase2",
28+
"tasks": [
29+
{"id": "Task3"}
30+
]
31+
}, {
32+
"id": "Phase1",
33+
"tasks": [
34+
{"id": "Task1"},
35+
{"id": "Task2"}
36+
]
37+
}]
38+
};
39+
40+
var diff = deep.diff(lhs, rhs);
41+
42+
// there should be differences
43+
expect(diff).to.be.ok();
44+
expect(diff.length).to.be(6);
45+
46+
47+
// It.phases[0].id changed from 'Phase1' to 'Phase2'
48+
//
49+
expect(diff[0].kind).to.be('E');
50+
expect(diff[0].path).to.be.an('array');
51+
expect(diff[0].path).to.have.length(3);
52+
expect(diff[0].path[0]).to.be('phases');
53+
expect(diff[0].path[1]).to.be(0);
54+
expect(diff[0].path[2]).to.be('id');
55+
expect(diff[0].lhs).to.be('Phase1');
56+
expect(diff[0].rhs).to.be('Phase2');
57+
58+
// It.phases[0].tasks[0].id changed from 'Task1' to 'Task3'
59+
//
60+
expect(diff[1].kind).to.be('E');
61+
expect(diff[1].path).to.be.an('array');
62+
expect(diff[1].path).to.have.length(5);
63+
expect(diff[1].path[0]).to.be('phases');
64+
expect(diff[1].path[1]).to.be(0);
65+
expect(diff[1].path[2]).to.be('tasks');
66+
expect(diff[1].path[3]).to.be(0);
67+
expect(diff[1].path[4]).to.be('id');
68+
expect(diff[1].lhs).to.be('Task1');
69+
expect(diff[1].rhs).to.be('Task3');
70+
71+
// It.phases[0].tasks[1] was deleted
72+
//
73+
expect(diff[2].kind).to.be('A');
74+
expect(diff[2].path).to.be.an('array');
75+
expect(diff[2].path).to.have.length(3);
76+
expect(diff[2].path[0]).to.be('phases');
77+
expect(diff[2].path[1]).to.be(0);
78+
expect(diff[2].path[2]).to.be('tasks');
79+
expect(diff[2].index).to.be(1);
80+
expect(diff[2].item.kind).to.be('D');
81+
82+
// It.phases[1].id changed from 'Phase2' to 'Phase1'
83+
//
84+
expect(diff[3].kind).to.be('E');
85+
expect(diff[3].path).to.be.an('array');
86+
expect(diff[3].path).to.have.length(3);
87+
expect(diff[3].path[0]).to.be('phases');
88+
expect(diff[3].path[1]).to.be(1);
89+
expect(diff[3].path[2]).to.be('id');
90+
expect(diff[3].lhs).to.be('Phase2');
91+
expect(diff[3].rhs).to.be('Phase1');
92+
93+
// It.phases[1].tasks[0].id changed from 'Task3' to 'Task1'
94+
//
95+
expect(diff[4].kind).to.be('E');
96+
expect(diff[4].path).to.be.an('array');
97+
expect(diff[4].path).to.have.length(5);
98+
expect(diff[4].path[0]).to.be('phases');
99+
expect(diff[4].path[1]).to.be(1);
100+
expect(diff[4].path[2]).to.be('tasks');
101+
expect(diff[4].path[3]).to.be(0);
102+
expect(diff[4].path[4]).to.be('id');
103+
expect(diff[4].lhs).to.be('Task3');
104+
expect(diff[4].rhs).to.be('Task1');
105+
106+
// It.phases[1].tasks[1] is new
107+
//
108+
expect(diff[5].kind).to.be('A');
109+
expect(diff[5].path).to.be.an('array');
110+
expect(diff[5].path).to.have.length(3);
111+
expect(diff[5].path[0]).to.be('phases');
112+
expect(diff[5].path[1]).to.be(1);
113+
expect(diff[5].path[2]).to.be('tasks');
114+
expect(diff[5].index).to.be(1);
115+
expect(diff[5].item.kind).to.be('N');
116+
117+
var applied = deep.applyDiff(lhs, rhs);

examples/example1.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ deep.observableDiff(lhs, rhs, function (d) {
3232
if (d.path.length !== 1 || d.path.join('.') !== 'name') {
3333
deep.applyChange(lhs, rhs, d);
3434
}
35-
});
35+
}, function (path, key) {
36+
var p = (path && path.length) ? path.join('/') : '<no-path>'
37+
util.log('prefilter: path = ' + p + ' key = ' + key);
38+
}
39+
);
3640

3741
console.log(util.inspect(lhs, false, 99));

0 commit comments

Comments
 (0)