Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: pkg/observe/test/list_change_test.dart

Issue 132403010: big update to observe, template_binding, polymer (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/observe/pubspec.yaml ('k') | pkg/observe/test/observable_list_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 import 'package:observe/observe.dart';
7 import 'package:unittest/unittest.dart'; 7 import 'package:unittest/unittest.dart';
8 import 'observe_test_utils.dart'; 8 import 'observe_test_utils.dart';
9 9
10 // This file contains code ported from: 10 // This file contains code ported from:
11 // https://github.com/rafaelw/ChangeSummary/blob/master/tests/test.js 11 // https://github.com/rafaelw/ChangeSummary/blob/master/tests/test.js
12 12
13 main() { 13 main() => dirtyCheckZone().run(listChangeTests);
14 // TODO(jmesserly): rename this? Is summarizeListChanges coming back?
15 group('summarizeListChanges', listChangeTests);
16 }
17 14
18 // TODO(jmesserly): port or write array fuzzer tests 15 // TODO(jmesserly): port or write array fuzzer tests
19 listChangeTests() { 16 listChangeTests() {
20 StreamSubscription sub; 17 StreamSubscription sub;
21 var model; 18 var model;
22 19
23 tearDown(() { 20 tearDown(() {
24 sub.cancel(); 21 sub.cancel();
25 model = null; 22 model = null;
26 }); 23 });
27 24
28 _delta(i, r, a) => new ListChangeRecord(model, i, removed: r, addedCount: a); 25 _delta(i, r, a) => new ListChangeRecord(model, i, removed: r, addedCount: a);
29 26
30 observeTest('sequential adds', () { 27 test('sequential adds', () {
31 model = toObservable([]); 28 model = toObservable([]);
32 model.add(0); 29 model.add(0);
33 30
34 var summary; 31 var summary;
35 sub = model.listChanges.listen((r) { summary = r; }); 32 sub = model.listChanges.listen((r) { summary = r; });
36 33
37 model.add(1); 34 model.add(1);
38 model.add(2); 35 model.add(2);
39 36
40 expect(summary, null); 37 expect(summary, null);
41 performMicrotaskCheckpoint(); 38 return new Future(() => expectChanges(summary, [_delta(1, [], 2)]));
42
43 expectChanges(summary, [_delta(1, [], 2)]);
44 }); 39 });
45 40
46 observeTest('List Splice Truncate And Expand With Length', () { 41 test('List Splice Truncate And Expand With Length', () {
47 model = toObservable(['a', 'b', 'c', 'd', 'e']); 42 model = toObservable(['a', 'b', 'c', 'd', 'e']);
48 43
49 var summary; 44 var summary;
50 sub = model.listChanges.listen((r) { summary = r; }); 45 sub = model.listChanges.listen((r) { summary = r; });
51 46
52 model.length = 2; 47 model.length = 2;
53 48
54 performMicrotaskCheckpoint(); 49 return new Future(() {
55 expectChanges(summary, [_delta(2, ['c', 'd', 'e'], 0)]); 50 expectChanges(summary, [_delta(2, ['c', 'd', 'e'], 0)]);
56 summary = null; 51 summary = null;
52 model.length = 5;
57 53
58 model.length = 5; 54 }).then(newMicrotask).then((_) {
59 55
60 performMicrotaskCheckpoint(); 56 expectChanges(summary, [_delta(2, [], 3)]);
61 expectChanges(summary, [_delta(2, [], 3)]); 57 });
62 }); 58 });
63 59
64 group('List deltas can be applied', () { 60 group('List deltas can be applied', () {
65 61
66 var summary = null; 62 applyAndCheckDeltas(model, copy, changes) => changes.then((summary) {
67
68 observeArray(model) {
69 sub = model.listChanges.listen((r) { summary = r; });
70 }
71
72 applyAndCheckDeltas(model, copy) {
73 summary = null;
74 performMicrotaskCheckpoint();
75
76 // apply deltas to the copy 63 // apply deltas to the copy
77 for (var delta in summary) { 64 for (var delta in summary) {
78 copy.removeRange(delta.index, delta.index + delta.removed.length); 65 copy.removeRange(delta.index, delta.index + delta.removed.length);
79 for (int i = delta.addedCount - 1; i >= 0; i--) { 66 for (int i = delta.addedCount - 1; i >= 0; i--) {
80 copy.insert(delta.index, model[delta.index + i]); 67 copy.insert(delta.index, model[delta.index + i]);
81 } 68 }
82 } 69 }
83 70
84 // Note: compare strings for easier debugging. 71 // Note: compare strings for easier debugging.
85 expect('$copy', '$model', reason: 'summary $summary'); 72 expect('$copy', '$model', reason: 'summary $summary');
86 } 73 });
87 74
88 observeTest('Contained', () { 75 test('Contained', () {
89 var model = toObservable(['a', 'b']); 76 var model = toObservable(['a', 'b']);
90 var copy = model.toList(); 77 var copy = model.toList();
91 observeArray(model); 78 var changes = model.listChanges.first;
92 79
93 model.removeAt(1); 80 model.removeAt(1);
94 model.insertAll(0, ['c', 'd', 'e']); 81 model.insertAll(0, ['c', 'd', 'e']);
95 model.removeRange(1, 3); 82 model.removeRange(1, 3);
96 model.insert(1, 'f'); 83 model.insert(1, 'f');
97 84
98 applyAndCheckDeltas(model, copy); 85 return applyAndCheckDeltas(model, copy, changes);
99 }); 86 });
100 87
101 observeTest('Delete Empty', () { 88 test('Delete Empty', () {
102 var model = toObservable([1]); 89 var model = toObservable([1]);
103 var copy = model.toList(); 90 var copy = model.toList();
104 observeArray(model); 91 var changes = model.listChanges.first;
105 92
106 model.removeAt(0); 93 model.removeAt(0);
107 model.insertAll(0, ['a', 'b', 'c']); 94 model.insertAll(0, ['a', 'b', 'c']);
108 95
109 applyAndCheckDeltas(model, copy); 96 return applyAndCheckDeltas(model, copy, changes);
110 }); 97 });
111 98
112 observeTest('Right Non Overlap', () { 99 test('Right Non Overlap', () {
113 var model = toObservable(['a', 'b', 'c', 'd']); 100 var model = toObservable(['a', 'b', 'c', 'd']);
114 var copy = model.toList(); 101 var copy = model.toList();
115 observeArray(model); 102 var changes = model.listChanges.first;
116 103
117 model.removeRange(0, 1); 104 model.removeRange(0, 1);
118 model.insert(0, 'e'); 105 model.insert(0, 'e');
119 model.removeRange(2, 3); 106 model.removeRange(2, 3);
120 model.insertAll(2, ['f', 'g']); 107 model.insertAll(2, ['f', 'g']);
121 108
122 applyAndCheckDeltas(model, copy); 109 return applyAndCheckDeltas(model, copy, changes);
123 }); 110 });
124 111
125 observeTest('Left Non Overlap', () { 112 test('Left Non Overlap', () {
126 var model = toObservable(['a', 'b', 'c', 'd']); 113 var model = toObservable(['a', 'b', 'c', 'd']);
127 var copy = model.toList(); 114 var copy = model.toList();
128 observeArray(model); 115 var changes = model.listChanges.first;
129 116
130 model.removeRange(3, 4); 117 model.removeRange(3, 4);
131 model.insertAll(3, ['f', 'g']); 118 model.insertAll(3, ['f', 'g']);
132 model.removeRange(0, 1); 119 model.removeRange(0, 1);
133 model.insert(0, 'e'); 120 model.insert(0, 'e');
134 121
135 applyAndCheckDeltas(model, copy); 122 return applyAndCheckDeltas(model, copy, changes);
136 }); 123 });
137 124
138 observeTest('Right Adjacent', () { 125 test('Right Adjacent', () {
139 var model = toObservable(['a', 'b', 'c', 'd']); 126 var model = toObservable(['a', 'b', 'c', 'd']);
140 var copy = model.toList(); 127 var copy = model.toList();
141 observeArray(model); 128 var changes = model.listChanges.first;
142 129
143 model.removeRange(1, 2); 130 model.removeRange(1, 2);
144 model.insert(3, 'e'); 131 model.insert(3, 'e');
145 model.removeRange(2, 3); 132 model.removeRange(2, 3);
146 model.insertAll(0, ['f', 'g']); 133 model.insertAll(0, ['f', 'g']);
147 134
148 applyAndCheckDeltas(model, copy); 135 return applyAndCheckDeltas(model, copy, changes);
149 }); 136 });
150 137
151 observeTest('Left Adjacent', () { 138 test('Left Adjacent', () {
152 var model = toObservable(['a', 'b', 'c', 'd']); 139 var model = toObservable(['a', 'b', 'c', 'd']);
153 var copy = model.toList(); 140 var copy = model.toList();
154 observeArray(model); 141 var changes = model.listChanges.first;
155 142
156 model.removeRange(2, 4); 143 model.removeRange(2, 4);
157 model.insert(2, 'e'); 144 model.insert(2, 'e');
158 145
159 model.removeAt(1); 146 model.removeAt(1);
160 model.insertAll(1, ['f', 'g']); 147 model.insertAll(1, ['f', 'g']);
161 148
162 applyAndCheckDeltas(model, copy); 149 return applyAndCheckDeltas(model, copy, changes);
163 }); 150 });
164 151
165 observeTest('Right Overlap', () { 152 test('Right Overlap', () {
166 var model = toObservable(['a', 'b', 'c', 'd']); 153 var model = toObservable(['a', 'b', 'c', 'd']);
167 var copy = model.toList(); 154 var copy = model.toList();
168 observeArray(model); 155 var changes = model.listChanges.first;
169 156
170 model.removeAt(1); 157 model.removeAt(1);
171 model.insert(1, 'e'); 158 model.insert(1, 'e');
172 model.removeAt(1); 159 model.removeAt(1);
173 model.insertAll(1, ['f', 'g']); 160 model.insertAll(1, ['f', 'g']);
174 161
175 applyAndCheckDeltas(model, copy); 162 return applyAndCheckDeltas(model, copy, changes);
176 }); 163 });
177 164
178 observeTest('Left Overlap', () { 165 test('Left Overlap', () {
179 var model = toObservable(['a', 'b', 'c', 'd']); 166 var model = toObservable(['a', 'b', 'c', 'd']);
180 var copy = model.toList(); 167 var copy = model.toList();
181 observeArray(model); 168 var changes = model.listChanges.first;
182 169
183 model.removeAt(2); 170 model.removeAt(2);
184 model.insertAll(2, ['e', 'f', 'g']); 171 model.insertAll(2, ['e', 'f', 'g']);
185 // a b [e f g] d 172 // a b [e f g] d
186 model.removeRange(1, 3); 173 model.removeRange(1, 3);
187 model.insertAll(1, ['h', 'i', 'j']); 174 model.insertAll(1, ['h', 'i', 'j']);
188 // a [h i j] f g d 175 // a [h i j] f g d
189 176
190 applyAndCheckDeltas(model, copy); 177 return applyAndCheckDeltas(model, copy, changes);
191 }); 178 });
192 179
193 observeTest('Prefix And Suffix One In', () { 180 test('Prefix And Suffix One In', () {
194 var model = toObservable(['a', 'b', 'c', 'd']); 181 var model = toObservable(['a', 'b', 'c', 'd']);
195 var copy = model.toList(); 182 var copy = model.toList();
196 observeArray(model); 183 var changes = model.listChanges.first;
197 184
198 model.insert(0, 'z'); 185 model.insert(0, 'z');
199 model.add('z'); 186 model.add('z');
200 187
201 applyAndCheckDeltas(model, copy); 188 return applyAndCheckDeltas(model, copy, changes);
202 }); 189 });
203 190
204 observeTest('Remove First', () { 191 test('Remove First', () {
205 var model = toObservable([16, 15, 15]); 192 var model = toObservable([16, 15, 15]);
206 var copy = model.toList(); 193 var copy = model.toList();
207 observeArray(model); 194 var changes = model.listChanges.first;
208 195
209 model.removeAt(0); 196 model.removeAt(0);
210 197
211 applyAndCheckDeltas(model, copy); 198 return applyAndCheckDeltas(model, copy, changes);
212 }); 199 });
213 200
214 observeTest('Update Remove', () { 201 test('Update Remove', () {
215 var model = toObservable(['a', 'b', 'c', 'd']); 202 var model = toObservable(['a', 'b', 'c', 'd']);
216 var copy = model.toList(); 203 var copy = model.toList();
217 observeArray(model); 204 var changes = model.listChanges.first;
218 205
219 model.removeAt(2); 206 model.removeAt(2);
220 model.insertAll(2, ['e', 'f', 'g']); // a b [e f g] d 207 model.insertAll(2, ['e', 'f', 'g']); // a b [e f g] d
221 model[0] = 'h'; 208 model[0] = 'h';
222 model.removeAt(1); 209 model.removeAt(1);
223 210
224 applyAndCheckDeltas(model, copy); 211 return applyAndCheckDeltas(model, copy, changes);
225 }); 212 });
226 213
227 observeTest('Remove Mid List', () { 214 test('Remove Mid List', () {
228 var model = toObservable(['a', 'b', 'c', 'd']); 215 var model = toObservable(['a', 'b', 'c', 'd']);
229 var copy = model.toList(); 216 var copy = model.toList();
230 observeArray(model); 217 var changes = model.listChanges.first;
231 218
232 model.removeAt(2); 219 model.removeAt(2);
233 220
234 applyAndCheckDeltas(model, copy); 221 return applyAndCheckDeltas(model, copy, changes);
235 }); 222 });
236 }); 223 });
237 224
238 group('edit distance', () { 225 group('edit distance', () {
239 var summary = null;
240 226
241 observeArray(model) { 227 assertEditDistance(orig, changes, expectedDist) => changes.then((summary) {
242 sub = model.listChanges.listen((r) { summary = r; });
243 }
244
245 assertEditDistance(orig, expectDistance) {
246 summary = null;
247 performMicrotaskCheckpoint();
248 var actualDistance = 0; 228 var actualDistance = 0;
249 229 for (var delta in summary) {
250 if (summary != null) { 230 actualDistance += delta.addedCount + delta.removed.length;
251 for (var delta in summary) {
252 actualDistance += delta.addedCount + delta.removed.length;
253 }
254 } 231 }
255 232
256 expect(actualDistance, expectDistance); 233 expect(actualDistance, expectedDist);
257 }
258
259 observeTest('add items', () {
260 var model = toObservable([]);
261 observeArray(model);
262 model.addAll([1, 2, 3]);
263 assertEditDistance(model, 3);
264 }); 234 });
265 235
266 observeTest('trunacte and add, sharing a contiguous block', () { 236 test('add items', () {
237 var model = toObservable([]);
238 var changes = model.listChanges.first;
239 model.addAll([1, 2, 3]);
240 return assertEditDistance(model, changes, 3);
241 });
242
243 test('trunacte and add, sharing a contiguous block', () {
267 var model = toObservable(['x', 'x', 'x', 'x', '1', '2', '3']); 244 var model = toObservable(['x', 'x', 'x', 'x', '1', '2', '3']);
268 observeArray(model); 245 var changes = model.listChanges.first;
269 model.length = 0; 246 model.length = 0;
270 model.addAll(['1', '2', '3', 'y', 'y', 'y', 'y']); 247 model.addAll(['1', '2', '3', 'y', 'y', 'y', 'y']);
271 assertEditDistance(model, 8); 248 return assertEditDistance(model, changes, 8);
272 }); 249 });
273 250
274 observeTest('truncate and add, sharing a discontiguous block', () { 251 test('truncate and add, sharing a discontiguous block', () {
275 var model = toObservable(['1', '2', '3', '4', '5']); 252 var model = toObservable(['1', '2', '3', '4', '5']);
276 observeArray(model); 253 var changes = model.listChanges.first;
277 model.length = 0; 254 model.length = 0;
278 model.addAll(['a', '2', 'y', 'y', '4', '5', 'z', 'z']); 255 model.addAll(['a', '2', 'y', 'y', '4', '5', 'z', 'z']);
279 assertEditDistance(model, 7); 256 return assertEditDistance(model, changes, 7);
280 }); 257 });
281 258
282 observeTest('insert at beginning and end', () { 259 test('insert at beginning and end', () {
283 var model = toObservable([2, 3, 4]); 260 var model = toObservable([2, 3, 4]);
284 observeArray(model); 261 var changes = model.listChanges.first;
285 model.insert(0, 5); 262 model.insert(0, 5);
286 model[2] = 6; 263 model[2] = 6;
287 model.add(7); 264 model.add(7);
288 assertEditDistance(model, 4); 265 return assertEditDistance(model, changes, 4);
289 }); 266 });
290 }); 267 });
291 } 268 }
OLDNEW
« no previous file with comments | « pkg/observe/pubspec.yaml ('k') | pkg/observe/test/observable_list_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698