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

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

Issue 817483003: delete observe from the repo (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years 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/test/observable_map_test.dart ('k') | pkg/observe/test/observe_test_utils.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 import 'dart:async';
6 import 'package:logging/logging.dart';
7 import 'package:observe/observe.dart';
8 import 'package:observe/src/dirty_check.dart' as dirty_check;
9 import 'package:unittest/unittest.dart';
10 import 'observe_test_utils.dart';
11
12 main() => dirtyCheckZone().run(_tests);
13
14 void _tests() {
15 // Note: to test the basic Observable system, we use ObservableBox due to its
16 // simplicity. We also test a variant that is based on dirty-checking.
17
18 test('no observers at the start', () {
19 expect(dirty_check.allObservablesCount, 0);
20 });
21
22 group('WatcherModel', () => _observeTests((x) => new WatcherModel(x)));
23
24 group('ObservableBox', () => _observeTests((x) => new ObservableBox(x)));
25
26 group('ModelSubclass', () => _observeTests((x) => new ModelSubclass(x)));
27
28 group('dirtyCheck loops can be debugged', () {
29 var messages;
30 var subscription;
31 setUp(() {
32 messages = [];
33 subscription = Logger.root.onRecord.listen((record) {
34 messages.add(record.message);
35 });
36 });
37
38 tearDown(() {
39 subscription.cancel();
40 });
41
42 test('logs debug information', () {
43 var maxNumIterations = dirty_check.MAX_DIRTY_CHECK_CYCLES;
44
45 var x = new WatcherModel(0);
46 var sub = x.changes.listen(expectAsync((_) { x.value++; },
47 count: maxNumIterations));
48 x.value = 1;
49 Observable.dirtyCheck();
50 expect(x.value, maxNumIterations + 1);
51 expect(messages.length, 2);
52
53 expect(messages[0], contains('Possible loop'));
54 expect(messages[1], contains('index 0'));
55 expect(messages[1], contains('object: $x'));
56
57 sub.cancel();
58 });
59 });
60 }
61
62 void _observeTests(createModel(x)) {
63 final watch = createModel(null) is! ChangeNotifier;
64
65 // Track the subscriptions so we can clean them up in tearDown.
66 List subs;
67
68 int initialObservers;
69 setUp(() {
70 initialObservers = dirty_check.allObservablesCount;
71 subs = [];
72
73 if (watch) scheduleMicrotask(Observable.dirtyCheck);
74 });
75
76 tearDown(() {
77 for (var sub in subs) sub.cancel();
78 return new Future(() {
79 expect(dirty_check.allObservablesCount, initialObservers,
80 reason: 'Observable object leaked');
81 });
82 });
83
84 test('handle future result', () {
85 var callback = expectAsync((){});
86 return new Future(callback);
87 });
88
89 test('no observers', () {
90 var t = createModel(123);
91 expect(t.value, 123);
92 t.value = 42;
93 expect(t.value, 42);
94 expect(t.hasObservers, false);
95 });
96
97 test('listen adds an observer', () {
98 var t = createModel(123);
99 expect(t.hasObservers, false);
100
101 subs.add(t.changes.listen((n) {}));
102 expect(t.hasObservers, true);
103 });
104
105 test('changes delived async', () {
106 var t = createModel(123);
107 int called = 0;
108
109 subs.add(t.changes.listen(expectAsync((records) {
110 called++;
111 expectPropertyChanges(records, watch ? 1 : 2);
112 })));
113
114 t.value = 41;
115 t.value = 42;
116 expect(called, 0);
117 });
118
119 test('cause changes in handler', () {
120 var t = createModel(123);
121 int called = 0;
122
123 subs.add(t.changes.listen(expectAsync((records) {
124 called++;
125 expectPropertyChanges(records, 1);
126 if (called == 1) {
127 // Cause another change
128 t.value = 777;
129 }
130 }, count: 2)));
131
132 t.value = 42;
133 });
134
135 test('multiple observers', () {
136 var t = createModel(123);
137
138 verifyRecords(records) {
139 expectPropertyChanges(records, watch ? 1 : 2);
140 };
141
142 subs.add(t.changes.listen(expectAsync(verifyRecords)));
143 subs.add(t.changes.listen(expectAsync(verifyRecords)));
144
145 t.value = 41;
146 t.value = 42;
147 });
148
149 test('async processing model', () {
150 var t = createModel(123);
151 var records = [];
152 subs.add(t.changes.listen((r) { records.addAll(r); }));
153 t.value = 41;
154 t.value = 42;
155 expectChanges(records, [], reason: 'changes delived async');
156
157 return new Future(() {
158 expectPropertyChanges(records, watch ? 1 : 2);
159 records.clear();
160
161 t.value = 777;
162 expectChanges(records, [], reason: 'changes delived async');
163
164 }).then(newMicrotask).then((_) {
165 expectPropertyChanges(records, 1);
166
167 // Has no effect if there are no changes
168 Observable.dirtyCheck();
169 expectPropertyChanges(records, 1);
170 });
171 });
172
173 test('cancel listening', () {
174 var t = createModel(123);
175 var sub;
176 sub = t.changes.listen(expectAsync((records) {
177 expectPropertyChanges(records, 1);
178 sub.cancel();
179 t.value = 777;
180 scheduleMicrotask(Observable.dirtyCheck);
181 }));
182 t.value = 42;
183 });
184
185 test('cancel and reobserve', () {
186 var t = createModel(123);
187 var sub;
188 sub = t.changes.listen(expectAsync((records) {
189 expectPropertyChanges(records, 1);
190 sub.cancel();
191
192 scheduleMicrotask(expectAsync(() {
193 subs.add(t.changes.listen(expectAsync((records) {
194 expectPropertyChanges(records, 1);
195 })));
196 t.value = 777;
197 scheduleMicrotask(Observable.dirtyCheck);
198 }));
199 }));
200 t.value = 42;
201 });
202
203 test('cannot modify changes list', () {
204 var t = createModel(123);
205 var records = null;
206 subs.add(t.changes.listen((r) { records = r; }));
207 t.value = 42;
208
209 return new Future(() {
210 expectPropertyChanges(records, 1);
211
212 // Verify that mutation operations on the list fail:
213
214 expect(() {
215 records[0] = new PropertyChangeRecord(t, #value, 0, 1);
216 }, throwsUnsupportedError);
217
218 expect(() { records.clear(); }, throwsUnsupportedError);
219
220 expect(() { records.length = 0; }, throwsUnsupportedError);
221 });
222 });
223
224 test('notifyChange', () {
225 var t = createModel(123);
226 var records = [];
227 subs.add(t.changes.listen((r) { records.addAll(r); }));
228 t.notifyChange(new PropertyChangeRecord(t, #value, 123, 42));
229
230 return new Future(() {
231 expectPropertyChanges(records, 1);
232 expect(t.value, 123, reason: 'value did not actually change.');
233 });
234 });
235
236 test('notifyPropertyChange', () {
237 var t = createModel(123);
238 var records = null;
239 subs.add(t.changes.listen((r) { records = r; }));
240 expect(t.notifyPropertyChange(#value, t.value, 42), 42,
241 reason: 'notifyPropertyChange returns newValue');
242
243 return new Future(() {
244 expectPropertyChanges(records, 1);
245 expect(t.value, 123, reason: 'value did not actually change.');
246 });
247 });
248 }
249
250 expectPropertyChanges(records, int number) {
251 expect(records.length, number, reason: 'expected $number change records');
252 for (var record in records) {
253 expect(record is PropertyChangeRecord, true, reason:
254 'record should be PropertyChangeRecord');
255 expect((record as PropertyChangeRecord).name, #value, reason:
256 'record should indicate a change to the "value" property');
257 }
258 }
259
260 // A test model based on dirty checking.
261 class WatcherModel<T> extends Observable {
262 @observable T value;
263
264 WatcherModel([T initialValue]) : value = initialValue;
265
266 String toString() => '#<$runtimeType value: $value>';
267 }
268
269 class ModelSubclass<T> extends WatcherModel<T> {
270 ModelSubclass([T initialValue]) : super(initialValue);
271 }
OLDNEW
« no previous file with comments | « pkg/observe/test/observable_map_test.dart ('k') | pkg/observe/test/observe_test_utils.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698