1 |
|
2 |
|
3 |
|
4 |
|
5 | import test from 'tape'
|
6 | import diff, {CREATE, UPDATE, MOVE, REMOVE} from '../src'
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | test('add', (t) => {
|
15 | let a = []
|
16 | let b = [{key: 'foo', val: 'bar'}]
|
17 | let c = clone(a)
|
18 | let patch = update(c)
|
19 |
|
20 | diff(a, b, patch)
|
21 |
|
22 | t.deepEqual(c, b)
|
23 |
|
24 | t.end()
|
25 | })
|
26 |
|
27 | test('add many', (t) => {
|
28 | let a = []
|
29 | let b = [{key: 'foo', val: 'bar'}, {key: 'bat', val: 'box'}]
|
30 | let c = clone(a)
|
31 | let patch = update(c)
|
32 |
|
33 | diff(a, b, patch)
|
34 |
|
35 | t.deepEqual(c, b)
|
36 |
|
37 | t.end()
|
38 | })
|
39 |
|
40 | test('add before/after', (t) => {
|
41 | let a = [{key: 'bar', val: 'two'}]
|
42 | let b = [
|
43 | {key: 'foo', val: 'one'},
|
44 | {key: 'bar', val: 'two'},
|
45 | {key: 'baz', val: 'three'}
|
46 | ]
|
47 | let c = clone(a)
|
48 | let patch = update(c)
|
49 |
|
50 | diff(a, b, patch)
|
51 |
|
52 | t.deepEqual(c, b)
|
53 |
|
54 | t.end()
|
55 | })
|
56 |
|
57 | test('add middle', (t) => {
|
58 | let a = [{key: 'foo', val: 'one'}, {key: 'baz', val: 'four'}]
|
59 | let b = [
|
60 | {key: 'foo', val: 'one'},
|
61 | {key: 'bar', val: 'five'},
|
62 | {key: 'baz', val: 'four'}
|
63 | ]
|
64 | let c = clone(a)
|
65 | let patch = update(c)
|
66 |
|
67 | diff(a, b, patch)
|
68 |
|
69 | t.deepEqual(c, b)
|
70 |
|
71 | t.end()
|
72 | })
|
73 |
|
74 | test('remove', (t) => {
|
75 | let a = [{key: 'foo', val: 'bar'}]
|
76 | let b = []
|
77 | let c = clone(a)
|
78 | let patch = update(c)
|
79 |
|
80 | diff(a, b, patch)
|
81 |
|
82 | t.deepEqual(c, b)
|
83 |
|
84 | t.end()
|
85 | })
|
86 |
|
87 | test('remove many', (t) => {
|
88 | let a = [{key: 'foo', val: 'bar'}, {key: 'bat', val: 'box'}]
|
89 | let b = []
|
90 | let c = clone(a)
|
91 | let patch = update(c)
|
92 |
|
93 | diff(a, b, patch)
|
94 |
|
95 | t.deepEqual(c, b)
|
96 |
|
97 | t.end()
|
98 | })
|
99 |
|
100 | test('remove one', (t) => {
|
101 | let a = [{key: 'bar', val: 'two'}, {key: 'foo', val: 'one'}]
|
102 | let b = [{key: 'bar', val: 'two'}]
|
103 | let c = clone(a)
|
104 | let patch = update(c)
|
105 |
|
106 | diff(a, b, patch)
|
107 |
|
108 | t.deepEqual(c, b)
|
109 |
|
110 | t.end()
|
111 | })
|
112 |
|
113 | test('remove complex', (t) => {
|
114 | let a = [{key: 'bar', val: 'one'}, {key: 'foo', val: 'two'}, {key: 'bat', val: 'three'}, {key: 'baz', val: 'four'}, {key: 'quz', val: 'five'}]
|
115 | let b = [{key: 'foo', val: 'two'}, {key: 'baz', val: 'four'}]
|
116 | let c = clone(a)
|
117 | let patch = update(c)
|
118 |
|
119 | diff(a, b, patch)
|
120 |
|
121 | t.deepEqual(c, b)
|
122 |
|
123 | t.end()
|
124 | })
|
125 |
|
126 |
|
127 | test('update', (t) => {
|
128 | let a = [{key: 'foo', val: 'bar'}]
|
129 | let b = [{key: 'foo', val: 'box'}]
|
130 | let c = clone(a)
|
131 | let patch = update(c)
|
132 |
|
133 | diff(a, b, patch)
|
134 |
|
135 | t.deepEqual(c, b)
|
136 |
|
137 | t.end()
|
138 | })
|
139 |
|
140 | test('update/remove', (t) => {
|
141 | let a = [
|
142 | {key: 'foo', val: 'one'},
|
143 | {key: 'bar', val: 'two'},
|
144 | {key: 'baz', val: 'three'}
|
145 | ]
|
146 | let b = [{key: 'foo', val: 'one'}, {key: 'baz', val: 'four'}]
|
147 | let c = clone(a)
|
148 | let patch = update(c)
|
149 |
|
150 | diff(a, b, patch)
|
151 |
|
152 | t.deepEqual(c, b)
|
153 |
|
154 | t.end()
|
155 | })
|
156 |
|
157 | test('update/remove 2', (t) => {
|
158 | let a = [
|
159 | {key: 'foo', val: 'one'},
|
160 | {key: 'bar', val: 'five'},
|
161 | {key: 'baz', val: 'four'}
|
162 | ]
|
163 | let b = [{key: 'foo', val: 'one'}, {key: 'bar', val: 'span'}]
|
164 | let c = clone(a)
|
165 | let patch = update(c)
|
166 |
|
167 | diff(a, b, patch)
|
168 |
|
169 | t.deepEqual(c, b)
|
170 |
|
171 | t.end()
|
172 | })
|
173 |
|
174 | test('update/remove 3', (t) => {
|
175 | let a = [
|
176 | {key: 'bar', val: 'span'},
|
177 | {key: 'foo', val: 'one'}
|
178 | ]
|
179 | let b = [{key: 'foo', val: 'span'}]
|
180 | let c = clone(a)
|
181 | let patch = update(c)
|
182 |
|
183 | diff(a, b, patch)
|
184 |
|
185 | t.deepEqual(c, b)
|
186 |
|
187 | t.end()
|
188 | })
|
189 |
|
190 | test('swap', (t) => {
|
191 | let a = [{key: 'foo', val: 'bar'}, {key: 'bat', val: 'box'}]
|
192 | let b = [{key: 'bat', val: 'box'}, {key: 'foo', val: 'bar'}]
|
193 | let c = clone(a)
|
194 | let patch = update(c)
|
195 |
|
196 | diff(a, b, patch)
|
197 |
|
198 | t.deepEqual(c, b)
|
199 |
|
200 | t.end()
|
201 | })
|
202 |
|
203 | test('reverse', (t) => {
|
204 | let a = [{key: 'foo', val: 'one'}, {key: 'bat', val: 'two'}, {key: 'baz', val: 'three'}, {key: 'qux', val: 'four'}]
|
205 | let b = [{key: 'qux', val: 'four'}, {key: 'baz', val: 'three'}, {key: 'bat', val: 'two'}, {key: 'foo', val: 'one'}]
|
206 | let c = clone(a)
|
207 | let patch = update(c)
|
208 |
|
209 | let log = []
|
210 |
|
211 | diff(a, b, function (...args) {
|
212 | log.push(args[0])
|
213 | patch(...args)
|
214 | })
|
215 |
|
216 | t.deepEqual(log, [MOVE, MOVE, MOVE, MOVE])
|
217 | t.deepEqual(c, b)
|
218 |
|
219 | t.end()
|
220 | })
|
221 |
|
222 | test('complex', (t) => {
|
223 | let a = [{key: 'foo', val: 'one'}, {key: 'bar', val: 'two'}, {key: 'baz', val: 'three'}]
|
224 | let b = [{key: 'bar', val: 'two'}, {key: 'foo', val: 'one'}, {key: 'bat', val: 'four'}]
|
225 | let c = clone(a)
|
226 |
|
227 | let patch = update(c)
|
228 |
|
229 | diff(a, b, patch)
|
230 |
|
231 | t.deepEqual(c, b)
|
232 |
|
233 | t.end()
|
234 | })
|
235 |
|
236 | function update(list) {
|
237 | return function(type, prev, next, pos) {
|
238 | switch(type) {
|
239 | case CREATE:
|
240 | insertAt(list, pos, next)
|
241 | break
|
242 | case REMOVE:
|
243 | remove(list, prev)
|
244 | break
|
245 | case MOVE:
|
246 | patch(list, prev, next)
|
247 | move(list, pos, prev)
|
248 | break
|
249 | case UPDATE:
|
250 | patch(list, prev, next)
|
251 | break
|
252 | }
|
253 | }
|
254 | }
|
255 |
|
256 | function insertAt (list, idx, item) {
|
257 | if (list[idx]) {
|
258 | list.splice(idx, 0, item)
|
259 | } else {
|
260 | list.push(item)
|
261 | }
|
262 | }
|
263 |
|
264 | function indexOf (list, item) {
|
265 | let i = 0
|
266 | for (; i < list.length; ++i) {
|
267 | if (list[i] === item) {
|
268 | return i
|
269 | }
|
270 | }
|
271 | return -1
|
272 | }
|
273 |
|
274 | function remove (list, item) {
|
275 | list.splice(indexOf(list, item), 1)
|
276 | }
|
277 |
|
278 | function move(list, idx, item) {
|
279 | remove(list, item)
|
280 | insertAt(list, idx, item)
|
281 | }
|
282 |
|
283 | function patch(list, pItem, nItem) {
|
284 | for (let key in pItem) {
|
285 | delete pItem[key]
|
286 | }
|
287 | for (let key in nItem) {
|
288 | pItem[key] = nItem[key]
|
289 | }
|
290 | return pItem
|
291 | }
|
292 |
|
293 | function clone (list) {
|
294 | return list.slice(0)
|
295 | }
|