blob: b992e1f0a3f0bea92baa23056dd2e71c6fabee5d [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 res(int n) => Result.value(n); Result err(n) => ErrorResult('\$n', someStack); /// Helper function creating an iterable of futures. Iterable> futures(int count, {bool Function(int index)? throwWhen}) sync* { for (var i = 0; i < count; i++) { if (throwWhen != null && throwWhen(i)) { yield Future.error('\$i', someStack); } else { yield Future.value(i); } } } void main() { test('empty', () async { var all = await Result.captureAll(futures(0)); expect(all, []); }); group('futures only,', () { test('single', () async { var all = await Result.captureAll(futures(1)); expect(all, [res(0)]); }); test('multiple', () async { var all = await Result.captureAll(futures(3)); expect(all, [res(0), res(1), res(2)]); }); test('error only', () async { var all = await Result.captureAll(futures(1, throwWhen: (_) => true)); expect(all, [err(0)]); }); test('multiple error only', () async { var all = await Result.captureAll(futures(3, throwWhen: (_) => true)); expect(all, [err(0), err(1), err(2)]); }); test('mixed error and value', () async { var all = await Result.captureAll(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()); var all = Result.captureAll(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()); var all = Result.captureAll(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()); var all = Result.captureAll(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()); var all = Result.captureAll(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()); var all = Result.captureAll(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()); var all = Result.captureAll(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); var n = 25; // max 32, otherwise rnd.nextInt(1< Completer()); var all = Result.captureAll(cs.map((c) => c.future)); var rnd = Random(seed); var throwFlags = rnd.nextInt(1 << n); // Bit-flag for throwing. bool throws(int index) => (throwFlags & (1 << index)) != 0; var expected = List.generate(n, (x) => throws(x) ? err(x) : res(x)); expect(all, completion(expected)); var completeFunctions = List.generate(n, (i) { var c = cs[i]; return () => throws(i) ? c.completeError('\$i', someStack) : c.complete(i); }); completeFunctions.shuffle(rnd); for (var i = 0; i < n; i++) { await 0; completeFunctions[i](); } }); }); group('values only,', () { test('single', () async { var all = await Result.captureAll([1]); expect(all, [res(1)]); }); test('multiple', () async { var all = await Result.captureAll([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(>[ 1, Future(() => 2), 3, Future.value(4), ]); expect(all, [res(1), res(2), res(3), res(4)]); }); test('error', () async { var all = await Result.captureAll(>[ 1, Future(() => 2), 3, Future(() async => await Future.error('4', someStack)), Future.value(5) ]); expect(all, [res(1), res(2), res(3), err(4), res(5)]); }); }); }