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 |
11 const Duration MS = const Duration(milliseconds: 1); | 11 const Duration MS = const Duration(milliseconds: 1); |
12 | 12 |
13 void testValue() { | 13 void testValue() { |
14 final future = new Future<String>.value("42"); | 14 final future = new Future<String>.value("42"); |
15 asyncStart(); | 15 asyncStart(); |
16 future.then((x) { | 16 future.then((x) { |
17 Expect.equals("42", x); | 17 Expect.equals("42", x); |
18 asyncEnd(); | 18 asyncEnd(); |
19 }); | 19 }); |
20 } | 20 } |
21 | 21 |
22 void testSync() { | 22 void testSync() { |
23 compare(func) { | 23 compare(func) { |
24 // Compare the results of the following two futures. | 24 // Compare the results of the following two futures. |
25 Future f1 = new Future.sync(func); | 25 Future f1 = new Future.sync(func); |
26 Future f2 = new Future.value().then((_) => func()); | 26 Future f2 = new Future.value().then((_) => func()); |
27 f2.catchError((_){}); // I'll get the error later. | 27 f2.catchError((_) {}); // I'll get the error later. |
28 f1.then((v1) { f2.then((v2) { Expect.equals(v1, v2); }); }, | 28 f1.then((v1) { |
29 onError: (e1) { | 29 f2.then((v2) { |
30 f2.then((_) { Expect.fail("Expected error"); }, | 30 Expect.equals(v1, v2); |
31 onError: (e2) { | 31 }); |
32 Expect.equals(e1, e2); | 32 }, onError: (e1) { |
33 }); | 33 f2.then((_) { |
34 }); | 34 Expect.fail("Expected error"); |
| 35 }, onError: (e2) { |
| 36 Expect.equals(e1, e2); |
| 37 }); |
| 38 }); |
35 } | 39 } |
| 40 |
36 Future val = new Future.value(42); | 41 Future val = new Future.value(42); |
37 Future err1 = new Future.error("Error")..catchError((_){}); | 42 Future err1 = new Future.error("Error")..catchError((_) {}); |
38 try { | 43 try { |
39 throw new List(0); | 44 throw new List(0); |
40 } catch (e, st) { | 45 } catch (e, st) { |
41 Future err2 = new Future.error(e, st)..catchError((_){}); | 46 Future err2 = new Future.error(e, st)..catchError((_) {}); |
42 } | 47 } |
43 compare(() => 42); | 48 compare(() => 42); |
44 compare(() => val); | 49 compare(() => val); |
45 compare(() { throw "Flif"; }); | 50 compare(() { |
| 51 throw "Flif"; |
| 52 }); |
46 compare(() => err1); | 53 compare(() => err1); |
47 bool hasExecuted = false; | 54 bool hasExecuted = false; |
48 compare(() { | 55 compare(() { |
49 hasExecuted = true; | 56 hasExecuted = true; |
50 return 499; | 57 return 499; |
51 }); | 58 }); |
52 Expect.isTrue(hasExecuted); | 59 Expect.isTrue(hasExecuted); |
53 } | 60 } |
54 | 61 |
55 void testNeverComplete() { | 62 void testNeverComplete() { |
(...skipping 16 matching lines...) Expand all Loading... |
72 | 79 |
73 // Tests for [then] | 80 // Tests for [then] |
74 | 81 |
75 void testCompleteWithSuccessHandlerBeforeComplete() { | 82 void testCompleteWithSuccessHandlerBeforeComplete() { |
76 final completer = new Completer<int>(); | 83 final completer = new Completer<int>(); |
77 final future = completer.future; | 84 final future = completer.future; |
78 | 85 |
79 int after; | 86 int after; |
80 | 87 |
81 asyncStart(); | 88 asyncStart(); |
82 future.then((int v) { after = v; }) | 89 future.then((int v) { |
83 .then((_) { | 90 after = v; |
84 Expect.equals(3, after); | 91 }).then((_) { |
85 asyncEnd(); | 92 Expect.equals(3, after); |
86 }); | 93 asyncEnd(); |
| 94 }); |
87 | 95 |
88 completer.complete(3); | 96 completer.complete(3); |
89 Expect.isNull(after); | 97 Expect.isNull(after); |
90 } | 98 } |
91 | 99 |
92 void testCompleteWithSuccessHandlerAfterComplete() { | 100 void testCompleteWithSuccessHandlerAfterComplete() { |
93 final completer = new Completer<int>(); | 101 final completer = new Completer<int>(); |
94 final future = completer.future; | 102 final future = completer.future; |
95 | 103 |
96 int after; | 104 int after; |
97 completer.complete(3); | 105 completer.complete(3); |
98 Expect.isNull(after); | 106 Expect.isNull(after); |
99 | 107 |
100 asyncStart(); | 108 asyncStart(); |
101 future.then((int v) { after = v; }) | 109 future.then((int v) { |
102 .then((_) { | 110 after = v; |
103 Expect.equals(3, after); | 111 }).then((_) { |
104 asyncEnd(); | 112 Expect.equals(3, after); |
105 }); | 113 asyncEnd(); |
| 114 }); |
106 } | 115 } |
107 | 116 |
108 void testCompleteManySuccessHandlers() { | 117 void testCompleteManySuccessHandlers() { |
109 final completer = new Completer<int>(); | 118 final completer = new Completer<int>(); |
110 final future = completer.future; | 119 final future = completer.future; |
111 int before; | 120 int before; |
112 int after1; | 121 int after1; |
113 int after2; | 122 int after2; |
114 | 123 |
115 var futures = []; | 124 var futures = []; |
116 futures.add(future.then((int v) { before = v; })); | 125 futures.add(future.then((int v) { |
| 126 before = v; |
| 127 })); |
117 completer.complete(3); | 128 completer.complete(3); |
118 futures.add(future.then((int v) { after1 = v; })); | 129 futures.add(future.then((int v) { |
119 futures.add(future.then((int v) { after2 = v; })); | 130 after1 = v; |
| 131 })); |
| 132 futures.add(future.then((int v) { |
| 133 after2 = v; |
| 134 })); |
120 | 135 |
121 asyncStart(); | 136 asyncStart(); |
122 Future.wait(futures).then((_) { | 137 Future.wait(futures).then((_) { |
123 Expect.equals(3, before); | 138 Expect.equals(3, before); |
124 Expect.equals(3, after1); | 139 Expect.equals(3, after1); |
125 Expect.equals(3, after2); | 140 Expect.equals(3, after2); |
126 asyncEnd(); | 141 asyncEnd(); |
127 }); | 142 }); |
128 } | 143 } |
129 | 144 |
130 // Tests for [catchError] | 145 // Tests for [catchError] |
131 | 146 |
132 void testException() { | 147 void testException() { |
133 final completer = new Completer<int>(); | 148 final completer = new Completer<int>(); |
134 final future = completer.future; | 149 final future = completer.future; |
135 final ex = new Exception(); | 150 final ex = new Exception(); |
136 | 151 |
137 asyncStart(); | 152 asyncStart(); |
138 future | 153 future.then((v) { |
139 .then((v) { throw "Value not expected"; }) | 154 throw "Value not expected"; |
140 .catchError((error) { | 155 }).catchError((error) { |
141 Expect.equals(error, ex); | 156 Expect.equals(error, ex); |
142 asyncEnd(); | 157 asyncEnd(); |
143 }, test: (e) => e == ex); | 158 }, test: (e) => e == ex); |
144 completer.completeError(ex); | 159 completer.completeError(ex); |
145 } | 160 } |
146 | 161 |
147 void testExceptionHandler() { | 162 void testExceptionHandler() { |
148 final completer = new Completer<int>(); | 163 final completer = new Completer<int>(); |
149 final future = completer.future; | 164 final future = completer.future; |
150 final ex = new Exception(); | 165 final ex = new Exception(); |
151 | 166 |
152 var ex2; | 167 var ex2; |
153 var done = future.catchError((error) { ex2 = error; }); | 168 var done = future.catchError((error) { |
| 169 ex2 = error; |
| 170 }); |
154 | 171 |
155 Expect.isFalse(completer.isCompleted); | 172 Expect.isFalse(completer.isCompleted); |
156 completer.completeError(ex); | 173 completer.completeError(ex); |
157 Expect.isTrue(completer.isCompleted); | 174 Expect.isTrue(completer.isCompleted); |
158 | 175 |
159 asyncStart(); | 176 asyncStart(); |
160 done.then((_) { | 177 done.then((_) { |
161 Expect.equals(ex, ex2); | 178 Expect.equals(ex, ex2); |
162 asyncEnd(); | 179 asyncEnd(); |
163 }); | 180 }); |
164 } | 181 } |
165 | 182 |
166 void testExceptionHandlerReturnsTrue() { | 183 void testExceptionHandlerReturnsTrue() { |
167 final completer = new Completer<int>(); | 184 final completer = new Completer<int>(); |
168 final future = completer.future; | 185 final future = completer.future; |
169 final ex = new Exception(); | 186 final ex = new Exception(); |
170 | 187 |
171 bool reached = false; | 188 bool reached = false; |
172 future.catchError((e) { }); | 189 future.catchError((e) {}); |
173 future.catchError((e) { reached = true; }, test: (e) => false) | 190 future.catchError((e) { |
174 .catchError((e) {}); | 191 reached = true; |
| 192 }, test: (e) => false).catchError((e) {}); |
175 Expect.isFalse(completer.isCompleted); | 193 Expect.isFalse(completer.isCompleted); |
176 completer.completeError(ex); | 194 completer.completeError(ex); |
177 Expect.isTrue(completer.isCompleted); | 195 Expect.isTrue(completer.isCompleted); |
178 Expect.isFalse(reached); | 196 Expect.isFalse(reached); |
179 } | 197 } |
180 | 198 |
181 void testExceptionHandlerReturnsTrue2() { | 199 void testExceptionHandlerReturnsTrue2() { |
182 final completer = new Completer<int>(); | 200 final completer = new Completer<int>(); |
183 final future = completer.future; | 201 final future = completer.future; |
184 final ex = new Exception(); | 202 final ex = new Exception(); |
185 | 203 |
186 bool reached = false; | 204 bool reached = false; |
187 var done = future | 205 var done = future.catchError((e) {}, test: (e) => false).catchError((e) { |
188 .catchError((e) { }, test: (e) => false) | 206 reached = true; |
189 .catchError((e) { reached = true; }); | 207 }); |
190 completer.completeError(ex); | 208 completer.completeError(ex); |
191 | 209 |
192 asyncStart(); | 210 asyncStart(); |
193 done.then((_) { | 211 done.then((_) { |
194 Expect.isTrue(reached); | 212 Expect.isTrue(reached); |
195 asyncEnd(); | 213 asyncEnd(); |
196 }); | 214 }); |
197 } | 215 } |
198 | 216 |
199 void testExceptionHandlerReturnsFalse() { | 217 void testExceptionHandlerReturnsFalse() { |
200 final completer = new Completer<int>(); | 218 final completer = new Completer<int>(); |
201 final future = completer.future; | 219 final future = completer.future; |
202 final ex = new Exception(); | 220 final ex = new Exception(); |
203 | 221 |
204 bool reached = false; | 222 bool reached = false; |
205 | 223 |
206 future.catchError((e) { }); | 224 future.catchError((e) {}); |
207 | 225 |
208 future.catchError((e) { reached = true; }, test: (e) => false) | 226 future.catchError((e) { |
209 .catchError((e) { }); | 227 reached = true; |
| 228 }, test: (e) => false).catchError((e) {}); |
210 | 229 |
211 completer.completeError(ex); | 230 completer.completeError(ex); |
212 | 231 |
213 Expect.isFalse(reached); | 232 Expect.isFalse(reached); |
214 } | 233 } |
215 | 234 |
216 void testFutureAsStreamCompleteAfter() { | 235 void testFutureAsStreamCompleteAfter() { |
217 var completer = new Completer(); | 236 var completer = new Completer(); |
218 bool gotValue = false; | 237 bool gotValue = false; |
219 asyncStart(); | 238 asyncStart(); |
220 completer.future.asStream().listen( | 239 completer.future.asStream().listen((data) { |
221 (data) { | 240 Expect.isFalse(gotValue); |
222 Expect.isFalse(gotValue); | 241 gotValue = true; |
223 gotValue = true; | 242 Expect.equals("value", data); |
224 Expect.equals("value", data); | 243 }, onDone: () { |
225 }, | 244 Expect.isTrue(gotValue); |
226 onDone: () { | 245 asyncEnd(); |
227 Expect.isTrue(gotValue); | 246 }); |
228 asyncEnd(); | |
229 }); | |
230 completer.complete("value"); | 247 completer.complete("value"); |
231 } | 248 } |
232 | 249 |
233 void testFutureAsStreamCompleteBefore() { | 250 void testFutureAsStreamCompleteBefore() { |
234 var completer = new Completer(); | 251 var completer = new Completer(); |
235 bool gotValue = false; | 252 bool gotValue = false; |
236 asyncStart(); | 253 asyncStart(); |
237 completer.complete("value"); | 254 completer.complete("value"); |
238 completer.future.asStream().listen( | 255 completer.future.asStream().listen((data) { |
239 (data) { | 256 Expect.isFalse(gotValue); |
240 Expect.isFalse(gotValue); | 257 gotValue = true; |
241 gotValue = true; | 258 Expect.equals("value", data); |
242 Expect.equals("value", data); | 259 }, onDone: () { |
243 }, | 260 Expect.isTrue(gotValue); |
244 onDone: () { | 261 asyncEnd(); |
245 Expect.isTrue(gotValue); | 262 }); |
246 asyncEnd(); | |
247 }); | |
248 } | 263 } |
249 | 264 |
250 void testFutureAsStreamCompleteImmediate() { | 265 void testFutureAsStreamCompleteImmediate() { |
251 bool gotValue = false; | 266 bool gotValue = false; |
252 asyncStart(); | 267 asyncStart(); |
253 new Future.value("value").asStream().listen( | 268 new Future.value("value").asStream().listen((data) { |
254 (data) { | 269 Expect.isFalse(gotValue); |
255 Expect.isFalse(gotValue); | 270 gotValue = true; |
256 gotValue = true; | 271 Expect.equals("value", data); |
257 Expect.equals("value", data); | 272 }, onDone: () { |
258 }, | 273 Expect.isTrue(gotValue); |
259 onDone: () { | 274 asyncEnd(); |
260 Expect.isTrue(gotValue); | 275 }); |
261 asyncEnd(); | |
262 }); | |
263 } | 276 } |
264 | 277 |
265 void testFutureAsStreamCompleteErrorAfter() { | 278 void testFutureAsStreamCompleteErrorAfter() { |
266 var completer = new Completer(); | 279 var completer = new Completer(); |
267 bool gotError = false; | 280 bool gotError = false; |
268 asyncStart(); | 281 asyncStart(); |
269 completer.future.asStream().listen( | 282 completer.future.asStream().listen((data) { |
270 (data) { | 283 Expect.fail("Unexpected data"); |
271 Expect.fail("Unexpected data"); | 284 }, onError: (error) { |
272 }, | 285 Expect.isFalse(gotError); |
273 onError: (error) { | 286 gotError = true; |
274 Expect.isFalse(gotError); | 287 Expect.equals("error", error); |
275 gotError = true; | 288 }, onDone: () { |
276 Expect.equals("error", error); | 289 Expect.isTrue(gotError); |
277 }, | 290 asyncEnd(); |
278 onDone: () { | 291 }); |
279 Expect.isTrue(gotError); | |
280 asyncEnd(); | |
281 }); | |
282 completer.completeError("error"); | 292 completer.completeError("error"); |
283 } | 293 } |
284 | 294 |
285 void testFutureAsStreamWrapper() { | 295 void testFutureAsStreamWrapper() { |
286 var completer = new Completer(); | 296 var completer = new Completer(); |
287 bool gotValue = false; | 297 bool gotValue = false; |
288 asyncStart(); | 298 asyncStart(); |
289 completer.complete("value"); | 299 completer.complete("value"); |
290 completer.future | 300 completer.future |
291 .catchError((_) { throw "not possible"; }) // Returns a future wrapper. | 301 .catchError((_) { |
292 .asStream().listen( | 302 throw "not possible"; |
293 (data) { | 303 }) // Returns a future wrapper. |
294 Expect.isFalse(gotValue); | 304 .asStream() |
295 gotValue = true; | 305 .listen((data) { |
296 Expect.equals("value", data); | 306 Expect.isFalse(gotValue); |
297 }, | 307 gotValue = true; |
298 onDone: () { | 308 Expect.equals("value", data); |
299 Expect.isTrue(gotValue); | 309 }, onDone: () { |
300 asyncEnd(); | 310 Expect.isTrue(gotValue); |
301 }); | 311 asyncEnd(); |
| 312 }); |
302 } | 313 } |
303 | 314 |
304 void testFutureWhenCompleteValue() { | 315 void testFutureWhenCompleteValue() { |
305 asyncStart(); | 316 asyncStart(); |
306 int counter = 2; | 317 int counter = 2; |
307 countDown() { | 318 countDown() { |
308 if (--counter == 0) asyncEnd(); | 319 if (--counter == 0) asyncEnd(); |
309 } | 320 } |
| 321 |
310 var completer = new Completer(); | 322 var completer = new Completer(); |
311 Future future = completer.future; | 323 Future future = completer.future; |
312 Future later = future.whenComplete(countDown); | 324 Future later = future.whenComplete(countDown); |
313 later.then((v) { | 325 later.then((v) { |
314 Expect.equals(42, v); | 326 Expect.equals(42, v); |
315 countDown(); | 327 countDown(); |
316 }); | 328 }); |
317 completer.complete(42); | 329 completer.complete(42); |
318 } | 330 } |
319 | 331 |
320 void testFutureWhenCompleteError() { | 332 void testFutureWhenCompleteError() { |
321 asyncStart(); | 333 asyncStart(); |
322 int counter = 2; | 334 int counter = 2; |
323 countDown() { | 335 countDown() { |
324 if (--counter == 0) asyncEnd(); | 336 if (--counter == 0) asyncEnd(); |
325 } | 337 } |
| 338 |
326 var completer = new Completer(); | 339 var completer = new Completer(); |
327 Future future = completer.future; | 340 Future future = completer.future; |
328 Future later = future.whenComplete(countDown); | 341 Future later = future.whenComplete(countDown); |
329 later.catchError((error) { | 342 later.catchError((error) { |
330 Expect.equals("error", error); | 343 Expect.equals("error", error); |
331 countDown(); | 344 countDown(); |
332 }); | 345 }); |
333 completer.completeError("error"); | 346 completer.completeError("error"); |
334 } | 347 } |
335 | 348 |
336 void testFutureWhenCompleteValueNewError() { | 349 void testFutureWhenCompleteValueNewError() { |
337 asyncStart(); | 350 asyncStart(); |
338 int counter = 2; | 351 int counter = 2; |
339 countDown() { | 352 countDown() { |
340 if (--counter == 0) asyncEnd(); | 353 if (--counter == 0) asyncEnd(); |
341 } | 354 } |
| 355 |
342 var completer = new Completer(); | 356 var completer = new Completer(); |
343 Future future = completer.future; | 357 Future future = completer.future; |
344 Future later = future.whenComplete(() { | 358 Future later = future.whenComplete(() { |
345 countDown(); | 359 countDown(); |
346 throw "new error"; | 360 throw "new error"; |
347 }); | 361 }); |
348 later.catchError((error) { | 362 later.catchError((error) { |
349 Expect.equals("new error", error); | 363 Expect.equals("new error", error); |
350 countDown(); | 364 countDown(); |
351 }); | 365 }); |
352 completer.complete(42); | 366 completer.complete(42); |
353 } | 367 } |
354 | 368 |
355 void testFutureWhenCompleteErrorNewError() { | 369 void testFutureWhenCompleteErrorNewError() { |
356 asyncStart(); | 370 asyncStart(); |
357 int counter = 2; | 371 int counter = 2; |
358 countDown() { | 372 countDown() { |
359 if (--counter == 0) asyncEnd(); | 373 if (--counter == 0) asyncEnd(); |
360 } | 374 } |
| 375 |
361 var completer = new Completer(); | 376 var completer = new Completer(); |
362 Future future = completer.future; | 377 Future future = completer.future; |
363 Future later = future.whenComplete(() { | 378 Future later = future.whenComplete(() { |
364 countDown(); | 379 countDown(); |
365 throw "new error"; | 380 throw "new error"; |
366 }); | 381 }); |
367 later.catchError((error) { | 382 later.catchError((error) { |
368 Expect.equals("new error", error); | 383 Expect.equals("new error", error); |
369 countDown(); | 384 countDown(); |
370 }); | 385 }); |
371 completer.completeError("error"); | 386 completer.completeError("error"); |
372 } | 387 } |
373 | 388 |
374 void testFutureWhenCompletePreValue() { | 389 void testFutureWhenCompletePreValue() { |
375 asyncStart(); | 390 asyncStart(); |
376 int counter = 2; | 391 int counter = 2; |
377 countDown() { | 392 countDown() { |
378 if (--counter == 0) asyncEnd(); | 393 if (--counter == 0) asyncEnd(); |
379 } | 394 } |
| 395 |
380 var completer = new Completer(); | 396 var completer = new Completer(); |
381 Future future = completer.future; | 397 Future future = completer.future; |
382 completer.complete(42); | 398 completer.complete(42); |
383 Timer.run(() { | 399 Timer.run(() { |
384 Future later = future.whenComplete(countDown); | 400 Future later = future.whenComplete(countDown); |
385 later.then((v) { | 401 later.then((v) { |
386 Expect.equals(42, v); | 402 Expect.equals(42, v); |
387 countDown(); | 403 countDown(); |
388 }); | 404 }); |
389 }); | 405 }); |
390 } | 406 } |
391 | 407 |
392 void testFutureWhenValueFutureValue() { | 408 void testFutureWhenValueFutureValue() { |
393 | |
394 asyncStart(); | 409 asyncStart(); |
395 int counter = 3; | 410 int counter = 3; |
396 countDown(int expect) { | 411 countDown(int expect) { |
397 Expect.equals(expect, counter); | 412 Expect.equals(expect, counter); |
398 if (--counter == 0) asyncEnd(); | 413 if (--counter == 0) asyncEnd(); |
399 } | 414 } |
| 415 |
400 var completer = new Completer(); | 416 var completer = new Completer(); |
401 completer.future.whenComplete(() { | 417 completer.future.whenComplete(() { |
402 countDown(3); | 418 countDown(3); |
403 var completer2 = new Completer(); | 419 var completer2 = new Completer(); |
404 new Timer(MS * 10, () { | 420 new Timer(MS * 10, () { |
405 countDown(2); | 421 countDown(2); |
406 completer2.complete(37); | 422 completer2.complete(37); |
407 }); | 423 }); |
408 return completer2.future; | 424 return completer2.future; |
409 }).then((v) { | 425 }).then((v) { |
410 Expect.equals(42, v); | 426 Expect.equals(42, v); |
411 countDown(1); | 427 countDown(1); |
412 }); | 428 }); |
413 | 429 |
414 completer.complete(42); | 430 completer.complete(42); |
415 } | 431 } |
416 | 432 |
417 void testFutureWhenValueFutureError() { | 433 void testFutureWhenValueFutureError() { |
418 asyncStart(); | 434 asyncStart(); |
419 int counter = 3; | 435 int counter = 3; |
420 countDown(int expect) { | 436 countDown(int expect) { |
421 Expect.equals(expect, counter); | 437 Expect.equals(expect, counter); |
422 if (--counter == 0) asyncEnd(); | 438 if (--counter == 0) asyncEnd(); |
423 } | 439 } |
| 440 |
424 var completer = new Completer(); | 441 var completer = new Completer(); |
425 completer.future.whenComplete(() { | 442 completer.future.whenComplete(() { |
426 countDown(3); | 443 countDown(3); |
427 var completer2 = new Completer(); | 444 var completer2 = new Completer(); |
428 new Timer(MS * 10, () { | 445 new Timer(MS * 10, () { |
429 countDown(2); | 446 countDown(2); |
430 completer2.completeError("Fail"); | 447 completer2.completeError("Fail"); |
431 }); | 448 }); |
432 return completer2.future; | 449 return completer2.future; |
433 }).then((v) { | 450 }).then((v) { |
434 Expect.fail("should fail async"); | 451 Expect.fail("should fail async"); |
435 }, onError: (error) { | 452 }, onError: (error) { |
436 Expect.equals("Fail", error); | 453 Expect.equals("Fail", error); |
437 countDown(1); | 454 countDown(1); |
438 }); | 455 }); |
439 | 456 |
440 completer.complete(42); | 457 completer.complete(42); |
441 } | 458 } |
442 | 459 |
443 void testFutureWhenErrorFutureValue() { | 460 void testFutureWhenErrorFutureValue() { |
444 asyncStart(); | 461 asyncStart(); |
445 int counter = 3; | 462 int counter = 3; |
446 countDown(int expect) { | 463 countDown(int expect) { |
447 Expect.equals(expect, counter); | 464 Expect.equals(expect, counter); |
448 if (--counter == 0) asyncEnd(); | 465 if (--counter == 0) asyncEnd(); |
449 } | 466 } |
| 467 |
450 var completer = new Completer(); | 468 var completer = new Completer(); |
451 completer.future.whenComplete(() { | 469 completer.future.whenComplete(() { |
452 countDown(3); | 470 countDown(3); |
453 var completer2 = new Completer(); | 471 var completer2 = new Completer(); |
454 new Timer(MS * 10, () { | 472 new Timer(MS * 10, () { |
455 countDown(2); | 473 countDown(2); |
456 completer2.complete(37); | 474 completer2.complete(37); |
457 }); | 475 }); |
458 return completer2.future; | 476 return completer2.future; |
459 }).then((v) { | 477 }).then((v) { |
460 Expect.fail("should fail async"); | 478 Expect.fail("should fail async"); |
461 }, onError: (error) { | 479 }, onError: (error) { |
462 Expect.equals("Error", error); | 480 Expect.equals("Error", error); |
463 countDown(1); | 481 countDown(1); |
464 }); | 482 }); |
465 | 483 |
466 completer.completeError("Error"); | 484 completer.completeError("Error"); |
467 } | 485 } |
468 | 486 |
469 void testFutureWhenErrorFutureError() { | 487 void testFutureWhenErrorFutureError() { |
470 asyncStart(); | 488 asyncStart(); |
471 int counter = 3; | 489 int counter = 3; |
472 countDown(int expect) { | 490 countDown(int expect) { |
473 Expect.equals(expect, counter); | 491 Expect.equals(expect, counter); |
474 if (--counter == 0) asyncEnd(); | 492 if (--counter == 0) asyncEnd(); |
475 } | 493 } |
| 494 |
476 var completer = new Completer(); | 495 var completer = new Completer(); |
477 completer.future.whenComplete(() { | 496 completer.future.whenComplete(() { |
478 countDown(3); | 497 countDown(3); |
479 var completer2 = new Completer(); | 498 var completer2 = new Completer(); |
480 new Timer(MS * 10, () { | 499 new Timer(MS * 10, () { |
481 countDown(2); | 500 countDown(2); |
482 completer2.completeError("Fail"); | 501 completer2.completeError("Fail"); |
483 }); | 502 }); |
484 return completer2.future; | 503 return completer2.future; |
485 }).then((v) { | 504 }).then((v) { |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 asyncEnd(); | 703 asyncEnd(); |
685 }); | 704 }); |
686 completer.completeError(null); | 705 completer.completeError(null); |
687 } | 706 } |
688 | 707 |
689 void testChainedFutureValue() { | 708 void testChainedFutureValue() { |
690 final completer = new Completer(); | 709 final completer = new Completer(); |
691 final future = completer.future; | 710 final future = completer.future; |
692 asyncStart(); | 711 asyncStart(); |
693 | 712 |
694 future.then((v) => new Future.value(v * 2)) | 713 future.then((v) => new Future.value(v * 2)).then((v) { |
695 .then((v) { | 714 Expect.equals(42, v); |
696 Expect.equals(42, v); | 715 asyncEnd(); |
697 asyncEnd(); | 716 }); |
698 }); | |
699 completer.complete(21); | 717 completer.complete(21); |
700 } | 718 } |
701 | 719 |
702 void testChainedFutureValueDelay() { | 720 void testChainedFutureValueDelay() { |
703 final completer = new Completer(); | 721 final completer = new Completer(); |
704 final future = completer.future; | 722 final future = completer.future; |
705 asyncStart(); | 723 asyncStart(); |
706 | 724 |
707 future.then((v) => new Future.delayed(const Duration(milliseconds: 10), | 725 future |
708 () => v * 2)) | 726 .then((v) => |
709 .then((v) { | 727 new Future.delayed(const Duration(milliseconds: 10), () => v * 2)) |
710 Expect.equals(42, v); | 728 .then((v) { |
711 asyncEnd(); | 729 Expect.equals(42, v); |
712 }); | 730 asyncEnd(); |
| 731 }); |
713 completer.complete(21); | 732 completer.complete(21); |
714 } | 733 } |
715 | 734 |
716 void testChainedFutureValue2Delay() { | 735 void testChainedFutureValue2Delay() { |
717 asyncStart(); | 736 asyncStart(); |
718 | 737 |
719 new Future.delayed(const Duration(milliseconds: 10)) | 738 new Future.delayed(const Duration(milliseconds: 10)).then((v) { |
720 .then((v) { | 739 Expect.isNull(v); |
721 Expect.isNull(v); | 740 asyncEnd(); |
722 asyncEnd(); | 741 }); |
723 }); | |
724 } | 742 } |
725 | 743 |
726 void testChainedFutureError() { | 744 void testChainedFutureError() { |
727 final completer = new Completer(); | 745 final completer = new Completer(); |
728 final future = completer.future; | 746 final future = completer.future; |
729 asyncStart(); | 747 asyncStart(); |
730 | 748 |
731 future.then((v) => new Future.error("Fehler")) | 749 future.then((v) => new Future.error("Fehler")).then((v) { |
732 .then((v) { Expect.fail("unreachable!"); }, onError: (error) { | 750 Expect.fail("unreachable!"); |
733 Expect.equals("Fehler", error); | 751 }, onError: (error) { |
734 asyncEnd(); | 752 Expect.equals("Fehler", error); |
735 }); | 753 asyncEnd(); |
| 754 }); |
736 completer.complete(21); | 755 completer.complete(21); |
737 } | 756 } |
738 | 757 |
739 void testSyncFuture_i13368() { | 758 void testSyncFuture_i13368() { |
740 asyncStart(); | 759 asyncStart(); |
741 | 760 |
742 final future = new Future<int>.sync(() { | 761 final future = new Future<int>.sync(() { |
743 return new Future<int>.value(42); | 762 return new Future<int>.value(42); |
744 }); | 763 }); |
745 | 764 |
746 future.then((int val) { | 765 future.then((int val) { |
747 Expect.equals(val, 42); | 766 Expect.equals(val, 42); |
748 asyncEnd(); | 767 asyncEnd(); |
749 }); | 768 }); |
750 } | 769 } |
751 | 770 |
752 void testWaitCleanUp() { | 771 void testWaitCleanUp() { |
753 asyncStart(); | 772 asyncStart(); |
754 // Creates three futures with different completion times, and where some fail. | 773 // Creates three futures with different completion times, and where some fail. |
755 // The `mask` specifies which futures fail (values 1-7), | 774 // The `mask` specifies which futures fail (values 1-7), |
756 // and `permute` defines the order of completion. values 0-5. | 775 // and `permute` defines the order of completion. values 0-5. |
757 void doTest(int mask, int permute) { | 776 void doTest(int mask, int permute) { |
758 asyncStart(); | 777 asyncStart(); |
759 String stringId = "waitCleanup-$mask-$permute"; | 778 String stringId = "waitCleanup-$mask-$permute"; |
760 List futures = new List(3); | 779 List futures = new List(3); |
761 List cleanup = new List(3); | 780 List cleanup = new List(3); |
762 int permuteTmp = permute; | 781 int permuteTmp = permute; |
763 for (int i = 0; i < 3; i++) { | 782 for (int i = 0; i < 3; i++) { |
764 bool throws = (mask & (1 << i)) != 0; | 783 bool throws = (mask & (1 << i)) != 0; |
765 var future = new Future.delayed( | 784 var future = new Future.delayed(new Duration(milliseconds: 100 * (i + 1)), |
766 new Duration(milliseconds: 100 * (i + 1)), | |
767 () => (throws ? throw "Error $i($mask-$permute)" : i)); | 785 () => (throws ? throw "Error $i($mask-$permute)" : i)); |
768 int mod = 3 - i; | 786 int mod = 3 - i; |
769 int position = permuteTmp % mod; | 787 int position = permuteTmp % mod; |
770 permuteTmp = permuteTmp ~/ mod; | 788 permuteTmp = permuteTmp ~/ mod; |
771 while (futures[position] != null) position++; | 789 while (futures[position] != null) position++; |
772 futures[position] = future; | 790 futures[position] = future; |
773 cleanup[i] = throws; | 791 cleanup[i] = throws; |
774 } | 792 } |
775 void cleanUp(index) { | 793 void cleanUp(index) { |
776 Expect.isFalse(cleanup[index]); | 794 Expect.isFalse(cleanup[index]); |
777 cleanup[index] = true; | 795 cleanup[index] = true; |
778 } | 796 } |
779 Future.wait(futures, cleanUp: cleanUp) | 797 |
780 .then((_) { Expect.fail("No error: $stringId"); }, | 798 Future.wait(futures, cleanUp: cleanUp).then((_) { |
781 onError: (e, s) { | 799 Expect.fail("No error: $stringId"); |
782 Expect.listEquals([true, true, true], cleanup); | 800 }, onError: (e, s) { |
783 asyncEnd(); | 801 Expect.listEquals([true, true, true], cleanup); |
784 }); | 802 asyncEnd(); |
| 803 }); |
785 } | 804 } |
786 | 805 |
787 for (int i = 1; i < 8; i++) { | 806 for (int i = 1; i < 8; i++) { |
788 for (int j = 0; j < 6; j++) { | 807 for (int j = 0; j < 6; j++) { |
789 doTest(i, j); | 808 doTest(i, j); |
790 } | 809 } |
791 } | 810 } |
792 asyncEnd(); | 811 asyncEnd(); |
793 } | 812 } |
794 | 813 |
795 void testWaitCleanUpEager() { | 814 void testWaitCleanUpEager() { |
796 asyncStart(); | 815 asyncStart(); |
797 // Creates three futures with different completion times, and where some fail. | 816 // Creates three futures with different completion times, and where some fail. |
798 // The `mask` specifies which futures fail (values 1-7), | 817 // The `mask` specifies which futures fail (values 1-7), |
799 // and `permute` defines the order of completion. values 0-5. | 818 // and `permute` defines the order of completion. values 0-5. |
800 void doTest(int mask, int permute) { | 819 void doTest(int mask, int permute) { |
801 asyncStart(); | 820 asyncStart(); |
802 asyncStart(); | 821 asyncStart(); |
803 bool done = false; | 822 bool done = false; |
804 String stringId = "waitCleanup-$mask-$permute"; | 823 String stringId = "waitCleanup-$mask-$permute"; |
805 List futures = new List(3); | 824 List futures = new List(3); |
806 List cleanup = new List(3); | 825 List cleanup = new List(3); |
807 int permuteTmp = permute; | 826 int permuteTmp = permute; |
808 for (int i = 0; i < 3; i++) { | 827 for (int i = 0; i < 3; i++) { |
809 bool throws = (mask & (1 << i)) != 0; | 828 bool throws = (mask & (1 << i)) != 0; |
810 var future = new Future.delayed( | 829 var future = new Future.delayed(new Duration(milliseconds: 100 * (i + 1)), |
811 new Duration(milliseconds: 100 * (i + 1)), | |
812 () => (throws ? throw "Error $i($mask-$permute)" : i)); | 830 () => (throws ? throw "Error $i($mask-$permute)" : i)); |
813 int mod = 3 - i; | 831 int mod = 3 - i; |
814 int position = permuteTmp % mod; | 832 int position = permuteTmp % mod; |
815 permuteTmp = permuteTmp ~/ mod; | 833 permuteTmp = permuteTmp ~/ mod; |
816 while (futures[position] != null) position++; | 834 while (futures[position] != null) position++; |
817 futures[position] = future; | 835 futures[position] = future; |
818 cleanup[i] = throws; | 836 cleanup[i] = throws; |
819 } | 837 } |
820 void checkDone() { | 838 void checkDone() { |
821 if (done) return; | 839 if (done) return; |
822 if (cleanup.every((v) => v)) { | 840 if (cleanup.every((v) => v)) { |
823 done = true; | 841 done = true; |
824 asyncEnd(); | 842 asyncEnd(); |
825 } | 843 } |
826 } | 844 } |
| 845 |
827 void cleanUp(index) { | 846 void cleanUp(index) { |
828 Expect.isFalse(cleanup[index]); | 847 Expect.isFalse(cleanup[index]); |
829 cleanup[index] = true; | 848 cleanup[index] = true; |
830 // Cleanup might happen before and after the wait().then() callback. | 849 // Cleanup might happen before and after the wait().then() callback. |
831 checkDone(); | 850 checkDone(); |
832 } | 851 } |
833 Future.wait(futures, eagerError: true, cleanUp: cleanUp) | 852 |
834 .then((_) { Expect.fail("No error: $stringId"); }, | 853 Future.wait(futures, eagerError: true, cleanUp: cleanUp).then((_) { |
835 onError: (e, s) { | 854 Expect.fail("No error: $stringId"); |
836 asyncEnd(); | 855 }, onError: (e, s) { |
837 checkDone(); | 856 asyncEnd(); |
838 }); | 857 checkDone(); |
| 858 }); |
839 } | 859 } |
840 | 860 |
841 for (int i = 1; i < 8; i++) { | 861 for (int i = 1; i < 8; i++) { |
842 for (int j = 0; j < 6; j++) { | 862 for (int j = 0; j < 6; j++) { |
843 doTest(i, j); | 863 doTest(i, j); |
844 } | 864 } |
845 } | 865 } |
846 asyncEnd(); | 866 asyncEnd(); |
847 } | 867 } |
848 | 868 |
849 void testWaitCleanUpError() { | 869 void testWaitCleanUpError() { |
850 var cms = const Duration(milliseconds: 100); | 870 var cms = const Duration(milliseconds: 100); |
851 var cleanups = new List.filled(3, false); | 871 var cleanups = new List.filled(3, false); |
852 var uncaughts = new List.filled(3, false); | 872 var uncaughts = new List.filled(3, false); |
853 asyncStart(); | 873 asyncStart(); |
854 asyncStart(); | 874 asyncStart(); |
855 asyncStart(); | 875 asyncStart(); |
856 runZoned(() { | 876 runZoned(() { |
857 Future.wait([new Future.delayed(cms, () => 0), | 877 Future.wait([ |
858 new Future.delayed(cms * 2, ()=> throw 1), | 878 new Future.delayed(cms, () => 0), |
859 new Future.delayed(cms * 3, () => 2)], | 879 new Future.delayed(cms * 2, () => throw 1), |
860 cleanUp: (index) { | 880 new Future.delayed(cms * 3, () => 2) |
861 Expect.isTrue(index == 0 || index == 2, "$index"); | 881 ], cleanUp: (index) { |
862 Expect.isFalse(cleanups[index]); | 882 Expect.isTrue(index == 0 || index == 2, "$index"); |
863 cleanups[index] = true; | 883 Expect.isFalse(cleanups[index]); |
864 throw index; | 884 cleanups[index] = true; |
865 }) | 885 throw index; |
866 .catchError((e) { | 886 }).catchError((e) { |
867 Expect.equals(e, 1); | 887 Expect.equals(e, 1); |
868 asyncEnd(); | 888 asyncEnd(); |
869 }); | 889 }); |
870 | |
871 }, onError: (int index, s) { | 890 }, onError: (int index, s) { |
872 Expect.isTrue(index == 0 || index == 2, "$index"); | 891 Expect.isTrue(index == 0 || index == 2, "$index"); |
873 Expect.isFalse(uncaughts[index]); | 892 Expect.isFalse(uncaughts[index]); |
874 uncaughts[index] = true; | 893 uncaughts[index] = true; |
875 asyncEnd(); | 894 asyncEnd(); |
876 }); | 895 }); |
877 } | 896 } |
878 | 897 |
879 void testWaitSyncError() { | 898 void testWaitSyncError() { |
880 var cms = const Duration(milliseconds: 100); | 899 var cms = const Duration(milliseconds: 100); |
881 var cleanups = new List.filled(3, false); | 900 var cleanups = new List.filled(3, false); |
882 asyncStart(); | 901 asyncStart(); |
883 asyncStart(); | 902 asyncStart(); |
884 runZoned(() { | 903 runZoned(() { |
885 Future.wait(new Iterable.generate(5, (i) { | 904 Future.wait( |
886 if (i != 3) return new Future.delayed(cms * (i + 1), () => i); | 905 new Iterable.generate(5, (i) { |
887 throw "throwing synchronously in iterable"; | 906 if (i != 3) return new Future.delayed(cms * (i + 1), () => i); |
888 }), cleanUp: (index) { | 907 throw "throwing synchronously in iterable"; |
| 908 }), cleanUp: (index) { |
889 Expect.isFalse(cleanups[index]); | 909 Expect.isFalse(cleanups[index]); |
890 cleanups[index] = true; | 910 cleanups[index] = true; |
891 if (cleanups.every((x) => x)) asyncEnd(); | 911 if (cleanups.every((x) => x)) asyncEnd(); |
892 }); | 912 }); |
893 }, onError: (e, s) { | 913 }, onError: (e, s) { |
894 asyncEnd(); | 914 asyncEnd(); |
895 }); | 915 }); |
896 } | 916 } |
897 | 917 |
898 void testWaitSyncError2() { | 918 void testWaitSyncError2() { |
899 asyncStart(); | 919 asyncStart(); |
900 Future.wait([null]).catchError((e, st) { | 920 Future.wait([null]).catchError((e, st) { |
901 // Makes sure that the `catchError` is invoked. | 921 // Makes sure that the `catchError` is invoked. |
902 // Regression test: an earlier version of `Future.wait` would propagate | 922 // Regression test: an earlier version of `Future.wait` would propagate |
903 // the error too soon for the code to install an error handler. | 923 // the error too soon for the code to install an error handler. |
904 // `testWaitSyncError` didn't show this problem, because the `runZoned` | 924 // `testWaitSyncError` didn't show this problem, because the `runZoned` |
905 // was already installed. | 925 // was already installed. |
906 asyncEnd(); | 926 asyncEnd(); |
907 }); | 927 }); |
908 } | 928 } |
909 | 929 |
910 // Future.wait transforms synchronous errors into asynchronous ones. | 930 // Future.wait transforms synchronous errors into asynchronous ones. |
911 // This function tests that zones can intercept them. | 931 // This function tests that zones can intercept them. |
912 void testWaitSyncError3() { | 932 void testWaitSyncError3() { |
913 var caughtError; | 933 var caughtError; |
914 var count = 0; | 934 var count = 0; |
915 | 935 |
916 AsyncError errorCallback( | 936 AsyncError errorCallback(Zone self, ZoneDelegate parent, Zone zone, |
917 Zone self, ZoneDelegate parent, Zone zone, Object error, | 937 Object error, StackTrace stackTrace) { |
918 StackTrace stackTrace) { | |
919 Expect.equals(0, count); | 938 Expect.equals(0, count); |
920 count++; | 939 count++; |
921 caughtError = error; | 940 caughtError = error; |
922 return parent.errorCallback(zone, error, stackTrace); | 941 return parent.errorCallback(zone, error, stackTrace); |
923 } | 942 } |
924 | 943 |
925 asyncStart(); | 944 asyncStart(); |
926 runZoned(() { | 945 runZoned(() { |
927 Future.wait([null]).catchError((e, st) { | 946 Future.wait([null]).catchError((e, st) { |
928 Expect.identical(e, caughtError); | 947 Expect.identical(e, caughtError); |
929 Expect.equals(1, count); | 948 Expect.equals(1, count); |
930 asyncEnd(); | 949 asyncEnd(); |
931 }); | 950 }); |
932 }, zoneSpecification: new ZoneSpecification(errorCallback: errorCallback)); | 951 }, zoneSpecification: new ZoneSpecification(errorCallback: errorCallback)); |
933 } | 952 } |
934 | 953 |
935 void testBadFuture() { | 954 void testBadFuture() { |
936 var bad = new BadFuture(); | 955 var bad = new BadFuture(); |
937 // Completing with bad future (then call throws) puts error in result. | 956 // Completing with bad future (then call throws) puts error in result. |
938 asyncStart(); | 957 asyncStart(); |
939 Completer completer = new Completer(); | 958 Completer completer = new Completer(); |
940 completer.complete(bad); | 959 completer.complete(bad); |
941 completer.future.then((_) { Expect.fail("unreachable"); }, | 960 completer.future.then((_) { |
942 onError: (e, s) { | 961 Expect.fail("unreachable"); |
943 Expect.isTrue(completer.isCompleted); | 962 }, onError: (e, s) { |
944 asyncEnd(); | 963 Expect.isTrue(completer.isCompleted); |
945 }); | 964 asyncEnd(); |
| 965 }); |
946 | 966 |
947 asyncStart(); | 967 asyncStart(); |
948 var f = new Future.value().then((_) => bad); | 968 var f = new Future.value().then((_) => bad); |
949 f.then((_) { Expect.fail("unreachable"); }, | 969 f.then((_) { |
950 onError: (e, s) { | 970 Expect.fail("unreachable"); |
951 asyncEnd(); | 971 }, onError: (e, s) { |
952 }); | 972 asyncEnd(); |
| 973 }); |
953 } | 974 } |
954 | 975 |
955 void testTypes() { | 976 void testTypes() { |
956 // Test that future is a Future<int> and not something less precise. | 977 // Test that future is a Future<int> and not something less precise. |
957 testType(name, future, [depth = 2]) { | 978 testType(name, future, [depth = 2]) { |
958 var desc = "$name${".whenComplete"*(2-depth)}"; | 979 var desc = "$name${".whenComplete"*(2-depth)}"; |
959 Expect.isTrue(future is Future<int>, "$desc is Future<int>"); | 980 Expect.isTrue(future is Future<int>, "$desc is Future<int>"); |
960 Expect.isFalse(future is Future<String>, "$desc is! Future<String>"); | 981 Expect.isFalse(future is Future<String>, "$desc is! Future<String>"); |
961 var stream = future.asStream(); | 982 var stream = future.asStream(); |
962 Expect.isTrue(stream is Stream<int>, "$desc.asStream() is Stream<int>"); | 983 Expect.isTrue(stream is Stream<int>, "$desc.asStream() is Stream<int>"); |
963 Expect.isFalse(stream is Stream<String>, | 984 Expect.isFalse( |
964 "$desc.asStream() is! Stream<String>"); | 985 stream is Stream<String>, "$desc.asStream() is! Stream<String>"); |
965 if (depth > 0) { | 986 if (depth > 0) { |
966 testType(name, future.whenComplete((){}), depth - 1); | 987 testType(name, future.whenComplete(() {}), depth - 1); |
967 } | 988 } |
968 } | 989 } |
| 990 |
969 for (var value in [42, null]) { | 991 for (var value in [42, null]) { |
970 testType("Future($value)", | 992 testType("Future($value)", new Future<int>(() => value)); |
971 new Future<int>(() => value)); | |
972 testType("Future.delayed($value)", | 993 testType("Future.delayed($value)", |
973 new Future<int>.delayed(Duration.ZERO, () => value)); | 994 new Future<int>.delayed(Duration.ZERO, () => value)); |
974 testType("Future.microtask($value)", | 995 testType( |
975 new Future<int>.microtask(() => value)); | 996 "Future.microtask($value)", new Future<int>.microtask(() => value)); |
976 testType("Future.sync($value)", new Future<int>.sync(() => value)); // //# 0
1: ok | 997 testType("Future.sync($value)", new Future<int>.sync(() => value)); // //# 0
1: ok |
977 testType("Future.sync(future($value))", // //# 0
1: continued | 998 testType("Future.sync(future($value))", // //# 0
1: continued |
978 new Future<int>.sync(() async => new Future.value(value))); //# 01:
continued | 999 new Future<int>.sync(() async => new Future.value(value))); //# 01:
continued |
979 testType("Future.value($value)", new Future<int>.value(value)); | 1000 testType("Future.value($value)", new Future<int>.value(value)); |
980 } | 1001 } |
981 testType("Completer.future", new Completer<int>().future); | 1002 testType("Completer.future", new Completer<int>().future); |
982 testType("Future.error", new Future<int>.error("ERR")..catchError((_){})); | 1003 testType("Future.error", new Future<int>.error("ERR")..catchError((_) {})); |
983 } | 1004 } |
984 | 1005 |
985 void testAnyValue() { | 1006 void testAnyValue() { |
986 asyncStart(); | 1007 asyncStart(); |
987 var cs = new List.generate(3, (_) => new Completer()); | 1008 var cs = new List.generate(3, (_) => new Completer()); |
988 var result = Future.any(cs.map((x) => x.future)); | 1009 var result = Future.any(cs.map((x) => x.future)); |
989 | 1010 |
990 result.then((v) { | 1011 result.then((v) { |
991 Expect.equals(42, v); | 1012 Expect.equals(42, v); |
992 asyncEnd(); | 1013 asyncEnd(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 // The errors are ignored, not uncaught. | 1069 // The errors are ignored, not uncaught. |
1049 cs[2].completeError("BAD"); | 1070 cs[2].completeError("BAD"); |
1050 cs[0].completeError("BAD"); | 1071 cs[0].completeError("BAD"); |
1051 } | 1072 } |
1052 | 1073 |
1053 void testFutureResult() { | 1074 void testFutureResult() { |
1054 asyncStart(); | 1075 asyncStart(); |
1055 () async { | 1076 () async { |
1056 var f = new UglyFuture(5); | 1077 var f = new UglyFuture(5); |
1057 // Sanity check that our future is as mis-behaved as we think. | 1078 // Sanity check that our future is as mis-behaved as we think. |
1058 f.then((v) { Expect.isTrue(v is Future); }); | 1079 f.then((v) { |
| 1080 Expect.isTrue(v is Future); |
| 1081 }); |
1059 | 1082 |
1060 var v = await f; | 1083 var v = await f; |
1061 // The static type of await is Flatten(static-type-of-expression), so it | 1084 // The static type of await is Flatten(static-type-of-expression), so it |
1062 // suggests that it flattens. In practice it currently doesn't. | 1085 // suggests that it flattens. In practice it currently doesn't. |
1063 // The specification doesn't say anything special, so v should be the | 1086 // The specification doesn't say anything special, so v should be the |
1064 // completion value of the UglyFuture future which is a future. | 1087 // completion value of the UglyFuture future which is a future. |
1065 Expect.isTrue(v is Future); | 1088 Expect.isTrue(v is Future); |
1066 | 1089 |
1067 // This used to hit an assert in checked mode. | 1090 // This used to hit an assert in checked mode. |
1068 // The CL adding this test changed the behavior to actually flatten the | 1091 // The CL adding this test changed the behavior to actually flatten the |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1163 Stream asStream() => _realFuture.asStream(); | 1186 Stream asStream() => _realFuture.asStream(); |
1164 String toString() => "CustomFuture@${_realFuture.hashCode}"; | 1187 String toString() => "CustomFuture@${_realFuture.hashCode}"; |
1165 int get hashCode => _realFuture.hashCode; | 1188 int get hashCode => _realFuture.hashCode; |
1166 } | 1189 } |
1167 | 1190 |
1168 /// A bad future that throws on every method. | 1191 /// A bad future that throws on every method. |
1169 class BadFuture<T> implements Future<T> { | 1192 class BadFuture<T> implements Future<T> { |
1170 Future then(action(T result), {Function onError}) { | 1193 Future then(action(T result), {Function onError}) { |
1171 throw "then GOTCHA!"; | 1194 throw "then GOTCHA!"; |
1172 } | 1195 } |
| 1196 |
1173 Future catchError(Function onError, {bool test(e)}) { | 1197 Future catchError(Function onError, {bool test(e)}) { |
1174 throw "catch GOTCHA!"; | 1198 throw "catch GOTCHA!"; |
1175 } | 1199 } |
| 1200 |
1176 Future whenComplete(action()) { | 1201 Future whenComplete(action()) { |
1177 throw "finally GOTCHA!"; | 1202 throw "finally GOTCHA!"; |
1178 } | 1203 } |
| 1204 |
1179 Stream<T> asStream() { | 1205 Stream<T> asStream() { |
1180 throw "asStream GOTCHA!"; | 1206 throw "asStream GOTCHA!"; |
1181 } | 1207 } |
| 1208 |
1182 Future timeout(Duration duration, {onTimeout()}) { | 1209 Future timeout(Duration duration, {onTimeout()}) { |
1183 throw "timeout GOTCHA!"; | 1210 throw "timeout GOTCHA!"; |
1184 } | 1211 } |
1185 } | 1212 } |
1186 | 1213 |
1187 // An evil future that completes with another future. | 1214 // An evil future that completes with another future. |
1188 class UglyFuture implements Future<dynamic> { | 1215 class UglyFuture implements Future<dynamic> { |
1189 final _result; | 1216 final _result; |
1190 UglyFuture(int badness) : | 1217 UglyFuture(int badness) |
1191 _result = (badness == 0) ? 42 : new UglyFuture(badness - 1); | 1218 : _result = (badness == 0) ? 42 : new UglyFuture(badness - 1); |
1192 Future then(action(value), {onError(error, StackTrace stack)}) { | 1219 Future then(action(value), {onError(error, StackTrace stack)}) { |
1193 var c = new Completer(); | 1220 var c = new Completer(); |
1194 c.complete(new Future.microtask(() => action(_result))); | 1221 c.complete(new Future.microtask(() => action(_result))); |
1195 return c.future; | 1222 return c.future; |
1196 } | 1223 } |
1197 Future catchError(onError, {test}) => this; // Never an error. | 1224 |
| 1225 Future catchError(onError, {test}) => this; // Never an error. |
1198 Future whenComplete(action()) { | 1226 Future whenComplete(action()) { |
1199 return new Future.microtask(action).then((_) => this); | 1227 return new Future.microtask(action).then((_) => this); |
1200 } | 1228 } |
| 1229 |
1201 Stream asStream() { | 1230 Stream asStream() { |
1202 return (new StreamController()..add(_result)..close()).stream; | 1231 return (new StreamController() |
| 1232 ..add(_result) |
| 1233 ..close()) |
| 1234 .stream; |
1203 } | 1235 } |
| 1236 |
1204 Future timeout(Duration duration, {onTimeout()}) { | 1237 Future timeout(Duration duration, {onTimeout()}) { |
1205 return this; | 1238 return this; |
1206 } | 1239 } |
1207 } | 1240 } |
OLD | NEW |