OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'package:observe/observe.dart'; | 6 |
7 import 'package:unittest/unittest.dart'; | 7 import 'package:observable/observable.dart'; |
8 import 'observe_test_utils.dart'; | 8 import 'package:test/test.dart'; |
| 9 |
| 10 import 'observable_test_utils.dart'; |
9 | 11 |
10 // This file contains code ported from: | 12 // This file contains code ported from: |
11 // https://github.com/rafaelw/ChangeSummary/blob/master/tests/test.js | 13 // https://github.com/rafaelw/ChangeSummary/blob/master/tests/test.js |
12 | 14 |
13 main() => dirtyCheckZone().run(listChangeTests); | 15 main() => listChangeTests(); |
14 | 16 |
15 // TODO(jmesserly): port or write array fuzzer tests | 17 // TODO(jmesserly): port or write array fuzzer tests |
16 listChangeTests() { | 18 listChangeTests() { |
17 StreamSubscription sub; | 19 StreamSubscription sub; |
18 var model; | 20 var model; |
19 | 21 |
20 tearDown(() { | 22 tearDown(() { |
21 sub.cancel(); | 23 sub.cancel(); |
22 model = null; | 24 model = null; |
23 }); | 25 }); |
24 | 26 |
25 _delta(i, r, a) => new ListChangeRecord(model, i, removed: r, addedCount: a); | 27 _delta(i, r, a) => new ListChangeRecord(model, i, removed: r, addedCount: a); |
26 | 28 |
27 test('sequential adds', () { | 29 test('sequential adds', () { |
28 model = toObservable([]); | 30 model = toObservable([]); |
29 model.add(0); | 31 model.add(0); |
30 | 32 |
31 var summary; | 33 var summary; |
32 sub = model.listChanges.listen((r) { summary = r; }); | 34 sub = model.listChanges.listen((r) => summary = r); |
33 | 35 |
34 model.add(1); | 36 model.add(1); |
35 model.add(2); | 37 model.add(2); |
36 | 38 |
37 expect(summary, null); | 39 expect(summary, null); |
38 return new Future(() => expectChanges(summary, [_delta(1, [], 2)])); | 40 return new Future(() => expectChanges(summary, [_delta(1, [], 2)])); |
39 }); | 41 }); |
40 | 42 |
41 test('List Splice Truncate And Expand With Length', () { | 43 test('List Splice Truncate And Expand With Length', () { |
42 model = toObservable(['a', 'b', 'c', 'd', 'e']); | 44 model = toObservable(['a', 'b', 'c', 'd', 'e']); |
43 | 45 |
44 var summary; | 46 var summary; |
45 sub = model.listChanges.listen((r) { summary = r; }); | 47 sub = model.listChanges.listen((r) => summary = r); |
46 | 48 |
47 model.length = 2; | 49 model.length = 2; |
48 | 50 |
49 return new Future(() { | 51 return new Future(() { |
50 expectChanges(summary, [_delta(2, ['c', 'd', 'e'], 0)]); | 52 expectChanges(summary, [ |
| 53 _delta(2, ['c', 'd', 'e'], 0) |
| 54 ]); |
51 summary = null; | 55 summary = null; |
52 model.length = 5; | 56 model.length = 5; |
53 | |
54 }).then(newMicrotask).then((_) { | 57 }).then(newMicrotask).then((_) { |
55 | |
56 expectChanges(summary, [_delta(2, [], 3)]); | 58 expectChanges(summary, [_delta(2, [], 3)]); |
57 }); | 59 }); |
58 }); | 60 }); |
59 | 61 |
60 group('List deltas can be applied', () { | 62 group('List deltas can be applied', () { |
| 63 applyAndCheckDeltas(model, copy, changes) => changes.then((summary) { |
| 64 // apply deltas to the copy |
| 65 for (var delta in summary) { |
| 66 copy.removeRange(delta.index, delta.index + delta.removed.length); |
| 67 for (int i = delta.addedCount - 1; i >= 0; i--) { |
| 68 copy.insert(delta.index, model[delta.index + i]); |
| 69 } |
| 70 } |
61 | 71 |
62 applyAndCheckDeltas(model, copy, changes) => changes.then((summary) { | 72 // Note: compare strings for easier debugging. |
63 // apply deltas to the copy | 73 expect('$copy', '$model', reason: 'summary $summary'); |
64 for (var delta in summary) { | 74 }); |
65 copy.removeRange(delta.index, delta.index + delta.removed.length); | |
66 for (int i = delta.addedCount - 1; i >= 0; i--) { | |
67 copy.insert(delta.index, model[delta.index + i]); | |
68 } | |
69 } | |
70 | |
71 // Note: compare strings for easier debugging. | |
72 expect('$copy', '$model', reason: 'summary $summary'); | |
73 }); | |
74 | 75 |
75 test('Contained', () { | 76 test('Contained', () { |
76 var model = toObservable(['a', 'b']); | 77 var model = toObservable(['a', 'b']); |
77 var copy = model.toList(); | 78 var copy = model.toList(); |
78 var changes = model.listChanges.first; | 79 var changes = model.listChanges.first; |
79 | 80 |
80 model.removeAt(1); | 81 model.removeAt(1); |
81 model.insertAll(0, ['c', 'd', 'e']); | 82 model.insertAll(0, ['c', 'd', 'e']); |
82 model.removeRange(1, 3); | 83 model.removeRange(1, 3); |
83 model.insert(1, 'f'); | 84 model.insert(1, 'f'); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 | 198 |
198 return applyAndCheckDeltas(model, copy, changes); | 199 return applyAndCheckDeltas(model, copy, changes); |
199 }); | 200 }); |
200 | 201 |
201 test('Update Remove', () { | 202 test('Update Remove', () { |
202 var model = toObservable(['a', 'b', 'c', 'd']); | 203 var model = toObservable(['a', 'b', 'c', 'd']); |
203 var copy = model.toList(); | 204 var copy = model.toList(); |
204 var changes = model.listChanges.first; | 205 var changes = model.listChanges.first; |
205 | 206 |
206 model.removeAt(2); | 207 model.removeAt(2); |
207 model.insertAll(2, ['e', 'f', 'g']); // a b [e f g] d | 208 model.insertAll(2, ['e', 'f', 'g']); // a b [e f g] d |
208 model[0] = 'h'; | 209 model[0] = 'h'; |
209 model.removeAt(1); | 210 model.removeAt(1); |
210 | 211 |
211 return applyAndCheckDeltas(model, copy, changes); | 212 return applyAndCheckDeltas(model, copy, changes); |
212 }); | 213 }); |
213 | 214 |
214 test('Remove Mid List', () { | 215 test('Remove Mid List', () { |
215 var model = toObservable(['a', 'b', 'c', 'd']); | 216 var model = toObservable(['a', 'b', 'c', 'd']); |
216 var copy = model.toList(); | 217 var copy = model.toList(); |
217 var changes = model.listChanges.first; | 218 var changes = model.listChanges.first; |
218 | 219 |
219 model.removeAt(2); | 220 model.removeAt(2); |
220 | 221 |
221 return applyAndCheckDeltas(model, copy, changes); | 222 return applyAndCheckDeltas(model, copy, changes); |
222 }); | 223 }); |
223 }); | 224 }); |
224 | 225 |
225 group('edit distance', () { | 226 group('edit distance', () { |
| 227 assertEditDistance(orig, changes, expectedDist) => changes.then((summary) { |
| 228 var actualDistance = 0; |
| 229 for (var delta in summary) { |
| 230 actualDistance += delta.addedCount + delta.removed.length; |
| 231 } |
226 | 232 |
227 assertEditDistance(orig, changes, expectedDist) => changes.then((summary) { | 233 expect(actualDistance, expectedDist); |
228 var actualDistance = 0; | 234 }); |
229 for (var delta in summary) { | |
230 actualDistance += delta.addedCount + delta.removed.length; | |
231 } | |
232 | |
233 expect(actualDistance, expectedDist); | |
234 }); | |
235 | 235 |
236 test('add items', () { | 236 test('add items', () { |
237 var model = toObservable([]); | 237 var model = toObservable([]); |
238 var changes = model.listChanges.first; | 238 var changes = model.listChanges.first; |
239 model.addAll([1, 2, 3]); | 239 model.addAll([1, 2, 3]); |
240 return assertEditDistance(model, changes, 3); | 240 return assertEditDistance(model, changes, 3); |
241 }); | 241 }); |
242 | 242 |
243 test('trunacte and add, sharing a contiguous block', () { | 243 test('trunacte and add, sharing a contiguous block', () { |
244 var model = toObservable(['x', 'x', 'x', 'x', '1', '2', '3']); | 244 var model = toObservable(['x', 'x', 'x', 'x', '1', '2', '3']); |
(...skipping 14 matching lines...) Expand all Loading... |
259 test('insert at beginning and end', () { | 259 test('insert at beginning and end', () { |
260 var model = toObservable([2, 3, 4]); | 260 var model = toObservable([2, 3, 4]); |
261 var changes = model.listChanges.first; | 261 var changes = model.listChanges.first; |
262 model.insert(0, 5); | 262 model.insert(0, 5); |
263 model[2] = 6; | 263 model[2] = 6; |
264 model.add(7); | 264 model.add(7); |
265 return assertEditDistance(model, changes, 4); | 265 return assertEditDistance(model, changes, 4); |
266 }); | 266 }); |
267 }); | 267 }); |
268 } | 268 } |
OLD | NEW |