OLD | NEW |
| (Empty) |
1 // Copyright (c) 2015, 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 | |
7 import 'package:async/async.dart'; | |
8 import 'package:test/src/util/cancelable_future.dart'; | |
9 import 'package:test/test.dart'; | |
10 | |
11 void main() { | |
12 group("without being canceled", () { | |
13 var completer; | |
14 setUp(() { | |
15 completer = new CancelableCompleter(expectAsync(() {}, count: 0)); | |
16 }); | |
17 | |
18 test("sends values to the future", () { | |
19 expect(completer.future, completion(equals(1))); | |
20 expect(completer.isCompleted, isFalse); | |
21 completer.complete(1); | |
22 expect(completer.isCompleted, isTrue); | |
23 }); | |
24 | |
25 test("sends errors to the future", () { | |
26 expect(completer.future, throwsA("error")); | |
27 expect(completer.isCompleted, isFalse); | |
28 completer.completeError("error"); | |
29 expect(completer.isCompleted, isTrue); | |
30 }); | |
31 | |
32 test("sends values in a future to the future", () { | |
33 expect(completer.future, completion(equals(1))); | |
34 expect(completer.isCompleted, isFalse); | |
35 completer.complete(new Future.value(1)); | |
36 expect(completer.isCompleted, isTrue); | |
37 }); | |
38 | |
39 test("sends errors in a future to the future", () { | |
40 expect(completer.future, throwsA("error")); | |
41 expect(completer.isCompleted, isFalse); | |
42 completer.complete(new Future.error("error")); | |
43 expect(completer.isCompleted, isTrue); | |
44 }); | |
45 | |
46 group("throws a StateError if completed", () { | |
47 test("successfully twice", () { | |
48 completer.complete(1); | |
49 expect(() => completer.complete(1), throwsStateError); | |
50 }); | |
51 | |
52 test("successfully then unsuccessfully", () { | |
53 completer.complete(1); | |
54 expect(() => completer.completeError("error"), throwsStateError); | |
55 }); | |
56 | |
57 test("unsuccessfully twice", () { | |
58 expect(completer.future, throwsA("error")); | |
59 completer.completeError("error"); | |
60 expect(() => completer.completeError("error"), throwsStateError); | |
61 }); | |
62 | |
63 test("successfully then with a future", () { | |
64 completer.complete(1); | |
65 expect(() => completer.complete(new Completer().future), | |
66 throwsStateError); | |
67 }); | |
68 | |
69 test("with a future then successfully", () { | |
70 completer.complete(new Completer().future); | |
71 expect(() => completer.complete(1), throwsStateError); | |
72 }); | |
73 | |
74 test("with a future twice", () { | |
75 completer.complete(new Completer().future); | |
76 expect(() => completer.complete(new Completer().future), | |
77 throwsStateError); | |
78 }); | |
79 }); | |
80 | |
81 group("CancelableFuture.fromFuture", () { | |
82 test("forwards values", () { | |
83 expect(new CancelableFuture.fromFuture(new Future.value(1)), | |
84 completion(equals(1))); | |
85 }); | |
86 | |
87 test("forwards errors", () { | |
88 expect(new CancelableFuture.fromFuture(new Future.error("error")), | |
89 throwsA("error")); | |
90 }); | |
91 }); | |
92 }); | |
93 | |
94 group("when canceled", () { | |
95 test("causes the future never to fire", () async { | |
96 var completer = new CancelableCompleter(); | |
97 completer.future.whenComplete(expectAsync(() {}, count: 0)); | |
98 completer.future.cancel(); | |
99 | |
100 // Give the future plenty of time to fire if it's going to. | |
101 await flushMicrotasks(); | |
102 completer.complete(); | |
103 await flushMicrotasks(); | |
104 }); | |
105 | |
106 test("fires onCancel", () { | |
107 var canceled = false; | |
108 var completer; | |
109 completer = new CancelableCompleter(expectAsync(() { | |
110 expect(completer.isCanceled, isTrue); | |
111 canceled = true; | |
112 })); | |
113 | |
114 expect(canceled, isFalse); | |
115 expect(completer.isCanceled, isFalse); | |
116 expect(completer.isCompleted, isFalse); | |
117 completer.future.cancel(); | |
118 expect(canceled, isTrue); | |
119 expect(completer.isCanceled, isTrue); | |
120 expect(completer.isCompleted, isFalse); | |
121 }); | |
122 | |
123 test("returns the onCancel future each time cancel is called", () { | |
124 var completer = new CancelableCompleter(expectAsync(() { | |
125 return new Future.value(1); | |
126 })); | |
127 expect(completer.future.cancel(), completion(equals(1))); | |
128 expect(completer.future.cancel(), completion(equals(1))); | |
129 expect(completer.future.cancel(), completion(equals(1))); | |
130 }); | |
131 | |
132 test("returns a future even if onCancel doesn't", () { | |
133 var completer = new CancelableCompleter(expectAsync(() {})); | |
134 expect(completer.future.cancel(), completes); | |
135 }); | |
136 | |
137 test("doesn't call onCancel if the completer has completed", () { | |
138 var completer = new CancelableCompleter(expectAsync(() {}, count: 0)); | |
139 completer.complete(1); | |
140 completer.future.whenComplete(expectAsync(() {}, count: 0)); | |
141 expect(completer.future.cancel(), completes); | |
142 }); | |
143 | |
144 test("does call onCancel if the completer has completed to an unfired " | |
145 "Future", () { | |
146 var completer = new CancelableCompleter(expectAsync(() {})); | |
147 completer.complete(new Completer().future); | |
148 expect(completer.future.cancel(), completes); | |
149 }); | |
150 | |
151 test("doesn't call onCancel if the completer has completed to a fired " | |
152 "Future", () async { | |
153 var completer = new CancelableCompleter(expectAsync(() {}, count: 0)); | |
154 completer.complete(new Future.value(1)); | |
155 await completer.future; | |
156 expect(completer.future.cancel(), completes); | |
157 }); | |
158 | |
159 test("can be completed once after being canceled", () async { | |
160 var completer = new CancelableCompleter(); | |
161 completer.future.whenComplete(expectAsync(() {}, count: 0)); | |
162 await completer.future.cancel(); | |
163 completer.complete(1); | |
164 expect(() => completer.complete(1), throwsStateError); | |
165 }); | |
166 | |
167 test("throws a CancelException along non-canceled branches", () { | |
168 var completer = new CancelableCompleter(); | |
169 expect(completer.future.then((_) {}), throwsCancelException); | |
170 completer.future.then((_) {}).cancel(); | |
171 }); | |
172 | |
173 test("doesn't throw a CancelException further along the canceled chain", | |
174 () async { | |
175 var completer = new CancelableCompleter(); | |
176 completer.future.then((_) {}).whenComplete(expectAsync((_) {}, count: 0)); | |
177 completer.future.cancel(); | |
178 await flushMicrotasks(); | |
179 }); | |
180 }); | |
181 | |
182 group("asStream()", () { | |
183 test("emits a value and then closes", () { | |
184 var completer = new CancelableCompleter(); | |
185 expect(completer.future.asStream().toList(), completion(equals([1]))); | |
186 completer.complete(1); | |
187 }); | |
188 | |
189 test("emits an error and then closes", () { | |
190 var completer = new CancelableCompleter(); | |
191 var queue = new StreamQueue(completer.future.asStream()); | |
192 expect(queue.next, throwsA("error")); | |
193 expect(queue.hasNext, completion(isFalse)); | |
194 completer.completeError("error"); | |
195 }); | |
196 | |
197 test("cancels the completer when the subscription is canceled", () { | |
198 var completer = new CancelableCompleter(expectAsync(() {})); | |
199 var sub = completer.future.asStream() | |
200 .listen(expectAsync((_) {}, count: 0)); | |
201 expect(completer.future, throwsCancelException); | |
202 sub.cancel(); | |
203 expect(completer.isCanceled, isTrue); | |
204 }); | |
205 }); | |
206 | |
207 group("timeout()", () { | |
208 test("emits a value if one arrives before timeout", () { | |
209 var completer = new CancelableCompleter(); | |
210 expect( | |
211 completer.future.timeout( | |
212 new Duration(hours: 1), | |
213 onTimeout: expectAsync(() {}, count: 0)), | |
214 completion(equals(1))); | |
215 completer.complete(1); | |
216 }); | |
217 | |
218 test("emits an error if one arrives before timeout", () { | |
219 var completer = new CancelableCompleter(); | |
220 expect( | |
221 completer.future.timeout( | |
222 new Duration(hours: 1), | |
223 onTimeout: expectAsync(() {}, count: 0)), | |
224 throwsA("error")); | |
225 completer.completeError("error"); | |
226 }); | |
227 | |
228 test("cancels the completer when the future times out", () async { | |
229 var completer = new CancelableCompleter(expectAsync(() {})); | |
230 expect(completer.future.timeout(Duration.ZERO), | |
231 throwsA(new isInstanceOf<TimeoutException>())); | |
232 expect(completer.future, throwsCancelException); | |
233 await flushMicrotasks(); | |
234 expect(completer.isCanceled, isTrue); | |
235 }); | |
236 | |
237 test("runs the user's onTimeout function when the future times out", | |
238 () async { | |
239 var completer = new CancelableCompleter(expectAsync(() {})); | |
240 expect( | |
241 completer.future.timeout( | |
242 Duration.ZERO, | |
243 onTimeout: expectAsync(() => 1)), | |
244 completion(equals(1))); | |
245 expect(completer.future, throwsCancelException); | |
246 await flushMicrotasks(); | |
247 expect(completer.isCanceled, isTrue); | |
248 }); | |
249 }); | |
250 } | |
251 | |
252 const Matcher throwsCancelException = | |
253 const Throws(const isInstanceOf<CancelException>()); | |
254 | |
255 Future flushMicrotasks() => new Future.delayed(Duration.ZERO); | |
OLD | NEW |