blob: c7b688f342e55c6e2c8032f195d88433fac03351 [file] [log] [blame]
// Copyright (c) 2017, 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.
import "dart:async";
import "dart:math" show Random;
import "package:async/async.dart";
import "package:test/test.dart";
final someStack = StackTrace.current;
Result<int> res(int n) => Result<int>.value(n);
Result err(n) => ErrorResult("$n", someStack);
/// Helper function creating an iterable of futures.
Iterable<Future<int>> futures(int count, {bool throwWhen(int index)}) sync* {
for (int i = 0; i < count; i++) {
if (throwWhen != null && throwWhen(i)) {
yield Future<int>.error("$i", someStack);
} else {
yield Future<int>.value(i);
}
}
}
main() {
test("empty", () async {
var all = await Result.captureAll<int>(futures(0));
expect(all, []);
});
group("futures only,", () {
test("single", () async {
var all = await Result.captureAll<int>(futures(1));
expect(all, [res(0)]);
});
test("multiple", () async {
var all = await Result.captureAll<int>(futures(3));
expect(all, [res(0), res(1), res(2)]);
});
test("error only", () async {
var all =
await Result.captureAll<int>(futures(1, throwWhen: (_) => true));
expect(all, [err(0)]);
});
test("multiple error only", () async {
var all =
await Result.captureAll<int>(futures(3, throwWhen: (_) => true));
expect(all, [err(0), err(1), err(2)]);
});
test("mixed error and value", () async {
var all =
await Result.captureAll<int>(futures(4, throwWhen: (x) => x.isOdd));
expect(all, [res(0), err(1), res(2), err(3)]);
});
test("completion permutation 1-2-3", () async {
var cs = List.generate(3, (_) => Completer<int>());
var all = Result.captureAll<int>(cs.map((c) => c.future));
expect(all, completion([res(1), res(2), err(3)]));
await 0;
cs[0].complete(1);
await 0;
cs[1].complete(2);
await 0;
cs[2].completeError("3", someStack);
});
test("completion permutation 1-3-2", () async {
var cs = List.generate(3, (_) => Completer<int>());
var all = Result.captureAll<int>(cs.map((c) => c.future));
expect(all, completion([res(1), res(2), err(3)]));
await 0;
cs[0].complete(1);
await 0;
cs[2].completeError("3", someStack);
await 0;
cs[1].complete(2);
});
test("completion permutation 2-1-3", () async {
var cs = List.generate(3, (_) => Completer<int>());
var all = Result.captureAll<int>(cs.map((c) => c.future));
expect(all, completion([res(1), res(2), err(3)]));
await 0;
cs[1].complete(2);
await 0;
cs[0].complete(1);
await 0;
cs[2].completeError("3", someStack);
});
test("completion permutation 2-3-1", () async {
var cs = List.generate(3, (_) => Completer<int>());
var all = Result.captureAll<int>(cs.map((c) => c.future));
expect(all, completion([res(1), res(2), err(3)]));
await 0;
cs[1].complete(2);
await 0;
cs[2].completeError("3", someStack);
await 0;
cs[0].complete(1);
});
test("completion permutation 3-1-2", () async {
var cs = List.generate(3, (_) => Completer<int>());
var all = Result.captureAll<int>(cs.map((c) => c.future));
expect(all, completion([res(1), res(2), err(3)]));
await 0;
cs[2].completeError("3", someStack);
await 0;
cs[0].complete(1);
await 0;
cs[1].complete(2);
});
test("completion permutation 3-2-1", () async {
var cs = List.generate(3, (_) => Completer<int>());
var all = Result.captureAll<int>(cs.map((c) => c.future));
expect(all, completion([res(1), res(2), err(3)]));
await 0;
cs[2].completeError("3", someStack);
await 0;
cs[1].complete(2);
await 0;
cs[0].complete(1);
});
var seed = Random().nextInt(0x100000000);
int n = 25; // max 32, otherwise rnd.nextInt(1<<n) won't work.
test("randomized #$n seed:${seed.toRadixString(16)}", () async {
var cs = List.generate(n, (_) => Completer<int>());
var all = Result.captureAll<int>(cs.map((c) => c.future));
var rnd = Random(seed);
var throwFlags = rnd.nextInt(1 << n); // Bit-flag for throwing.
bool throws(index) => (throwFlags & (1 << index)) != 0;
var expected = List.generate(n, (x) => throws(x) ? err(x) : res(x));
expect(all, completion(expected));
var completeFunctions = List<Function()>.generate(n, (i) {
var c = cs[i];
return () =>
throws(i) ? c.completeError("$i", someStack) : c.complete(i);
});
completeFunctions.shuffle(rnd);
for (int i = 0; i < n; i++) {
await 0;
completeFunctions[i]();
}
});
});
group("values only,", () {
test("single", () async {
var all = await Result.captureAll<int>(<int>[1]);
expect(all, [res(1)]);
});
test("multiple", () async {
var all = await Result.captureAll<int>(<int>[1, 2, 3]);
expect(all, [res(1), res(2), res(3)]);
});
});
group("mixed futures and values,", () {
test("no error", () async {
var all = await Result.captureAll<int>(<FutureOr<int>>[
1,
Future<int>(() => 2),
3,
Future<int>.value(4),
]);
expect(all, [res(1), res(2), res(3), res(4)]);
});
test("error", () async {
var all = await Result.captureAll<int>(<FutureOr<int>>[
1,
Future<int>(() => 2),
3,
Future<int>(() async => await Future.error("4", someStack)),
Future<int>.value(5)
]);
expect(all, [res(1), res(2), res(3), err(4), res(5)]);
});
});
}