blob: 9d8597fabb555c4f04df6ef6e8bedf170677ac31 [file] [log] [blame]
// 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 = <Future>[];
return Future.wait(futures);
}
Future testCompleteAfterWait() {
final futures = <Future>[];
final c = new Completer<Object?>();
futures.add(c.future);
Future future = Future.wait(futures);
c.complete(null);
return future;
}
Future testCompleteBeforeWait() {
final futures = <Future>[];
final c = new Completer();
futures.add(c.future);
c.complete(null);
return Future.wait(futures);
}
Future testWaitWithMultipleValues() {
final futures = <Future>[];
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 = <Future>[];
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<void>((_) {
throw 'incorrect error';
}).catchError((error, stackTrace) {
Expect.equals('correct error', error);
Expect.isNotNull(stackTrace);
});
}
Future testWaitWithMultipleErrors() {
final futures = <Future>[];
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<void>((_) {
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 = <Future>[];
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<void>((_) {
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;
}
}
Future testWaitWithSingleErrorWithStackTrace() {
final futures = <Future>[];
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<void>((_) {
throw 'incorrect error';
}).catchError((error, stackTrace) {
Expect.equals('correct error', error);
Expect.isNotNull(stackTrace);
});
}
Future testWaitWithMultipleErrorsWithStackTrace() {
final futures = <Future>[];
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<void>((_) {
throw 'incorrect error 2';
}).catchError((error, stackTrace) {
Expect.equals('correct error', error);
Expect.isNotNull(stackTrace);
});
}
Future testWaitWithMultipleErrorsWithStackTraceEager() {
final futures = <Future>[];
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<void>((_) {
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 = <Future>[c1.future, c2.future];
final waited = Future.wait(futures, eagerError: true);
final result = waited.then<void>((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 = <int>[];
return Future.forEach([1, 2, 3, 4, 5], (dynamic n) {
seen.add(n);
return new Future.value();
}).then((_) => Expect.listEquals([1, 2, 3, 4, 5], seen));
}
Future testForEachSync() {
final seen = <int>[];
return Future.forEach([1, 2, 3, 4, 5], seen.add)
.then((_) => Expect.listEquals([1, 2, 3, 4, 5], seen));
}
Future testForEachWithException() {
final seen = <int>[];
return Future.forEach([1, 2, 3, 4, 5], (dynamic n) {
if (n == 4) throw 'correct exception';
seen.add(n);
return new Future.value();
}).then<void>((_) {
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<void>((_) {
throw 'incorrect exception';
}).catchError((error) {
Expect.equals('correct exception', error);
}).whenComplete(() {
return new Future(() => false);
});
}
main() {
final futures = <Future>[];
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();
});
}