UNPKG

6.5 kBJavaScriptView Raw
1var expect = require('chai').expect
2 , diff = require('..');
3
4describe('changeset', function () {
5 beforeEach(function (done) {
6 done();
7 });
8
9 it('should be able to diff two objects and return a changeset',
10 function (done) {
11 var a = {
12 name: 'Eugene',
13 number: 42,
14 tags: ['tag1', 'tag2', 'tag3'],
15 scores: {
16 tetris: 1000,
17 carmageddon: 3,
18 someArray: ['one', 'two', 'three']
19 }
20 };
21
22 a.self = a;
23 a.scoresAgain = a.scores;
24
25 var b = {
26 name: 'Susan',
27 number: 43,
28 tags: ['tag1', 'tag4'],
29 scores: {
30 carmageddon: 3,
31 zelda: 3000,
32 someArray: ['one', 'three']
33 },
34 age: 37
35 };
36
37 b.friend = a;
38 b.self = b;
39
40 var changes = diff(a, b);
41
42 expect(changes).to.deep.equal([
43 { type: 'put', key: ['name'], value: 'Susan' },
44 { type: 'put', key: ['number'], value: 43 },
45 { type: 'put', key: ['tags', '1'], value: 'tag4' },
46 { type: 'del', key: ['tags', '2'] },
47 { type: 'put', key: [ 'scores', 'someArray', '1' ], value: 'three' },
48 { type: 'del', key: [ 'scores', 'someArray', '2' ] },
49 { type: 'del', key: ['scores', 'tetris'] },
50 { type: 'put', key: ['scores', 'zelda'], value: 3000 },
51 { type: 'put', key: ['self'], value: b },
52 { type: 'del', key: ['scoresAgain'], },
53 { type: 'put', key: ['age'], value: 37 },
54 { type: 'put', key: ['friend'], value: a }
55 ]);
56
57 done();
58 });
59
60 it('should be able to handle basic types', function (done) {
61 var a = 'Eugene';
62 var b = 'Susan';
63
64 var changes = diff(a, b);
65 expect(changes).to.deep.equal([
66 { type: 'put', key: [], value: 'Susan' }
67 ]);
68
69 done();
70 });
71
72 it('should be able to handle nulls', function (done) {
73 var changes;
74
75 changes = diff(null, 'Susan');
76 expect(changes).to.deep.equal([
77 { type: 'put', key: [], value: 'Susan' }
78 ]);
79
80 changes = diff('Eugene', null);
81 expect(changes).to.deep.equal([
82 { type: 'put', key: [], value: null }
83 ]);
84
85 done();
86 });
87
88 it('should be able to handle undefined', function (done) {
89 var changes;
90
91 changes = diff(undefined, 'Susan');
92 expect(changes).to.deep.equal([
93 { type: 'put', key: [], value: 'Susan' }
94 ]);
95
96 changes = diff('Eugene', undefined);
97 expect(changes).to.deep.equal([
98 { type: 'del', key: [] }
99 ]);
100
101 done();
102 });
103
104 it('should be able to apply a changeset to an object', function (done) {
105 var a = {
106 name: 'Eugene',
107 number: 42,
108 tags: ['tag1', 'tag2', 'tag3'],
109 scores: {
110 tetris: 1000,
111 carmageddon: 3,
112 someArray: ['one', 'two', 'three']
113 }
114 };
115
116 a.self = a;
117 a.scoresAgain = a.scores;
118
119 var b = {
120 name: 'Susan',
121 number: 43,
122 tags: ['tag1', 'tag4'],
123 scores: {
124 carmageddon: 3,
125 zelda: 3000,
126 someArray: ['one', 'three']
127 },
128 age: 37
129 };
130
131 b.friend = a;
132 b.self = b;
133
134 var clone = require("udc");
135 var bClone = clone(b);
136
137 var changes = diff(a, b);
138 var b_ = diff.apply(changes, a);
139 expect(b_.scores.someArray.length).to.equal(b.scores.someArray.length);
140 expect(b_).to.deep.equals(b);
141 expect(b).to.deep.equals(bClone); // Target did not change.
142 done();
143 });
144
145 it('should be able to apply a changeset to a value', function (done) {
146 var a = 'Eugene';
147 var b = 'Susan';
148
149 var changes = diff(a, b);
150 var b_ = diff.apply(changes, a);
151 expect(b_).to.deep.equals(b);
152 done();
153 });
154
155 it('should be able to apply a changeset with nulls', function (done) {
156 var changes, b_;
157
158 changes = diff(null, 'Susan');
159 b_ = diff.apply(changes, null);
160 expect(b_).to.deep.equals('Susan');
161
162 changes = diff('Eugene', null);
163 b_ = diff.apply(changes, 'Eugene');
164 expect(b_).to.deep.equals(null);
165
166 done();
167 });
168
169 it('should be able to apply a changeset with undefined', function (done) {
170 var changes, b_;
171
172 changes = diff(undefined, 'Susan');
173 b_ = diff.apply(changes, undefined);
174 expect(b_).to.deep.equals('Susan');
175
176 changes = diff('Eugene', undefined);
177 b_ = diff.apply(changes, 'Eugene');
178 expect(b_).to.deep.equals(null);
179
180 done();
181 });
182
183 it('should be able to apply a changeset to an object and modify it',
184 function (done) {
185 var a = {
186 name: 'Eugene',
187 number: 42,
188 tags: ['tag1', 'tag2', 'tag3'],
189 scores: {
190 tetris: 1000,
191 carmageddon: 3,
192 someArray: ['one', 'two', 'three']
193 }
194 };
195
196 a.self = a;
197 a.scoresAgain = a.scores;
198
199 var b = {
200 name: 'Susan',
201 number: 43,
202 tags: ['tag1', 'tag4'],
203 scores: {
204 carmageddon: 3,
205 zelda: 3000,
206 someArray: ['one', 'three']
207 },
208 age: 37
209 };
210
211 b.friend = a;
212 b.self = b;
213
214 var changes = diff(a, b);
215 var b_ = diff.apply(changes, a, true);
216 expect(b_.scores.someArray.length).to.equal(b.scores.someArray.length);
217 expect(b_).to.deep.equals(b);
218 expect(b_).to.equal(a);
219 done();
220 });
221
222 it('should be able to self-modify and replace an entire object',
223 function(done) {
224 var data = { name: 'Eugene', number: 43 };
225 var change = [ { type: 'put', key: [], value: 'xxx' } ];
226 var obj = diff.apply(change, data, true);
227 expect(obj).to.equal('xxx');
228 done();
229 });
230
231 it('should be able to deal with incrementally built arrays', function(done) {
232 var obj = [];
233 var changeset = [
234 { type: 'put', key: [], value: [] },
235 { type: 'put', key: [ 0, 'make' ], value: 'Toyota' },
236 { type: 'put', key: [ 0, 'model' ], value: 'Camry' },
237 { type: 'put', key: [ 1, 'make' ], value: 'Toyota' },
238 { type: 'put', key: [ 1, 'model' ], value: 'Corolla' } ];
239 obj = diff.apply(changeset, obj, true);
240 expect(obj).to.deep.equals([
241 { make: 'Toyota', model: 'Camry' },
242 { make: 'Toyota', model: 'Corolla' }
243 ]);
244 done();
245 });
246
247 it('should not allow prototype pollution', function(done) {
248 var changeset = [
249 { type: 'put', key: ['__proto__','polluted'], value: 'Yes! Its Polluted'}
250 ];
251 diff.apply(changeset, {}, true);
252 expect({}.polluted).to.not.equal('Yes! Its Polluted');
253 done();
254 })
255});