OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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 library future_test; | 5 library future_test; |
6 | 6 |
7 import 'package:async_helper/async_helper.dart'; | 7 import 'package:async_helper/async_helper.dart'; |
8 import "package:expect/expect.dart"; | 8 import "package:expect/expect.dart"; |
9 import 'dart:async'; | 9 import 'dart:async'; |
10 | 10 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 }); | 114 }); |
115 } | 115 } |
116 | 116 |
117 void testCompleteManySuccessHandlers() { | 117 void testCompleteManySuccessHandlers() { |
118 final completer = new Completer<int>(); | 118 final completer = new Completer<int>(); |
119 final future = completer.future; | 119 final future = completer.future; |
120 int before; | 120 int before; |
121 int after1; | 121 int after1; |
122 int after2; | 122 int after2; |
123 | 123 |
124 var futures = []; | 124 var futures = <Future<int>>[]; |
125 futures.add(future.then((int v) { | 125 futures.add(future.then((int v) { |
126 before = v; | 126 before = v; |
127 })); | 127 })); |
128 completer.complete(3); | 128 completer.complete(3); |
129 futures.add(future.then((int v) { | 129 futures.add(future.then((int v) { |
130 after1 = v; | 130 after1 = v; |
131 })); | 131 })); |
132 futures.add(future.then((int v) { | 132 futures.add(future.then((int v) { |
133 after2 = v; | 133 after2 = v; |
134 })); | 134 })); |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 completer.future.then((v) { | 594 completer.future.then((v) { |
595 Expect.equals(42, v); | 595 Expect.equals(42, v); |
596 asyncEnd(); | 596 asyncEnd(); |
597 }); | 597 }); |
598 completer2.complete(42); | 598 completer2.complete(42); |
599 } | 599 } |
600 | 600 |
601 void testCompleteWithFutureSuccess2() { | 601 void testCompleteWithFutureSuccess2() { |
602 asyncStart(); | 602 asyncStart(); |
603 final completer = new Completer<int>(); | 603 final completer = new Completer<int>(); |
604 Future result = new Future.value(42); | 604 final result = new Future<int>.value(42); |
605 completer.complete(result); | 605 completer.complete(result); |
606 completer.future.then((v) { | 606 completer.future.then((v) { |
607 Expect.equals(42, v); | 607 Expect.equals(42, v); |
608 asyncEnd(); | 608 asyncEnd(); |
609 }); | 609 }); |
610 } | 610 } |
611 | 611 |
612 void testCompleteWithFutureError() { | 612 void testCompleteWithFutureError() { |
613 asyncStart(); | 613 asyncStart(); |
614 final completer = new Completer<int>(); | 614 final completer = new Completer<int>(); |
615 final completer2 = new Completer<int>(); | 615 final completer2 = new Completer<int>(); |
616 completer.complete(completer2.future); | 616 completer.complete(completer2.future); |
617 completer.future.then((v) { | 617 completer.future.then((v) { |
618 Expect.fail("Should not happen"); | 618 Expect.fail("Should not happen"); |
619 asyncEnd(); | 619 asyncEnd(); |
620 }, onError: (e) { | 620 }, onError: (e) { |
621 Expect.equals("ERROR-tcwfe", e); | 621 Expect.equals("ERROR-tcwfe", e); |
622 asyncEnd(); | 622 asyncEnd(); |
623 }); | 623 }); |
624 completer2.completeError("ERROR-tcwfe"); | 624 completer2.completeError("ERROR-tcwfe"); |
625 } | 625 } |
626 | 626 |
627 void testCompleteWithFutureError2() { | 627 void testCompleteWithFutureError2() { |
628 asyncStart(); | 628 asyncStart(); |
629 final completer = new Completer<int>(); | 629 final completer = new Completer<int>(); |
630 Future result = new Future.error("ERROR-tcwfe2"); | 630 var result = new Future<int>.error("ERROR-tcwfe2"); |
631 completer.complete(result); | 631 completer.complete(result); |
632 completer.future.then((v) { | 632 completer.future.then((v) { |
633 Expect.fail("Should not happen"); | 633 Expect.fail("Should not happen"); |
634 asyncEnd(); | 634 asyncEnd(); |
635 }, onError: (e) { | 635 }, onError: (e) { |
636 Expect.equals("ERROR-tcwfe2", e); | 636 Expect.equals("ERROR-tcwfe2", e); |
637 asyncEnd(); | 637 asyncEnd(); |
638 }); | 638 }); |
| 639 |
639 } | 640 } |
640 | 641 |
641 void testCompleteErrorWithFuture() { | 642 void testCompleteErrorWithFuture() { |
642 asyncStart(); | 643 asyncStart(); |
643 final completer = new Completer<int>(); | 644 final completer = new Completer<int>(); |
644 completer.completeError(new Future.value(42)); | 645 completer.completeError(new Future.value(42)); |
645 completer.future.then((_) { | 646 completer.future.then((_) { |
646 Expect.fail("Shouldn't happen"); | 647 Expect.fail("Shouldn't happen"); |
647 }, onError: (e, s) { | 648 }, onError: (e, s) { |
648 Future f = e; | 649 Future f = e; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 } | 770 } |
770 | 771 |
771 void testWaitCleanUp() { | 772 void testWaitCleanUp() { |
772 asyncStart(); | 773 asyncStart(); |
773 // Creates three futures with different completion times, and where some fail. | 774 // Creates three futures with different completion times, and where some fail. |
774 // The `mask` specifies which futures fail (values 1-7), | 775 // The `mask` specifies which futures fail (values 1-7), |
775 // and `permute` defines the order of completion. values 0-5. | 776 // and `permute` defines the order of completion. values 0-5. |
776 void doTest(int mask, int permute) { | 777 void doTest(int mask, int permute) { |
777 asyncStart(); | 778 asyncStart(); |
778 String stringId = "waitCleanup-$mask-$permute"; | 779 String stringId = "waitCleanup-$mask-$permute"; |
779 List futures = new List(3); | 780 List<Future> futures = new List(3); |
780 List cleanup = new List(3); | 781 List cleanup = new List(3); |
781 int permuteTmp = permute; | 782 int permuteTmp = permute; |
782 for (int i = 0; i < 3; i++) { | 783 for (int i = 0; i < 3; i++) { |
783 bool throws = (mask & (1 << i)) != 0; | 784 bool throws = (mask & (1 << i)) != 0; |
784 var future = new Future.delayed(new Duration(milliseconds: 100 * (i + 1)), | 785 var future = new Future.delayed(new Duration(milliseconds: 100 * (i + 1)), |
785 () => (throws ? throw "Error $i($mask-$permute)" : i)); | 786 () => (throws ? throw "Error $i($mask-$permute)" : i)); |
786 int mod = 3 - i; | 787 int mod = 3 - i; |
787 int position = permuteTmp % mod; | 788 int position = permuteTmp % mod; |
788 permuteTmp = permuteTmp ~/ mod; | 789 permuteTmp = permuteTmp ~/ mod; |
789 while (futures[position] != null) position++; | 790 while (futures[position] != null) position++; |
(...skipping 24 matching lines...) Expand all Loading... |
814 void testWaitCleanUpEager() { | 815 void testWaitCleanUpEager() { |
815 asyncStart(); | 816 asyncStart(); |
816 // Creates three futures with different completion times, and where some fail. | 817 // Creates three futures with different completion times, and where some fail. |
817 // The `mask` specifies which futures fail (values 1-7), | 818 // The `mask` specifies which futures fail (values 1-7), |
818 // and `permute` defines the order of completion. values 0-5. | 819 // and `permute` defines the order of completion. values 0-5. |
819 void doTest(int mask, int permute) { | 820 void doTest(int mask, int permute) { |
820 asyncStart(); | 821 asyncStart(); |
821 asyncStart(); | 822 asyncStart(); |
822 bool done = false; | 823 bool done = false; |
823 String stringId = "waitCleanup-$mask-$permute"; | 824 String stringId = "waitCleanup-$mask-$permute"; |
824 List futures = new List(3); | 825 List<Future> futures = new List<Future>(3); |
825 List cleanup = new List(3); | 826 List cleanup = new List(3); |
826 int permuteTmp = permute; | 827 int permuteTmp = permute; |
827 for (int i = 0; i < 3; i++) { | 828 for (int i = 0; i < 3; i++) { |
828 bool throws = (mask & (1 << i)) != 0; | 829 bool throws = (mask & (1 << i)) != 0; |
829 var future = new Future.delayed(new Duration(milliseconds: 100 * (i + 1)), | 830 var future = new Future.delayed(new Duration(milliseconds: 100 * (i + 1)), |
830 () => (throws ? throw "Error $i($mask-$permute)" : i)); | 831 () => (throws ? throw "Error $i($mask-$permute)" : i)); |
831 int mod = 3 - i; | 832 int mod = 3 - i; |
832 int position = permuteTmp % mod; | 833 int position = permuteTmp % mod; |
833 permuteTmp = permuteTmp ~/ mod; | 834 permuteTmp = permuteTmp ~/ mod; |
834 while (futures[position] != null) position++; | 835 while (futures[position] != null) position++; |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
987 testType(name, future.whenComplete(() {}), depth - 1); | 988 testType(name, future.whenComplete(() {}), depth - 1); |
988 } | 989 } |
989 } | 990 } |
990 | 991 |
991 for (var value in [42, null]) { | 992 for (var value in [42, null]) { |
992 testType("Future($value)", new Future<int>(() => value)); | 993 testType("Future($value)", new Future<int>(() => value)); |
993 testType("Future.delayed($value)", | 994 testType("Future.delayed($value)", |
994 new Future<int>.delayed(Duration.ZERO, () => value)); | 995 new Future<int>.delayed(Duration.ZERO, () => value)); |
995 testType( | 996 testType( |
996 "Future.microtask($value)", new Future<int>.microtask(() => value)); | 997 "Future.microtask($value)", new Future<int>.microtask(() => value)); |
997 testType("Future.sync($value)", new Future<int>.sync(() => value)); //# 01:
ok | 998 testType( |
998 testType("Future.sync(future($value))", // //# 01:
continued | 999 "Future.sync($value)", new Future<int>.sync(() => value)); // #01: ok |
999 new Future<int>.sync(() => new Future<int>.value(value))); //# 01:
continued | 1000 testType( //# 01: continued |
| 1001 "Future.sync(future($value))", //# 01: continued |
| 1002 new Future<int>.sync(//# 01: continued |
| 1003 () => new Future<int>.value(value))); //# 01: continued |
1000 testType("Future.value($value)", new Future<int>.value(value)); | 1004 testType("Future.value($value)", new Future<int>.value(value)); |
1001 } | 1005 } |
1002 testType("Completer.future", new Completer<int>().future); | 1006 testType("Completer.future", new Completer<int>().future); |
1003 testType("Future.error", new Future<int>.error("ERR")..catchError((_) {})); | 1007 testType("Future.error", new Future<int>.error("ERR")..catchError((_) {})); |
1004 } | 1008 } |
1005 | 1009 |
1006 void testAnyValue() { | 1010 void testAnyValue() { |
1007 asyncStart(); | 1011 asyncStart(); |
1008 var cs = new List.generate(3, (_) => new Completer()); | 1012 var cs = new List.generate(3, (_) => new Completer()); |
1009 var result = Future.any(cs.map((x) => x.future)); | 1013 var result = Future.any(cs.map((x) => x.future)); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 testAnyIgnoreIncomplete(); | 1171 testAnyIgnoreIncomplete(); |
1168 testAnyIgnoreError(); | 1172 testAnyIgnoreError(); |
1169 | 1173 |
1170 testFutureResult(); | 1174 testFutureResult(); |
1171 | 1175 |
1172 asyncEnd(); | 1176 asyncEnd(); |
1173 } | 1177 } |
1174 | 1178 |
1175 /// A well-behaved Future that isn't recognizable as a _Future. | 1179 /// A well-behaved Future that isn't recognizable as a _Future. |
1176 class CustomFuture<T> implements Future<T> { | 1180 class CustomFuture<T> implements Future<T> { |
1177 Future _realFuture; | 1181 Future<T> _realFuture; |
1178 CustomFuture(this._realFuture); | 1182 CustomFuture(this._realFuture); |
1179 Future then(action(result), {Function onError}) => | 1183 Future<S> then<S>(action(T result), {Function onError}) => |
1180 _realFuture.then(action, onError: onError); | 1184 _realFuture.then(action, onError: onError); |
1181 Future catchError(Function onError, {bool test(e)}) => | 1185 Future<T> catchError(Function onError, {bool test(e)}) => |
1182 _realFuture.catchError(onError, test: test); | 1186 _realFuture.catchError(onError, test: test); |
1183 Future whenComplete(action()) => _realFuture.whenComplete(action); | 1187 Future<T> whenComplete(action()) => _realFuture.whenComplete(action); |
1184 Future timeout(Duration timeLimit, {void onTimeout()}) => | 1188 Future<T> timeout(Duration timeLimit, {void onTimeout()}) => |
1185 _realFuture.timeout(timeLimit, onTimeout: onTimeout); | 1189 _realFuture.timeout(timeLimit, onTimeout: onTimeout); |
1186 Stream asStream() => _realFuture.asStream(); | 1190 Stream<T> asStream() => _realFuture.asStream(); |
1187 String toString() => "CustomFuture@${_realFuture.hashCode}"; | 1191 String toString() => "CustomFuture@${_realFuture.hashCode}"; |
1188 int get hashCode => _realFuture.hashCode; | 1192 int get hashCode => _realFuture.hashCode; |
1189 } | 1193 } |
1190 | 1194 |
1191 /// A bad future that throws on every method. | 1195 /// A bad future that throws on every method. |
1192 class BadFuture<T> implements Future<T> { | 1196 class BadFuture<T> implements Future<T> { |
1193 Future then(action(T result), {Function onError}) { | 1197 Future<S> then<S>(action(T result), {Function onError}) { |
1194 throw "then GOTCHA!"; | 1198 throw "then GOTCHA!"; |
1195 } | 1199 } |
1196 | 1200 |
1197 Future catchError(Function onError, {bool test(e)}) { | 1201 Future<T> catchError(Function onError, {bool test(Object e)}) { |
1198 throw "catch GOTCHA!"; | 1202 throw "catch GOTCHA!"; |
1199 } | 1203 } |
1200 | 1204 |
1201 Future whenComplete(action()) { | 1205 Future<T> whenComplete(action()) { |
1202 throw "finally GOTCHA!"; | 1206 throw "finally GOTCHA!"; |
1203 } | 1207 } |
1204 | 1208 |
1205 Stream<T> asStream() { | 1209 Stream<T> asStream() { |
1206 throw "asStream GOTCHA!"; | 1210 throw "asStream GOTCHA!"; |
1207 } | 1211 } |
1208 | 1212 |
1209 Future timeout(Duration duration, {onTimeout()}) { | 1213 Future<T> timeout(Duration duration, {onTimeout()}) { |
1210 throw "timeout GOTCHA!"; | 1214 throw "timeout GOTCHA!"; |
1211 } | 1215 } |
1212 } | 1216 } |
1213 | 1217 |
1214 // An evil future that completes with another future. | 1218 // An evil future that completes with another future. |
1215 class UglyFuture implements Future<dynamic> { | 1219 class UglyFuture implements Future<dynamic> { |
1216 final _result; | 1220 final _result; |
1217 UglyFuture(int badness) | 1221 UglyFuture(int badness) |
1218 : _result = (badness == 0) ? 42 : new UglyFuture(badness - 1); | 1222 : _result = (badness == 0) ? 42 : new UglyFuture(badness - 1); |
1219 Future then(action(value), {onError(error, StackTrace stack)}) { | 1223 Future<S> then<S>(action(value), {Function onError}) { |
1220 var c = new Completer(); | 1224 var c = new Completer(); |
1221 c.complete(new Future.microtask(() => action(_result))); | 1225 c.complete(new Future.microtask(() => action(_result))); |
1222 return c.future; | 1226 return c.future; |
1223 } | 1227 } |
1224 | 1228 |
1225 Future catchError(onError, {test}) => this; // Never an error. | 1229 Future catchError(onError, {test}) => this; // Never an error. |
1226 Future whenComplete(action()) { | 1230 Future whenComplete(action()) { |
1227 return new Future.microtask(action).then((_) => this); | 1231 return new Future.microtask(action).then((_) => this); |
1228 } | 1232 } |
1229 | 1233 |
1230 Stream asStream() { | 1234 Stream asStream() { |
1231 return (new StreamController() | 1235 return (new StreamController() |
1232 ..add(_result) | 1236 ..add(_result) |
1233 ..close()) | 1237 ..close()) |
1234 .stream; | 1238 .stream; |
1235 } | 1239 } |
1236 | 1240 |
1237 Future timeout(Duration duration, {onTimeout()}) { | 1241 Future timeout(Duration duration, {onTimeout()}) { |
1238 return this; | 1242 return this; |
1239 } | 1243 } |
1240 } | 1244 } |
OLD | NEW |