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

Side by Side Diff: tests/lib_strong/async/future_test.dart

Issue 2802973005: Migrate async tests to strong (Closed)
Patch Set: Created 3 years, 8 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 (c) 2012, 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 library future_test;
6
7 import 'package:async_helper/async_helper.dart';
8 import "package:expect/expect.dart";
9 import 'dart:async';
10
11 const Duration MS = const Duration(milliseconds: 1);
12
13 void testValue() {
14 final future = new Future<String>.value("42");
15 asyncStart();
16 future.then((x) {
17 Expect.equals("42", x);
18 asyncEnd();
19 });
20 }
21
22 void testSync() {
23 compare(func) {
24 // Compare the results of the following two futures.
25 Future f1 = new Future.sync(func);
26 Future f2 = new Future.value().then((_) => func());
27 f2.catchError((_) {}); // I'll get the error later.
28 f1.then((v1) {
29 f2.then((v2) {
30 Expect.equals(v1, v2);
31 });
32 }, onError: (e1) {
33 f2.then((_) {
34 Expect.fail("Expected error");
35 }, onError: (e2) {
36 Expect.equals(e1, e2);
37 });
38 });
39 }
40
41 Future val = new Future.value(42);
42 Future err1 = new Future.error("Error")..catchError((_) {});
43 try {
44 throw new List(0);
45 } catch (e, st) {
46 Future err2 = new Future.error(e, st)..catchError((_) {});
47 }
48 compare(() => 42);
49 compare(() => val);
50 compare(() {
51 throw "Flif";
52 });
53 compare(() => err1);
54 bool hasExecuted = false;
55 compare(() {
56 hasExecuted = true;
57 return 499;
58 });
59 Expect.isTrue(hasExecuted);
60 }
61
62 void testNeverComplete() {
63 final completer = new Completer<int>();
64 final future = completer.future;
65 future.then((v) => Expect.fail("Value not expected"));
66 future.catchError((e) => Expect.fail("Value not expected"));
67 }
68
69 void testComplete() {
70 final completer = new Completer<int>();
71 final future = completer.future;
72 Expect.isFalse(completer.isCompleted);
73
74 completer.complete(3);
75 Expect.isTrue(completer.isCompleted);
76
77 future.then((v) => Expect.equals(3, v));
78 }
79
80 // Tests for [then]
81
82 void testCompleteWithSuccessHandlerBeforeComplete() {
83 final completer = new Completer<int>();
84 final future = completer.future;
85
86 int after;
87
88 asyncStart();
89 future.then((int v) {
90 after = v;
91 }).then((_) {
92 Expect.equals(3, after);
93 asyncEnd();
94 });
95
96 completer.complete(3);
97 Expect.isNull(after);
98 }
99
100 void testCompleteWithSuccessHandlerAfterComplete() {
101 final completer = new Completer<int>();
102 final future = completer.future;
103
104 int after;
105 completer.complete(3);
106 Expect.isNull(after);
107
108 asyncStart();
109 future.then((int v) {
110 after = v;
111 }).then((_) {
112 Expect.equals(3, after);
113 asyncEnd();
114 });
115 }
116
117 void testCompleteManySuccessHandlers() {
118 final completer = new Completer<int>();
119 final future = completer.future;
120 int before;
121 int after1;
122 int after2;
123
124 var futures = [];
125 futures.add(future.then((int v) {
126 before = v;
127 }));
128 completer.complete(3);
129 futures.add(future.then((int v) {
130 after1 = v;
131 }));
132 futures.add(future.then((int v) {
133 after2 = v;
134 }));
135
136 asyncStart();
137 Future.wait(futures).then((_) {
138 Expect.equals(3, before);
139 Expect.equals(3, after1);
140 Expect.equals(3, after2);
141 asyncEnd();
142 });
143 }
144
145 // Tests for [catchError]
146
147 void testException() {
148 final completer = new Completer<int>();
149 final future = completer.future;
150 final ex = new Exception();
151
152 asyncStart();
153 future.then((v) {
154 throw "Value not expected";
155 }).catchError((error) {
156 Expect.equals(error, ex);
157 asyncEnd();
158 }, test: (e) => e == ex);
159 completer.completeError(ex);
160 }
161
162 void testExceptionHandler() {
163 final completer = new Completer<int>();
164 final future = completer.future;
165 final ex = new Exception();
166
167 var ex2;
168 var done = future.catchError((error) {
169 ex2 = error;
170 });
171
172 Expect.isFalse(completer.isCompleted);
173 completer.completeError(ex);
174 Expect.isTrue(completer.isCompleted);
175
176 asyncStart();
177 done.then((_) {
178 Expect.equals(ex, ex2);
179 asyncEnd();
180 });
181 }
182
183 void testExceptionHandlerReturnsTrue() {
184 final completer = new Completer<int>();
185 final future = completer.future;
186 final ex = new Exception();
187
188 bool reached = false;
189 future.catchError((e) {});
190 future.catchError((e) {
191 reached = true;
192 }, test: (e) => false).catchError((e) {});
193 Expect.isFalse(completer.isCompleted);
194 completer.completeError(ex);
195 Expect.isTrue(completer.isCompleted);
196 Expect.isFalse(reached);
197 }
198
199 void testExceptionHandlerReturnsTrue2() {
200 final completer = new Completer<int>();
201 final future = completer.future;
202 final ex = new Exception();
203
204 bool reached = false;
205 var done = future.catchError((e) {}, test: (e) => false).catchError((e) {
206 reached = true;
207 });
208 completer.completeError(ex);
209
210 asyncStart();
211 done.then((_) {
212 Expect.isTrue(reached);
213 asyncEnd();
214 });
215 }
216
217 void testExceptionHandlerReturnsFalse() {
218 final completer = new Completer<int>();
219 final future = completer.future;
220 final ex = new Exception();
221
222 bool reached = false;
223
224 future.catchError((e) {});
225
226 future.catchError((e) {
227 reached = true;
228 }, test: (e) => false).catchError((e) {});
229
230 completer.completeError(ex);
231
232 Expect.isFalse(reached);
233 }
234
235 void testFutureAsStreamCompleteAfter() {
236 var completer = new Completer();
237 bool gotValue = false;
238 asyncStart();
239 completer.future.asStream().listen((data) {
240 Expect.isFalse(gotValue);
241 gotValue = true;
242 Expect.equals("value", data);
243 }, onDone: () {
244 Expect.isTrue(gotValue);
245 asyncEnd();
246 });
247 completer.complete("value");
248 }
249
250 void testFutureAsStreamCompleteBefore() {
251 var completer = new Completer();
252 bool gotValue = false;
253 asyncStart();
254 completer.complete("value");
255 completer.future.asStream().listen((data) {
256 Expect.isFalse(gotValue);
257 gotValue = true;
258 Expect.equals("value", data);
259 }, onDone: () {
260 Expect.isTrue(gotValue);
261 asyncEnd();
262 });
263 }
264
265 void testFutureAsStreamCompleteImmediate() {
266 bool gotValue = false;
267 asyncStart();
268 new Future.value("value").asStream().listen((data) {
269 Expect.isFalse(gotValue);
270 gotValue = true;
271 Expect.equals("value", data);
272 }, onDone: () {
273 Expect.isTrue(gotValue);
274 asyncEnd();
275 });
276 }
277
278 void testFutureAsStreamCompleteErrorAfter() {
279 var completer = new Completer();
280 bool gotError = false;
281 asyncStart();
282 completer.future.asStream().listen((data) {
283 Expect.fail("Unexpected data");
284 }, onError: (error) {
285 Expect.isFalse(gotError);
286 gotError = true;
287 Expect.equals("error", error);
288 }, onDone: () {
289 Expect.isTrue(gotError);
290 asyncEnd();
291 });
292 completer.completeError("error");
293 }
294
295 void testFutureAsStreamWrapper() {
296 var completer = new Completer();
297 bool gotValue = false;
298 asyncStart();
299 completer.complete("value");
300 completer.future
301 .catchError((_) {
302 throw "not possible";
303 }) // Returns a future wrapper.
304 .asStream()
305 .listen((data) {
306 Expect.isFalse(gotValue);
307 gotValue = true;
308 Expect.equals("value", data);
309 }, onDone: () {
310 Expect.isTrue(gotValue);
311 asyncEnd();
312 });
313 }
314
315 void testFutureWhenCompleteValue() {
316 asyncStart();
317 int counter = 2;
318 countDown() {
319 if (--counter == 0) asyncEnd();
320 }
321
322 var completer = new Completer();
323 Future future = completer.future;
324 Future later = future.whenComplete(countDown);
325 later.then((v) {
326 Expect.equals(42, v);
327 countDown();
328 });
329 completer.complete(42);
330 }
331
332 void testFutureWhenCompleteError() {
333 asyncStart();
334 int counter = 2;
335 countDown() {
336 if (--counter == 0) asyncEnd();
337 }
338
339 var completer = new Completer();
340 Future future = completer.future;
341 Future later = future.whenComplete(countDown);
342 later.catchError((error) {
343 Expect.equals("error", error);
344 countDown();
345 });
346 completer.completeError("error");
347 }
348
349 void testFutureWhenCompleteValueNewError() {
350 asyncStart();
351 int counter = 2;
352 countDown() {
353 if (--counter == 0) asyncEnd();
354 }
355
356 var completer = new Completer();
357 Future future = completer.future;
358 Future later = future.whenComplete(() {
359 countDown();
360 throw "new error";
361 });
362 later.catchError((error) {
363 Expect.equals("new error", error);
364 countDown();
365 });
366 completer.complete(42);
367 }
368
369 void testFutureWhenCompleteErrorNewError() {
370 asyncStart();
371 int counter = 2;
372 countDown() {
373 if (--counter == 0) asyncEnd();
374 }
375
376 var completer = new Completer();
377 Future future = completer.future;
378 Future later = future.whenComplete(() {
379 countDown();
380 throw "new error";
381 });
382 later.catchError((error) {
383 Expect.equals("new error", error);
384 countDown();
385 });
386 completer.completeError("error");
387 }
388
389 void testFutureWhenCompletePreValue() {
390 asyncStart();
391 int counter = 2;
392 countDown() {
393 if (--counter == 0) asyncEnd();
394 }
395
396 var completer = new Completer();
397 Future future = completer.future;
398 completer.complete(42);
399 Timer.run(() {
400 Future later = future.whenComplete(countDown);
401 later.then((v) {
402 Expect.equals(42, v);
403 countDown();
404 });
405 });
406 }
407
408 void testFutureWhenValueFutureValue() {
409 asyncStart();
410 int counter = 3;
411 countDown(int expect) {
412 Expect.equals(expect, counter);
413 if (--counter == 0) asyncEnd();
414 }
415
416 var completer = new Completer();
417 completer.future.whenComplete(() {
418 countDown(3);
419 var completer2 = new Completer();
420 new Timer(MS * 10, () {
421 countDown(2);
422 completer2.complete(37);
423 });
424 return completer2.future;
425 }).then((v) {
426 Expect.equals(42, v);
427 countDown(1);
428 });
429
430 completer.complete(42);
431 }
432
433 void testFutureWhenValueFutureError() {
434 asyncStart();
435 int counter = 3;
436 countDown(int expect) {
437 Expect.equals(expect, counter);
438 if (--counter == 0) asyncEnd();
439 }
440
441 var completer = new Completer();
442 completer.future.whenComplete(() {
443 countDown(3);
444 var completer2 = new Completer();
445 new Timer(MS * 10, () {
446 countDown(2);
447 completer2.completeError("Fail");
448 });
449 return completer2.future;
450 }).then((v) {
451 Expect.fail("should fail async");
452 }, onError: (error) {
453 Expect.equals("Fail", error);
454 countDown(1);
455 });
456
457 completer.complete(42);
458 }
459
460 void testFutureWhenErrorFutureValue() {
461 asyncStart();
462 int counter = 3;
463 countDown(int expect) {
464 Expect.equals(expect, counter);
465 if (--counter == 0) asyncEnd();
466 }
467
468 var completer = new Completer();
469 completer.future.whenComplete(() {
470 countDown(3);
471 var completer2 = new Completer();
472 new Timer(MS * 10, () {
473 countDown(2);
474 completer2.complete(37);
475 });
476 return completer2.future;
477 }).then((v) {
478 Expect.fail("should fail async");
479 }, onError: (error) {
480 Expect.equals("Error", error);
481 countDown(1);
482 });
483
484 completer.completeError("Error");
485 }
486
487 void testFutureWhenErrorFutureError() {
488 asyncStart();
489 int counter = 3;
490 countDown(int expect) {
491 Expect.equals(expect, counter);
492 if (--counter == 0) asyncEnd();
493 }
494
495 var completer = new Completer();
496 completer.future.whenComplete(() {
497 countDown(3);
498 var completer2 = new Completer();
499 new Timer(MS * 10, () {
500 countDown(2);
501 completer2.completeError("Fail");
502 });
503 return completer2.future;
504 }).then((v) {
505 Expect.fail("should fail async");
506 }, onError: (error) {
507 Expect.equals("Fail", error);
508 countDown(1);
509 });
510
511 completer.completeError("Error");
512 }
513
514 void testFutureThenThrowsAsync() {
515 final completer = new Completer<int>();
516 final future = completer.future;
517 int error = 42;
518
519 asyncStart();
520 future.then((v) {
521 throw error;
522 }).catchError((e) {
523 Expect.identical(error, e);
524 asyncEnd();
525 });
526 completer.complete(0);
527 }
528
529 void testFutureCatchThrowsAsync() {
530 final completer = new Completer<int>();
531 final future = completer.future;
532 int error = 42;
533
534 asyncStart();
535 future.catchError((e) {
536 throw error;
537 }).catchError((e) {
538 Expect.identical(error, e);
539 asyncEnd();
540 });
541 completer.completeError(0);
542 }
543
544 void testFutureCatchRethrowsAsync() {
545 final completer = new Completer<int>();
546 final future = completer.future;
547 var error;
548
549 asyncStart();
550 future.catchError((e) {
551 error = e;
552 throw e;
553 }).catchError((e) {
554 Expect.identical(error, e);
555 asyncEnd();
556 });
557 completer.completeError(0);
558 }
559
560 void testFutureWhenThrowsAsync() {
561 final completer = new Completer<int>();
562 final future = completer.future;
563 var error = 42;
564
565 asyncStart();
566 future.whenComplete(() {
567 throw error;
568 }).catchError((e) {
569 Expect.identical(error, e);
570 asyncEnd();
571 });
572 completer.complete(0);
573 }
574
575 void testCompleteWithError() {
576 final completer = new Completer<int>();
577 final future = completer.future;
578 var error = 42;
579
580 asyncStart();
581 future.catchError((e) {
582 Expect.identical(error, e);
583 asyncEnd();
584 });
585
586 completer.completeError(error);
587 }
588
589 void testCompleteWithFutureSuccess() {
590 asyncStart();
591 final completer = new Completer<int>();
592 final completer2 = new Completer<int>();
593 completer.complete(completer2.future);
594 completer.future.then((v) {
595 Expect.equals(42, v);
596 asyncEnd();
597 });
598 completer2.complete(42);
599 }
600
601 void testCompleteWithFutureSuccess2() {
602 asyncStart();
603 final completer = new Completer<int>();
604 Future result = new Future.value(42);
605 completer.complete(result);
606 completer.future.then((v) {
607 Expect.equals(42, v);
608 asyncEnd();
609 });
610 }
611
612 void testCompleteWithFutureError() {
613 asyncStart();
614 final completer = new Completer<int>();
615 final completer2 = new Completer<int>();
616 completer.complete(completer2.future);
617 completer.future.then((v) {
618 Expect.fail("Should not happen");
619 asyncEnd();
620 }, onError: (e) {
621 Expect.equals("ERROR-tcwfe", e);
622 asyncEnd();
623 });
624 completer2.completeError("ERROR-tcwfe");
625 }
626
627 void testCompleteWithFutureError2() {
628 asyncStart();
629 final completer = new Completer<int>();
630 Future result = new Future.error("ERROR-tcwfe2");
631 completer.complete(result);
632 completer.future.then((v) {
633 Expect.fail("Should not happen");
634 asyncEnd();
635 }, onError: (e) {
636 Expect.equals("ERROR-tcwfe2", e);
637 asyncEnd();
638 });
639 }
640
641 void testCompleteErrorWithFuture() {
642 asyncStart();
643 final completer = new Completer<int>();
644 completer.completeError(new Future.value(42));
645 completer.future.then((_) {
646 Expect.fail("Shouldn't happen");
647 }, onError: (e, s) {
648 Future f = e;
649 f.then((v) {
650 Expect.equals(42, v);
651 asyncEnd();
652 });
653 });
654 }
655
656 void testCompleteWithCustomFutureSuccess() {
657 asyncStart();
658 final completer = new Completer<int>();
659 final completer2 = new Completer<int>();
660 completer.complete(new CustomFuture(completer2.future));
661 completer.future.then((v) {
662 Expect.equals(42, v);
663 asyncEnd();
664 });
665 completer2.complete(42);
666 }
667
668 void testCompleteWithCustomFutureError() {
669 asyncStart();
670 final completer = new Completer<int>();
671 final completer2 = new Completer<int>();
672 completer.complete(new CustomFuture(completer2.future));
673 completer.future.then((v) {
674 Expect.fail("Should not happen");
675 asyncEnd();
676 }, onError: (e) {
677 Expect.equals("ERROR-tcwcfe", e);
678 asyncEnd();
679 });
680 completer2.completeError("ERROR-tcwcfe");
681 }
682
683 void testCompleteErrorWithCustomFuture() {
684 asyncStart();
685 final completer = new Completer<int>();
686 var future = new CustomFuture(new Future.value(42));
687 completer.completeError(future);
688 completer.future.then((_) {
689 Expect.fail("Shouldn't happen");
690 }, onError: (Future f) {
691 f.then((v) {
692 Expect.equals(42, v);
693 asyncEnd();
694 });
695 });
696 }
697
698 void testCompleteErrorWithNull() {
699 asyncStart();
700 final completer = new Completer<int>();
701 completer.future.catchError((e) {
702 Expect.isTrue(e is NullThrownError);
703 asyncEnd();
704 });
705 completer.completeError(null);
706 }
707
708 void testChainedFutureValue() {
709 final completer = new Completer();
710 final future = completer.future;
711 asyncStart();
712
713 future.then((v) => new Future.value(v * 2)).then((v) {
714 Expect.equals(42, v);
715 asyncEnd();
716 });
717 completer.complete(21);
718 }
719
720 void testChainedFutureValueDelay() {
721 final completer = new Completer();
722 final future = completer.future;
723 asyncStart();
724
725 future
726 .then((v) =>
727 new Future.delayed(const Duration(milliseconds: 10), () => v * 2))
728 .then((v) {
729 Expect.equals(42, v);
730 asyncEnd();
731 });
732 completer.complete(21);
733 }
734
735 void testChainedFutureValue2Delay() {
736 asyncStart();
737
738 new Future.delayed(const Duration(milliseconds: 10)).then((v) {
739 Expect.isNull(v);
740 asyncEnd();
741 });
742 }
743
744 void testChainedFutureError() {
745 final completer = new Completer();
746 final future = completer.future;
747 asyncStart();
748
749 future.then((v) => new Future.error("Fehler")).then((v) {
750 Expect.fail("unreachable!");
751 }, onError: (error) {
752 Expect.equals("Fehler", error);
753 asyncEnd();
754 });
755 completer.complete(21);
756 }
757
758 void testSyncFuture_i13368() {
759 asyncStart();
760
761 final future = new Future<int>.sync(() {
762 return new Future<int>.value(42);
763 });
764
765 future.then((int val) {
766 Expect.equals(val, 42);
767 asyncEnd();
768 });
769 }
770
771 void testWaitCleanUp() {
772 asyncStart();
773 // Creates three futures with different completion times, and where some fail.
774 // The `mask` specifies which futures fail (values 1-7),
775 // and `permute` defines the order of completion. values 0-5.
776 void doTest(int mask, int permute) {
777 asyncStart();
778 String stringId = "waitCleanup-$mask-$permute";
779 List futures = new List(3);
780 List cleanup = new List(3);
781 int permuteTmp = permute;
782 for (int i = 0; i < 3; i++) {
783 bool throws = (mask & (1 << i)) != 0;
784 var future = new Future.delayed(new Duration(milliseconds: 100 * (i + 1)),
785 () => (throws ? throw "Error $i($mask-$permute)" : i));
786 int mod = 3 - i;
787 int position = permuteTmp % mod;
788 permuteTmp = permuteTmp ~/ mod;
789 while (futures[position] != null) position++;
790 futures[position] = future;
791 cleanup[i] = throws;
792 }
793 void cleanUp(index) {
794 Expect.isFalse(cleanup[index]);
795 cleanup[index] = true;
796 }
797
798 Future.wait(futures, cleanUp: cleanUp).then((_) {
799 Expect.fail("No error: $stringId");
800 }, onError: (e, s) {
801 Expect.listEquals([true, true, true], cleanup);
802 asyncEnd();
803 });
804 }
805
806 for (int i = 1; i < 8; i++) {
807 for (int j = 0; j < 6; j++) {
808 doTest(i, j);
809 }
810 }
811 asyncEnd();
812 }
813
814 void testWaitCleanUpEager() {
815 asyncStart();
816 // Creates three futures with different completion times, and where some fail.
817 // The `mask` specifies which futures fail (values 1-7),
818 // and `permute` defines the order of completion. values 0-5.
819 void doTest(int mask, int permute) {
820 asyncStart();
821 asyncStart();
822 bool done = false;
823 String stringId = "waitCleanup-$mask-$permute";
824 List futures = new List(3);
825 List cleanup = new List(3);
826 int permuteTmp = permute;
827 for (int i = 0; i < 3; i++) {
828 bool throws = (mask & (1 << i)) != 0;
829 var future = new Future.delayed(new Duration(milliseconds: 100 * (i + 1)),
830 () => (throws ? throw "Error $i($mask-$permute)" : i));
831 int mod = 3 - i;
832 int position = permuteTmp % mod;
833 permuteTmp = permuteTmp ~/ mod;
834 while (futures[position] != null) position++;
835 futures[position] = future;
836 cleanup[i] = throws;
837 }
838 void checkDone() {
839 if (done) return;
840 if (cleanup.every((v) => v)) {
841 done = true;
842 asyncEnd();
843 }
844 }
845
846 void cleanUp(index) {
847 Expect.isFalse(cleanup[index]);
848 cleanup[index] = true;
849 // Cleanup might happen before and after the wait().then() callback.
850 checkDone();
851 }
852
853 Future.wait(futures, eagerError: true, cleanUp: cleanUp).then((_) {
854 Expect.fail("No error: $stringId");
855 }, onError: (e, s) {
856 asyncEnd();
857 checkDone();
858 });
859 }
860
861 for (int i = 1; i < 8; i++) {
862 for (int j = 0; j < 6; j++) {
863 doTest(i, j);
864 }
865 }
866 asyncEnd();
867 }
868
869 void testWaitCleanUpError() {
870 var cms = const Duration(milliseconds: 100);
871 var cleanups = new List.filled(3, false);
872 var uncaughts = new List.filled(3, false);
873 asyncStart();
874 asyncStart();
875 asyncStart();
876 runZoned(() {
877 Future.wait([
878 new Future.delayed(cms, () => 0),
879 new Future.delayed(cms * 2, () => throw 1),
880 new Future.delayed(cms * 3, () => 2)
881 ], cleanUp: (index) {
882 Expect.isTrue(index == 0 || index == 2, "$index");
883 Expect.isFalse(cleanups[index]);
884 cleanups[index] = true;
885 throw index;
886 }).catchError((e) {
887 Expect.equals(e, 1);
888 asyncEnd();
889 });
890 }, onError: (int index, s) {
891 Expect.isTrue(index == 0 || index == 2, "$index");
892 Expect.isFalse(uncaughts[index]);
893 uncaughts[index] = true;
894 asyncEnd();
895 });
896 }
897
898 void testWaitSyncError() {
899 var cms = const Duration(milliseconds: 100);
900 var cleanups = new List.filled(3, false);
901 asyncStart();
902 asyncStart();
903 runZoned(() {
904 Future.wait(
905 new Iterable.generate(5, (i) {
906 if (i != 3) return new Future.delayed(cms * (i + 1), () => i);
907 throw "throwing synchronously in iterable";
908 }), cleanUp: (index) {
909 Expect.isFalse(cleanups[index]);
910 cleanups[index] = true;
911 if (cleanups.every((x) => x)) asyncEnd();
912 });
913 }, onError: (e, s) {
914 asyncEnd();
915 });
916 }
917
918 void testWaitSyncError2() {
919 asyncStart();
920 Future.wait([null]).catchError((e, st) {
921 // Makes sure that the `catchError` is invoked.
922 // Regression test: an earlier version of `Future.wait` would propagate
923 // the error too soon for the code to install an error handler.
924 // `testWaitSyncError` didn't show this problem, because the `runZoned`
925 // was already installed.
926 asyncEnd();
927 });
928 }
929
930 // Future.wait transforms synchronous errors into asynchronous ones.
931 // This function tests that zones can intercept them.
932 void testWaitSyncError3() {
933 var caughtError;
934 var count = 0;
935
936 AsyncError errorCallback(Zone self, ZoneDelegate parent, Zone zone,
937 Object error, StackTrace stackTrace) {
938 Expect.equals(0, count);
939 count++;
940 caughtError = error;
941 return parent.errorCallback(zone, error, stackTrace);
942 }
943
944 asyncStart();
945 runZoned(() {
946 Future.wait([null]).catchError((e, st) {
947 Expect.identical(e, caughtError);
948 Expect.equals(1, count);
949 asyncEnd();
950 });
951 }, zoneSpecification: new ZoneSpecification(errorCallback: errorCallback));
952 }
953
954 void testBadFuture() {
955 var bad = new BadFuture();
956 // Completing with bad future (then call throws) puts error in result.
957 asyncStart();
958 Completer completer = new Completer();
959 completer.complete(bad);
960 completer.future.then((_) {
961 Expect.fail("unreachable");
962 }, onError: (e, s) {
963 Expect.isTrue(completer.isCompleted);
964 asyncEnd();
965 });
966
967 asyncStart();
968 var f = new Future.value().then((_) => bad);
969 f.then((_) {
970 Expect.fail("unreachable");
971 }, onError: (e, s) {
972 asyncEnd();
973 });
974 }
975
976 void testTypes() {
977 // Test that future is a Future<int> and not something less precise.
978 testType(name, future, [depth = 2]) {
979 var desc = "$name${".whenComplete"*(2-depth)}";
980 Expect.isTrue(future is Future<int>, "$desc is Future<int>");
981 Expect.isFalse(future is Future<String>, "$desc is! Future<String>");
982 var stream = future.asStream();
983 Expect.isTrue(stream is Stream<int>, "$desc.asStream() is Stream<int>");
984 Expect.isFalse(
985 stream is Stream<String>, "$desc.asStream() is! Stream<String>");
986 if (depth > 0) {
987 testType(name, future.whenComplete(() {}), depth - 1);
988 }
989 }
990
991 for (var value in [42, null]) {
992 testType("Future($value)", new Future<int>(() => value));
993 testType("Future.delayed($value)",
994 new Future<int>.delayed(Duration.ZERO, () => value));
995 testType(
996 "Future.microtask($value)", new Future<int>.microtask(() => value));
997 testType("Future.sync($value)", new Future<int>.sync(() => value)); //# 01: ok
998 testType("Future.sync(future($value))", // //# 01: continued
999 new Future<int>.sync(() => new Future<int>.value(value))); //# 01: continued
1000 testType("Future.value($value)", new Future<int>.value(value));
1001 }
1002 testType("Completer.future", new Completer<int>().future);
1003 testType("Future.error", new Future<int>.error("ERR")..catchError((_) {}));
1004 }
1005
1006 void testAnyValue() {
1007 asyncStart();
1008 var cs = new List.generate(3, (_) => new Completer());
1009 var result = Future.any(cs.map((x) => x.future));
1010
1011 result.then((v) {
1012 Expect.equals(42, v);
1013 asyncEnd();
1014 }, onError: (e, s) {
1015 Expect.fail("Unexpected error: $e");
1016 });
1017
1018 cs[1].complete(42);
1019 cs[2].complete(10);
1020 cs[0].complete(20);
1021 }
1022
1023 void testAnyError() {
1024 asyncStart();
1025 var cs = new List.generate(3, (_) => new Completer());
1026 var result = Future.any(cs.map((x) => x.future));
1027
1028 result.then((v) {
1029 Expect.fail("Unexpected value: $v");
1030 }, onError: (e, s) {
1031 Expect.equals(42, e);
1032 asyncEnd();
1033 });
1034
1035 cs[1].completeError(42);
1036 cs[2].complete(10);
1037 cs[0].complete(20);
1038 }
1039
1040 void testAnyIgnoreIncomplete() {
1041 asyncStart();
1042 var cs = new List.generate(3, (_) => new Completer());
1043 var result = Future.any(cs.map((x) => x.future));
1044
1045 result.then((v) {
1046 Expect.equals(42, v);
1047 asyncEnd();
1048 }, onError: (e, s) {
1049 Expect.fail("Unexpected error: $e");
1050 });
1051
1052 cs[1].complete(42);
1053 // The other two futures never complete.
1054 }
1055
1056 void testAnyIgnoreError() {
1057 asyncStart();
1058 var cs = new List.generate(3, (_) => new Completer());
1059 var result = Future.any(cs.map((x) => x.future));
1060
1061 result.then((v) {
1062 Expect.equals(42, v);
1063 asyncEnd();
1064 }, onError: (e, s) {
1065 Expect.fail("Unexpected error: $e");
1066 });
1067
1068 cs[1].complete(42);
1069 // The errors are ignored, not uncaught.
1070 cs[2].completeError("BAD");
1071 cs[0].completeError("BAD");
1072 }
1073
1074 void testFutureResult() {
1075 asyncStart();
1076 () async {
1077 var f = new UglyFuture(5);
1078 // Sanity check that our future is as mis-behaved as we think.
1079 f.then((v) {
1080 Expect.isTrue(v is Future);
1081 });
1082
1083 var v = await f;
1084 // The static type of await is Flatten(static-type-of-expression), so it
1085 // suggests that it flattens. In practice it currently doesn't.
1086 // The specification doesn't say anything special, so v should be the
1087 // completion value of the UglyFuture future which is a future.
1088 Expect.isTrue(v is Future);
1089
1090 // This used to hit an assert in checked mode.
1091 // The CL adding this test changed the behavior to actually flatten the
1092 // the future returned by the then-callback.
1093 var w = new Future.value(42).then((_) => f);
1094 Expect.equals(42, await w);
1095 asyncEnd();
1096 }();
1097 }
1098
1099 main() {
1100 asyncStart();
1101
1102 testValue();
1103 testSync();
1104 testNeverComplete();
1105
1106 testComplete();
1107 testCompleteWithSuccessHandlerBeforeComplete();
1108 testCompleteWithSuccessHandlerAfterComplete();
1109 testCompleteManySuccessHandlers();
1110 testCompleteWithError();
1111
1112 testCompleteWithFutureSuccess();
1113 testCompleteWithFutureSuccess2();
1114 testCompleteWithFutureError();
1115 testCompleteWithFutureError2();
1116 testCompleteErrorWithFuture();
1117 testCompleteWithCustomFutureSuccess();
1118 testCompleteWithCustomFutureError();
1119 testCompleteErrorWithCustomFuture();
1120 testCompleteErrorWithNull();
1121
1122 testException();
1123 testExceptionHandler();
1124 testExceptionHandlerReturnsTrue();
1125 testExceptionHandlerReturnsTrue2();
1126 testExceptionHandlerReturnsFalse();
1127
1128 testFutureAsStreamCompleteAfter();
1129 testFutureAsStreamCompleteBefore();
1130 testFutureAsStreamCompleteImmediate();
1131 testFutureAsStreamCompleteErrorAfter();
1132 testFutureAsStreamWrapper();
1133
1134 testFutureWhenCompleteValue();
1135 testFutureWhenCompleteError();
1136 testFutureWhenCompleteValueNewError();
1137 testFutureWhenCompleteErrorNewError();
1138
1139 testFutureWhenValueFutureValue();
1140 testFutureWhenErrorFutureValue();
1141 testFutureWhenValueFutureError();
1142 testFutureWhenErrorFutureError();
1143
1144 testFutureThenThrowsAsync();
1145 testFutureCatchThrowsAsync();
1146 testFutureWhenThrowsAsync();
1147 testFutureCatchRethrowsAsync();
1148
1149 testChainedFutureValue();
1150 testChainedFutureValueDelay();
1151 testChainedFutureError();
1152
1153 testSyncFuture_i13368();
1154
1155 testWaitCleanUp();
1156 testWaitCleanUpError();
1157 testWaitSyncError();
1158 testWaitSyncError2();
1159 testWaitSyncError3();
1160
1161 testBadFuture();
1162
1163 testTypes();
1164
1165 testAnyValue();
1166 testAnyError();
1167 testAnyIgnoreIncomplete();
1168 testAnyIgnoreError();
1169
1170 testFutureResult();
1171
1172 asyncEnd();
1173 }
1174
1175 /// A well-behaved Future that isn't recognizable as a _Future.
1176 class CustomFuture<T> implements Future<T> {
1177 Future _realFuture;
1178 CustomFuture(this._realFuture);
1179 Future then(action(result), {Function onError}) =>
1180 _realFuture.then(action, onError: onError);
1181 Future catchError(Function onError, {bool test(e)}) =>
1182 _realFuture.catchError(onError, test: test);
1183 Future whenComplete(action()) => _realFuture.whenComplete(action);
1184 Future timeout(Duration timeLimit, {void onTimeout()}) =>
1185 _realFuture.timeout(timeLimit, onTimeout: onTimeout);
1186 Stream asStream() => _realFuture.asStream();
1187 String toString() => "CustomFuture@${_realFuture.hashCode}";
1188 int get hashCode => _realFuture.hashCode;
1189 }
1190
1191 /// A bad future that throws on every method.
1192 class BadFuture<T> implements Future<T> {
1193 Future then(action(T result), {Function onError}) {
1194 throw "then GOTCHA!";
1195 }
1196
1197 Future catchError(Function onError, {bool test(e)}) {
1198 throw "catch GOTCHA!";
1199 }
1200
1201 Future whenComplete(action()) {
1202 throw "finally GOTCHA!";
1203 }
1204
1205 Stream<T> asStream() {
1206 throw "asStream GOTCHA!";
1207 }
1208
1209 Future timeout(Duration duration, {onTimeout()}) {
1210 throw "timeout GOTCHA!";
1211 }
1212 }
1213
1214 // An evil future that completes with another future.
1215 class UglyFuture implements Future<dynamic> {
1216 final _result;
1217 UglyFuture(int badness)
1218 : _result = (badness == 0) ? 42 : new UglyFuture(badness - 1);
1219 Future then(action(value), {onError(error, StackTrace stack)}) {
1220 var c = new Completer();
1221 c.complete(new Future.microtask(() => action(_result)));
1222 return c.future;
1223 }
1224
1225 Future catchError(onError, {test}) => this; // Never an error.
1226 Future whenComplete(action()) {
1227 return new Future.microtask(action).then((_) => this);
1228 }
1229
1230 Stream asStream() {
1231 return (new StreamController()
1232 ..add(_result)
1233 ..close())
1234 .stream;
1235 }
1236
1237 Future timeout(Duration duration, {onTimeout()}) {
1238 return this;
1239 }
1240 }
OLDNEW
« no previous file with comments | « tests/lib_strong/async/future_or_strong_test.dart ('k') | tests/lib_strong/async/future_timeout_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698