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

Side by Side Diff: packages/quiver/test/testing/async/fake_async_test.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 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
OLDNEW
(Empty)
1 // Copyright 2014 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 library quiver.testing.async.fake_async_test;
16
17 import 'dart:async';
18
19 import 'package:quiver/testing/async.dart';
20 import 'package:test/test.dart';
21
22 main() {
23 group('FakeAsync', () {
24 var initialTime = new DateTime(2000);
25 var elapseBy = const Duration(days: 1);
26
27 test('should set initial time', () {
28 expect(new FakeAsync().getClock(initialTime).now(), initialTime);
29 });
30
31 group('elapseBlocking', () {
32 test('should elapse time without calling timers', () {
33 var timerCalled = false;
34 var timer = new Timer(elapseBy ~/ 2, () => timerCalled = true);
35 new FakeAsync().elapseBlocking(elapseBy);
36 expect(timerCalled, isFalse);
37 timer.cancel();
38 });
39
40 test('should elapse time by the specified amount', () {
41 var it = new FakeAsync();
42 it.elapseBlocking(elapseBy);
43 expect(it.getClock(initialTime).now(), initialTime.add(elapseBy));
44 });
45
46 test('should throw when called with a negative duration', () {
47 expect(() {
48 new FakeAsync().elapseBlocking(const Duration(days: -1));
49 }, throwsA(new isInstanceOf<ArgumentError>()));
50 });
51 });
52
53 group('elapse', () {
54 test('should elapse time by the specified amount', () {
55 new FakeAsync().run((async) {
56 async.elapse(elapseBy);
57 expect(async.getClock(initialTime).now(), initialTime.add(elapseBy));
58 });
59 });
60
61 test('should throw ArgumentError when called with a negative duration',
62 () {
63 expect(() => new FakeAsync().elapse(const Duration(days: -1)),
64 throwsA(new isInstanceOf<ArgumentError>()));
65 });
66
67 test('should throw when called before previous call is complete', () {
68 new FakeAsync().run((async) {
69 var error;
70 new Timer(elapseBy ~/ 2, () {
71 try {
72 async.elapse(elapseBy);
73 } catch (e) {
74 error = e;
75 }
76 });
77 async.elapse(elapseBy);
78 expect(error, new isInstanceOf<StateError>());
79 });
80 });
81
82 group('when creating timers', () {
83 test('should call timers expiring before or at end time', () {
84 new FakeAsync().run((async) {
85 var beforeCallCount = 0;
86 var atCallCount = 0;
87 new Timer(elapseBy ~/ 2, () {
88 beforeCallCount++;
89 });
90 new Timer(elapseBy, () {
91 atCallCount++;
92 });
93 async.elapse(elapseBy);
94 expect(beforeCallCount, 1);
95 expect(atCallCount, 1);
96 });
97 });
98
99 test('should call timers expiring due to elapseBlocking', () {
100 new FakeAsync().run((async) {
101 bool secondaryCalled = false;
102 new Timer(elapseBy, () {
103 async.elapseBlocking(elapseBy);
104 });
105 new Timer(elapseBy * 2, () {
106 secondaryCalled = true;
107 });
108 async.elapse(elapseBy);
109 expect(secondaryCalled, isTrue);
110 expect(async.getClock(initialTime).now(),
111 initialTime.add(elapseBy * 2));
112 });
113 });
114
115 test('should call timers at their scheduled time', () {
116 new FakeAsync().run((async) {
117 DateTime calledAt;
118 var periodicCalledAt = <DateTime>[];
119 new Timer(elapseBy ~/ 2, () {
120 calledAt = async.getClock(initialTime).now();
121 });
122 new Timer.periodic(elapseBy ~/ 2, (_) {
123 periodicCalledAt.add(async.getClock(initialTime).now());
124 });
125 async.elapse(elapseBy);
126 expect(calledAt, initialTime.add(elapseBy ~/ 2));
127 expect(periodicCalledAt,
128 [elapseBy ~/ 2, elapseBy].map(initialTime.add));
129 });
130 });
131
132 test('should not call timers expiring after end time', () {
133 new FakeAsync().run((async) {
134 var timerCallCount = 0;
135 new Timer(elapseBy * 2, () {
136 timerCallCount++;
137 });
138 async.elapse(elapseBy);
139 expect(timerCallCount, 0);
140 });
141 });
142
143 test('should not call canceled timers', () {
144 new FakeAsync().run((async) {
145 int timerCallCount = 0;
146 var timer = new Timer(elapseBy ~/ 2, () {
147 timerCallCount++;
148 });
149 timer.cancel();
150 async.elapse(elapseBy);
151 expect(timerCallCount, 0);
152 });
153 });
154
155 test('should call periodic timers each time the duration elapses', () {
156 new FakeAsync().run((async) {
157 var periodicCallCount = 0;
158 new Timer.periodic(elapseBy ~/ 10, (_) {
159 periodicCallCount++;
160 });
161 async.elapse(elapseBy);
162 expect(periodicCallCount, 10);
163 });
164 });
165
166 test('should process microtasks surrounding each timer', () {
167 new FakeAsync().run((async) {
168 var microtaskCalls = 0;
169 var timerCalls = 0;
170 scheduleMicrotasks() {
171 for (int i = 0; i < 5; i++) {
172 scheduleMicrotask(() => microtaskCalls++);
173 }
174 }
175 scheduleMicrotasks();
176 new Timer.periodic(elapseBy ~/ 5, (_) {
177 timerCalls++;
178 expect(microtaskCalls, 5 * timerCalls);
179 scheduleMicrotasks();
180 });
181 async.elapse(elapseBy);
182 expect(timerCalls, 5);
183 expect(microtaskCalls, 5 * (timerCalls + 1));
184 });
185 });
186
187 test('should pass the periodic timer itself to callbacks', () {
188 new FakeAsync().run((async) {
189 Timer passedTimer;
190 Timer periodic = new Timer.periodic(elapseBy, (timer) {
191 passedTimer = timer;
192 });
193 async.elapse(elapseBy);
194 expect(periodic, same(passedTimer));
195 });
196 });
197
198 test('should call microtasks before advancing time', () {
199 new FakeAsync().run((async) {
200 DateTime calledAt;
201 scheduleMicrotask(() {
202 calledAt = async.getClock(initialTime).now();
203 });
204 async.elapse(const Duration(minutes: 1));
205 expect(calledAt, initialTime);
206 });
207 });
208
209 test('should add event before advancing time', () {
210 return new Future(() => new FakeAsync().run((async) {
211 var controller = new StreamController();
212 var ret = controller.stream.first.then((_) {
213 expect(async.getClock(initialTime).now(), initialTime);
214 });
215 controller.add(null);
216 async.elapse(const Duration(minutes: 1));
217 return ret;
218 }));
219 });
220
221 test('should increase negative duration timers to zero duration', () {
222 new FakeAsync().run((async) {
223 var negativeDuration = const Duration(days: -1);
224 DateTime calledAt;
225 new Timer(negativeDuration, () {
226 calledAt = async.getClock(initialTime).now();
227 });
228 async.elapse(const Duration(minutes: 1));
229 expect(calledAt, initialTime);
230 });
231 });
232
233 test('should not be additive with elapseBlocking', () {
234 new FakeAsync().run((async) {
235 new Timer(Duration.ZERO, () => async.elapseBlocking(elapseBy * 5));
236 async.elapse(elapseBy);
237 expect(async.getClock(initialTime).now(),
238 initialTime.add(elapseBy * 5));
239 });
240 });
241
242 group('isActive', () {
243 test('should be false after timer is run', () {
244 new FakeAsync().run((async) {
245 var timer = new Timer(elapseBy ~/ 2, () {});
246 async.elapse(elapseBy);
247 expect(timer.isActive, isFalse);
248 });
249 });
250
251 test('should be true after periodic timer is run', () {
252 new FakeAsync().run((async) {
253 var timer = new Timer.periodic(elapseBy ~/ 2, (_) {});
254 async.elapse(elapseBy);
255 expect(timer.isActive, isTrue);
256 });
257 });
258
259 test('should be false after timer is canceled', () {
260 new FakeAsync().run((async) {
261 var timer = new Timer(elapseBy ~/ 2, () {});
262 timer.cancel();
263 expect(timer.isActive, isFalse);
264 });
265 });
266 });
267
268 test('should work with new Future()', () {
269 new FakeAsync().run((async) {
270 var callCount = 0;
271 new Future(() => callCount++);
272 async.elapse(Duration.ZERO);
273 expect(callCount, 1);
274 });
275 });
276
277 test('should work with Future.delayed', () {
278 new FakeAsync().run((async) {
279 int result;
280 new Future.delayed(elapseBy, () => result = 5);
281 async.elapse(elapseBy);
282 expect(result, 5);
283 });
284 });
285
286 test('should work with Future.timeout', () {
287 new FakeAsync().run((async) {
288 var completer = new Completer();
289 var timed = completer.future.timeout(elapseBy ~/ 2);
290 expect(timed, throwsA(new isInstanceOf<TimeoutException>()));
291 async.elapse(elapseBy);
292 completer.complete();
293 });
294 });
295
296 // TODO: Pausing and resuming the timeout Stream doesn't work since
297 // it uses `new Stopwatch()`.
298 //
299 // See https://code.google.com/p/dart/issues/detail?id=18149
300 test('should work with Stream.periodic', () {
301 new FakeAsync().run((async) {
302 var events = <int>[];
303 StreamSubscription subscription;
304 var periodic =
305 new Stream.periodic(const Duration(minutes: 1), (i) => i);
306 subscription = periodic.listen(events.add, cancelOnError: true);
307 async.elapse(const Duration(minutes: 3));
308 subscription.cancel();
309 expect(events, [0, 1, 2]);
310 });
311 });
312
313 test('should work with Stream.timeout', () {
314 new FakeAsync().run((async) {
315 var events = <int>[];
316 var errors = [];
317 var controller = new StreamController();
318 var timed = controller.stream.timeout(const Duration(minutes: 2));
319 var subscription = timed.listen(events.add,
320 onError: errors.add, cancelOnError: true);
321 controller.add(0);
322 async.elapse(const Duration(minutes: 1));
323 expect(events, [0]);
324 async.elapse(const Duration(minutes: 1));
325 subscription.cancel();
326 expect(errors, hasLength(1));
327 expect(errors.first, new isInstanceOf<TimeoutException>());
328 return controller.close();
329 });
330 });
331 });
332 });
333
334 group('flushMicrotasks', () {
335 test('should flush a microtask', () {
336 new FakeAsync().run((async) {
337 bool microtaskRan = false;
338 new Future.microtask(() {
339 microtaskRan = true;
340 });
341 expect(microtaskRan, isFalse,
342 reason: 'should not flush until asked to');
343 async.flushMicrotasks();
344 expect(microtaskRan, isTrue);
345 });
346 });
347 test('should flush microtasks scheduled by microtasks in order', () {
348 new FakeAsync().run((async) {
349 final log = [];
350 new Future.microtask(() {
351 log.add(1);
352 new Future.microtask(() {
353 log.add(3);
354 });
355 });
356 new Future.microtask(() {
357 log.add(2);
358 });
359 expect(log, hasLength(0), reason: 'should not flush until asked to');
360 async.flushMicrotasks();
361 expect(log, [1, 2, 3]);
362 });
363 });
364 test('should not run timers', () {
365 new FakeAsync().run((async) {
366 final log = [];
367 new Future.microtask(() {
368 log.add(1);
369 });
370 new Future(() {
371 log.add(2);
372 });
373 new Timer.periodic(new Duration(seconds: 1), (_) {
374 log.add(2);
375 });
376 async.flushMicrotasks();
377 expect(log, [1]);
378 });
379 });
380 });
381
382 group('flushTimers', () {
383 test('should flush timers', () {
384 new FakeAsync().run((async) {
385 final log = [];
386 new Future(() {
387 log.add(2);
388 new Future.delayed(elapseBy, () {
389 log.add(3);
390 });
391 });
392 new Future(() {
393 log.add(1);
394 });
395 expect(log, hasLength(0), reason: 'should not flush until asked to');
396 async.flushTimers(timeout: elapseBy * 2, flushPeriodicTimers: false);
397 expect(log, [1, 2, 3]);
398 expect(async.getClock(initialTime).now(), initialTime.add(elapseBy));
399 });
400 });
401
402 test('should run collateral periodic timers', () {
403 new FakeAsync().run((async) {
404 final log = [];
405 new Future.delayed(new Duration(seconds: 2), () {
406 log.add('delayed');
407 });
408 new Timer.periodic(new Duration(seconds: 1), (_) {
409 log.add('periodic');
410 });
411 expect(log, hasLength(0), reason: 'should not flush until asked to');
412 async.flushTimers(flushPeriodicTimers: false);
413 expect(log, ['periodic', 'periodic', 'delayed']);
414 });
415 });
416
417 test('should timeout', () {
418 new FakeAsync().run((async) {
419 int count = 0;
420 // Schedule 3 timers. All but the last one should fire.
421 for (int delay in [30, 60, 90]) {
422 new Future.delayed(new Duration(minutes: delay), () {
423 count++;
424 });
425 }
426 expect(() => async.flushTimers(flushPeriodicTimers: false),
427 throwsStateError);
428 expect(count, 2);
429 });
430 });
431
432 test('should timeout a chain of timers', () {
433 new FakeAsync().run((async) {
434 int count = 0;
435 createTimer() {
436 new Future.delayed(new Duration(minutes: 30), () {
437 count++;
438 createTimer();
439 });
440 }
441 createTimer();
442 expect(() => async.flushTimers(
443 timeout: new Duration(hours: 2), flushPeriodicTimers: false),
444 throwsStateError);
445 expect(count, 4);
446 });
447 });
448
449 test('should timeout periodic timers', () {
450 new FakeAsync().run((async) {
451 int count = 0;
452 new Timer.periodic(new Duration(minutes: 30), (Timer timer) {
453 count++;
454 });
455 expect(() => async.flushTimers(timeout: new Duration(hours: 1)),
456 throwsStateError);
457 expect(count, 2);
458 });
459 });
460
461 test('should flush periodic timers', () {
462 new FakeAsync().run((async) {
463 int count = 0;
464 new Timer.periodic(new Duration(minutes: 30), (Timer timer) {
465 if (count == 3) {
466 timer.cancel();
467 }
468 count++;
469 });
470 async.flushTimers(timeout: new Duration(hours: 20));
471 expect(count, 4);
472 });
473 });
474
475 test('should compute absolute timeout as elapsed + timeout', () {
476 new FakeAsync().run((async) {
477 final log = [];
478 int count = 0;
479 createTimer() {
480 new Future.delayed(new Duration(minutes: 30), () {
481 log.add(count);
482 count++;
483 if (count < 4) {
484 createTimer();
485 }
486 });
487 }
488 createTimer();
489 async.elapse(new Duration(hours: 1));
490 async.flushTimers(timeout: new Duration(hours: 1));
491 expect(count, 4);
492 });
493 });
494 });
495
496 group('stats', () {
497 test('should report the number of pending microtasks', () {
498 new FakeAsync().run((async) {
499 expect(async.microtaskCount, 0);
500 scheduleMicrotask(() => null);
501 expect(async.microtaskCount, 1);
502 scheduleMicrotask(() => null);
503 expect(async.microtaskCount, 2);
504 async.flushMicrotasks();
505 expect(async.microtaskCount, 0);
506 });
507 });
508
509 test('it should report the number of pending periodic timers', () {
510 new FakeAsync().run((async) {
511 expect(async.periodicTimerCount, 0);
512 Timer timer = new Timer.periodic(new Duration(minutes: 30),
513 (Timer timer) { });
514 expect(async.periodicTimerCount, 1);
515 new Timer.periodic(new Duration(minutes: 20), (Timer timer) { });
516 expect(async.periodicTimerCount, 2);
517 async.elapse(new Duration(minutes: 20));
518 expect(async.periodicTimerCount, 2);
519 timer.cancel();
520 expect(async.periodicTimerCount, 1);
521 });
522 });
523
524 test('it should report the number of pending non periodic timers', () {
525 new FakeAsync().run((async) {
526 expect(async.nonPeriodicTimerCount, 0);
527 Timer timer = new Timer(new Duration(minutes: 30), () { });
528 expect(async.nonPeriodicTimerCount, 1);
529 new Timer(new Duration(minutes: 20), () { });
530 expect(async.nonPeriodicTimerCount, 2);
531 async.elapse(new Duration(minutes: 25));
532 expect(async.nonPeriodicTimerCount, 1);
533 timer.cancel();
534 expect(async.nonPeriodicTimerCount, 0);
535 });
536 });
537 });
538 });
539 }
OLDNEW
« no previous file with comments | « packages/quiver/test/testing/async/all_tests.dart ('k') | packages/quiver/test/testing/equality/all_tests.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698