| 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 |