-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathapply-diff.test.js
325 lines (294 loc) · 10.7 KB
/
apply-diff.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
import { describe, test, expect } from 'vitest'
import { diff } from 'deep-object-diff'
import { applyDiff } from '../src/apply-diff.js'
describe('base case', () => {
describe('equal', () => {
test.each([
['int', 1],
['string', 'a'],
['boolean', true],
['null', null],
['undefined', undefined],
['object', { a: 1 }],
['array', [1]],
// ['function', () => ({})], // See 'equal Function' test below
['date', new Date()],
['date with milliseconds', new Date('2017-01-01T00:00:00.637Z')],
])('returns empty object when given values of type %s are equal to %s', (type, value) => {
const d = diff(value, value)
expect(d).toEqual({})
const newValue = structuredClone(value) // does not work for Function
const restoredRHS = applyDiff(newValue, d)
expect(restoredRHS).to.deep.equal(value)
})
test('equal Function', () => {
const value = () => ({})
const d = diff(value, value)
expect(d).toEqual({})
const restoredRHS = applyDiff(value, d)
expect(restoredRHS).to.deep.equal(value)
})
})
describe('not equal and not object', () => {
test.each([
[1, 2],
['a', 'b'],
[true, false],
['hello', null],
['hello', undefined],
[null, undefined],
[undefined, null],
[null, { a: 1 }],
['872983', { areaCode: '+44', number: '872983' }],
[100, () => ({})],
[() => ({}), 100],
[new Date('2017-01-01'), new Date('2017-01-02')],
[new Date('2017-01-01T00:00:00.636Z'), new Date('2017-01-01T00:00:00.637Z')],
])('returns right hand side value when different to left hand side value (%s, %s)', (lhs, rhs) => {
const d = diff(lhs, rhs)
expect(d).toEqual(rhs)
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
})
})
describe('recursive case', () => {
describe('object', () => {
test('return right hand side empty object value when left hand side has been updated', () => {
const lhs = { a: 1 }
const rhs = { a: {} }
const d = diff(lhs, rhs)
expect(d).toEqual(rhs)
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns right hand side value when given objects are different', () => {
const lhs = { a: 1 }
const rhs = { a: 2 }
const d = diff(lhs, rhs)
expect(d).toEqual(rhs)
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns right hand side value when right hand side value is null', () => {
const lhs = { a: 1 }
const rhs = { a: null }
const d = diff(lhs, rhs)
expect(d).toEqual(rhs)
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns subset of right hand side value when sibling objects differ', () => {
const lhs = { a: { b: 1 }, c: 2 }
const rhs = { a: { b: 1 }, c: 3 }
const d = diff(lhs, rhs)
expect(d).toEqual({ c: 3 })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns subset of right hand side value when nested values differ', () => {
const lhs = { a: { b: 1, c: 2 } }
const rhs = { a: { b: 1, c: 3 } }
const d = diff(lhs, rhs)
expect(d).toEqual({ a: { c: 3 } })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns subset of right hand side value when nested values differ at multiple paths', () => {
const lhs = { a: { b: 1 }, c: 2, d: { e: 100 } }
const rhs = { a: { b: 99 }, c: 3, d: { e: 100 } }
const d = diff(lhs, rhs)
expect(d).toEqual({ a: { b: 99 }, c: 3 })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns subset of right hand side value when a key value has been deleted', () => {
const lhs = { a: { b: 1 }, c: 2, d: { e: 100 } }
const rhs = { a: { b: 1 }, c: 2, d: {} }
const d = diff(lhs, rhs)
expect(d).toEqual({ d: { e: undefined } })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns subset of right hand side value when a key value has been added', () => {
const lhs = { a: 1 }
const rhs = { a: 1, b: 2 }
const d = diff(lhs, rhs)
expect(d).toEqual({ b: 2 })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns keys as undefined when deleted from right hand side', () => {
const lhs = { a: 1, b: { c: 2 } }
const rhs = { a: 1 }
const d = diff(lhs, rhs)
expect(d).toEqual({ b: undefined })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
})
describe('arrays', () => {
test('return right hand side empty object value when left hand side has been updated', () => {
const lhs = [{ a: 1 }]
const rhs = [{ a: {} }]
const d = diff(lhs, rhs)
expect(d).toEqual({ 0: { a: {} } })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns right hand side value as object of indices to value when arrays are different', () => {
const lhs = [1]
const rhs = [2]
const d = diff(lhs, rhs)
expect(d).toEqual({ 0: 2 })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns subset of right hand side array as object of indices to value when arrays differs at multiple indicies', () => {
const lhs = [1, 2, 3]
const rhs = [9, 8, 3]
const d = diff(lhs, rhs)
expect(d).toEqual({ 0: 9, 1: 8 })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns subset of right hand side array as object of indices to value when right hand side array has deletions', () => {
const lhs = [1, 2, 3]
const rhs = [1, 3]
const d = diff(lhs, rhs)
expect(d).toEqual({ 1: 3, 2: undefined })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns subset of right hand side array as object of indices to value when right hand side array has additions', () => {
const lhs = [1, 2, 3]
const rhs = [1, 2, 3, 9]
const d = diff(lhs, rhs)
expect(d).toEqual({ 3: 9 })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
})
describe('date', () => {
const lhsDate = new Date('2016')
const rhsDate = new Date('2017')
test('returns empty object when dates are equal', () => {
const lhs = new Date('2016')
const rhs = new Date('2016')
const d = diff(lhs, rhs)
expect(d).toEqual({})
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns right hand side date when updated', () => {
let lhs = { date: lhsDate }
let rhs = { date: rhsDate }
const d = diff(lhs, rhs)
expect(d).toEqual({ date: rhsDate })
let restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
lhs = [lhsDate]
rhs = [rhsDate]
const d2 = diff(lhs, rhs)
expect(d2).toEqual({ 0: rhsDate })
restoredRHS = applyDiff(lhs, d2)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns undefined when date deleted', () => {
let lhs = { date: lhsDate }
let rhs = {}
const d = diff(lhs, rhs)
expect(d).toEqual({ date: undefined })
let restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
lhs = [lhsDate]
rhs = []
const d2 = diff(lhs, rhs)
expect(d2).toEqual({ 0: undefined })
restoredRHS = applyDiff(lhs, d2)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns right hand side when date is added', () => {
let lhs = {}
let rhs = { date: rhsDate }
const d = diff(lhs, rhs)
expect(d).toEqual({ date: rhsDate })
let restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
lhs = []
rhs = [rhsDate]
const d2 = diff(lhs, rhs)
expect(d2).toEqual({ 0: rhsDate })
restoredRHS = applyDiff(lhs, d2)
expect(restoredRHS).to.deep.equal(rhs)
})
})
describe('object create null', () => {
test('returns right hand side value when given objects are different', () => {
const lhs = Object.create(null)
lhs.a = 1
const rhs = Object.create(null)
rhs.a = 2
const d = diff(lhs, rhs)
expect(d).toEqual({ a: 2 })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns subset of right hand side value when sibling objects differ', () => {
const lhs = Object.create(null)
lhs.a = { b: 1 }
lhs.c = 2
const rhs = Object.create(null)
rhs.a = { b: 1 }
rhs.c = 3
const d = diff(lhs, rhs)
expect(d).toEqual({ c: 3 })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns subset of right hand side value when nested values differ', () => {
const lhs = Object.create(null)
lhs.a = { b: 1, c: 2 }
const rhs = Object.create(null)
rhs.a = { b: 1, c: 3 }
const d = diff(lhs, rhs)
expect(d).toEqual({ a: { c: 3 } })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns subset of right hand side value when nested values differ at multiple paths', () => {
const lhs = Object.create(null)
lhs.a = { b: 1 }
lhs.c = 2
const rhs = Object.create(null)
rhs.a = { b: 99 }
rhs.c = 3
const d = diff(lhs, rhs)
expect(d).toEqual({ a: { b: 99 }, c: 3 })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns subset of right hand side value when a key value has been deleted', () => {
const lhs = Object.create(null)
lhs.a = { b: 1 }
lhs.c = 2
const rhs = Object.create(null)
rhs.a = { b: 1 }
const d = diff(lhs, rhs)
expect(d).toEqual({ c: undefined })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
test('returns subset of right hand side value when a key value has been added', () => {
const lhs = Object.create(null)
lhs.a = 1
const rhs = Object.create(null)
rhs.a = 1
rhs.b = 2
const d = diff(lhs, rhs)
expect(d).toEqual({ b: 2 })
const restoredRHS = applyDiff(lhs, d)
expect(restoredRHS).to.deep.equal(rhs)
})
})
})