// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. library futures_test; import 'package:async_helper/async_helper.dart'; import "package:expect/expect.dart"; import 'dart:async'; Future testWaitEmpty() { final futures = new List(); return Future.wait(futures); } Future testCompleteAfterWait() { final futures = new List(); final c = new Completer(); futures.add(c.future); Future future = Future.wait(futures); c.complete(null); return future; } Future testCompleteBeforeWait() { final futures = new List(); final c = new Completer(); futures.add(c.future); c.complete(null); return Future.wait(futures); } Future testWaitWithMultipleValues() { final futures = new List(); final c1 = new Completer(); final c2 = new Completer(); futures.add(c1.future); futures.add(c2.future); c1.complete(1); c2.complete(2); return Future.wait(futures).then((values) { Expect.listEquals([1, 2], values); }); } Future testWaitWithSingleError() { final futures = new List(); final c1 = new Completer(); final c2 = new Completer(); futures.add(c1.future); futures.add(c2.future); c1.complete(); c2.completeError('correct error'); return Future.wait(futures).then((_) { throw 'incorrect error'; }).catchError((error, stackTrace) { Expect.equals('correct error', error); Expect.isNotNull(stackTrace); }); } Future testWaitWithMultipleErrors() { final futures = new List(); final c1 = new Completer(); final c2 = new Completer(); futures.add(c1.future); futures.add(c2.future); c1.completeError('correct error'); c2.completeError('incorrect error 1'); return Future.wait(futures).then((_) { throw 'incorrect error 2'; }).catchError((error, stackTrace) { Expect.equals('correct error', error); Expect.isNotNull(stackTrace); }); } // Regression test for https://github.com/dart-lang/sdk/issues/41656 Future testWaitWithErrorAndNonErrorEager() { return Future(() { var f1 = Future(() => throw "Error"); var f2 = Future(() => 3); return Future.wait([f1, f2], eagerError: true); }).then((_) => 0, onError: (_) => -1); } Future testWaitWithMultipleErrorsEager() { final futures = new List(); final c1 = new Completer(); final c2 = new Completer(); futures.add(c1.future); futures.add(c2.future); c1.completeError('correct error'); c2.completeError('incorrect error 1'); return Future.wait(futures, eagerError: true).then((_) { throw 'incorrect error 2'; }).catchError((error, stackTrace) { Expect.equals('correct error', error); Expect.isNotNull(stackTrace); }); } StackTrace get currentStackTrace { try { throw 0; } catch (e, st) { return st; } throw "unreachable"; } Future testWaitWithSingleErrorWithStackTrace() { final futures = new List(); final c1 = new Completer(); final c2 = new Completer(); futures.add(c1.future); futures.add(c2.future); c1.complete(); c2.completeError('correct error', currentStackTrace); return Future.wait(futures).then((_) { throw 'incorrect error'; }).catchError((error, stackTrace) { Expect.equals('correct error', error); Expect.isNotNull(stackTrace); }); } Future testWaitWithMultipleErrorsWithStackTrace() { final futures = new List(); final c1 = new Completer(); final c2 = new Completer(); futures.add(c1.future); futures.add(c2.future); c1.completeError('correct error', currentStackTrace); c2.completeError('incorrect error 1'); return Future.wait(futures).then((_) { throw 'incorrect error 2'; }).catchError((error, stackTrace) { Expect.equals('correct error', error); Expect.isNotNull(stackTrace); }); } Future testWaitWithMultipleErrorsWithStackTraceEager() { final futures = new List(); final c1 = new Completer(); final c2 = new Completer(); futures.add(c1.future); futures.add(c2.future); c1.completeError('correct error', currentStackTrace); c2.completeError('incorrect error 1'); return Future.wait(futures, eagerError: true).then((_) { throw 'incorrect error 2'; }).catchError((error, stackTrace) { Expect.equals('correct error', error); Expect.isNotNull(stackTrace); }); } Future testEagerWait() { var st; try { throw 0; } catch (e, s) { st = s; } final c1 = new Completer(); final c2 = new Completer(); final futures = [c1.future, c2.future]; final waited = Future.wait(futures, eagerError: true); final result = waited.then((v) { throw "should not be called"; }, onError: (e, s) { Expect.equals(e, 42); Expect.identical(st, s); }).whenComplete(() { return new Future(() => true); }); c1.completeError(42, st); return result; } Future testForEachEmpty() { return Future.forEach([], (_) { throw 'should not be called'; }); } Future testForEach() { final seen = []; return Future.forEach([1, 2, 3, 4, 5], (n) { seen.add(n); return new Future.value(); }).then((_) => Expect.listEquals([1, 2, 3, 4, 5], seen)); } Future testForEachSync() { final seen = []; return Future.forEach([1, 2, 3, 4, 5], seen.add) .then((_) => Expect.listEquals([1, 2, 3, 4, 5], seen)); } Future testForEachWithException() { final seen = []; return Future.forEach([1, 2, 3, 4, 5], (n) { if (n == 4) throw 'correct exception'; seen.add(n); return new Future.value(); }).then((_) { throw 'incorrect exception'; }).catchError((error) { Expect.equals('correct exception', error); }); } Future testDoWhile() { var count = 0; return Future.doWhile(() { count++; return new Future(() => count < 10); }).then((_) => Expect.equals(10, count)); } Future testDoWhileSync() { var count = 0; return Future.doWhile(() { count++; return count < 10; }).then((_) => Expect.equals(10, count)); } Future testDoWhileWithException() { var count = 0; return Future.doWhile(() { count++; if (count == 4) throw 'correct exception'; return new Future(() => true); }).then((_) { throw 'incorrect exception'; }).catchError((error) { Expect.equals('correct exception', error); }).whenComplete(() { return new Future(() => false); }); } main() { final futures = new List(); futures.add(testWaitEmpty()); futures.add(testCompleteAfterWait()); futures.add(testCompleteBeforeWait()); futures.add(testWaitWithMultipleValues()); futures.add(testWaitWithSingleError()); futures.add(testWaitWithMultipleErrors()); futures.add(testWaitWithErrorAndNonErrorEager()); futures.add(testWaitWithMultipleErrorsEager()); futures.add(testWaitWithSingleErrorWithStackTrace()); futures.add(testWaitWithMultipleErrorsWithStackTrace()); futures.add(testWaitWithMultipleErrorsWithStackTraceEager()); futures.add(testEagerWait()); futures.add(testForEachEmpty()); futures.add(testForEach()); futures.add(testForEachSync()); futures.add(testForEachWithException()); futures.add(testDoWhile()); futures.add(testDoWhileSync()); futures.add(testDoWhileWithException()); asyncStart(); Future.wait(futures).then((List list) { Expect.equals(19, list.length); asyncEnd(); }); }