// Copyright (c) 2020, 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. // Checks that Future> is a valid type and that futures can contain // and complete other futures. // This essentially checks that `FutureOr` is treated correctly depending // on what `X` is. import 'dart:async'; import 'package:async_helper/async_helper.dart'; import "package:expect/expect.dart"; main() { asyncStart(); // Helper values. Future nullFuture = Future.value(null); var stack = StackTrace.current; var error = ArgumentError("yep"); Future errorFuture = Future.error(error, stack) ..catchError((_) => null); Future fi(int n) => Future.value(n); // Tests that Future> can be created. Future> ffi(n) => Future>.value(fi(n)); asyncTest(() { return expectFutureFutureInt(ffi(0), 0); }); // Check `Future.then`'s callback. asyncTest(() { Future future = nullFuture.then((_) => fi(1)); return expectFutureInt(future, 1); }); asyncTest(() { Future> future = nullFuture.then>((_) => fi(2)); return expectFutureFutureInt(future, 2); }); asyncTest(() { Future> future = nullFuture.then>((_) => ffi(3)); return expectFutureFutureInt(future, 3); }); // Check `Future.then`'s `onError`. asyncTest(() { Future future = errorFuture.then((_) => -1, onError: (_) => fi(4)); return expectFutureInt(future, 4); }); asyncTest(() { Future> future = errorFuture.then>((_) => fi(-1), onError: (_) => fi(5)); return expectFutureFutureInt(future, 5); }); asyncTest(() { Future> future = errorFuture.then>((_) => fi(-1), onError: (_) => ffi(6)); return expectFutureFutureInt(future, 6); }); // Checkc Future.catchError, it's FutureOr is based on the // original future's type. asyncTest(() { Future errorFuture = Future.error(error, stack); Future future = errorFuture.catchError((_) => fi(7)); return expectFutureInt(future, 7); }); asyncTest(() { Future> errorFuture = Future>.error(error, stack); Future> future = errorFuture.catchError((_) => fi(8)); return expectFutureFutureInt(future, 8); }); asyncTest(() { Future> errorFuture = Future>.error(error, stack); Future> future = errorFuture.catchError((_) => ffi(9)); return expectFutureFutureInt(future, 9); }); // Check Completer.complete. asyncTest(() { var completer = Completer()..complete(fi(10)); return expectFutureInt(completer.future, 10); }); asyncTest(() { var completer = Completer>()..complete(fi(11)); return expectFutureFutureInt(completer.future, 11); }); asyncTest(() { var completer = Completer>()..complete(ffi(12)); return expectFutureFutureInt(completer.future, 12); }); // Future works correctly when Object is another Future. asyncTest(() { Future future = nullFuture.then((_) => fi(13)); Expect.type>(future); Expect.notType>(future); return future.then((o) { Expect.equals(13, o); }); }); asyncTest(() { Future future = nullFuture.then((_) => ffi(14)); Expect.type>(future); Expect.notType>(future); Expect.notType>>(future); return future.then((v) => expectFutureInt(v, 14)); }); asyncTest(() { Future future = errorFuture.then((_) => -1, onError: (_) => fi(15)); Expect.type>(future); Expect.notType>(future); return future.then((o) { Expect.equals(15, o); }); }); asyncTest(() { Future future = errorFuture.then((_) => -1, onError: (_) => ffi(16)); Expect.type>(future); Expect.notType>(future); Expect.notType>>(future); return future.then((v) => expectFutureInt(v, 16)); }); asyncTest(() { Future errorFuture = Future.error(error, stack); Future future = errorFuture.catchError((_) => fi(17)); Expect.type>(future); Expect.notType>(future); return future.then((o) { Expect.equals(17, o); }); }); asyncTest(() { Future errorFuture = Future.error(error, stack); Future future = errorFuture.catchError((_) => ffi(18)); Expect.type>(future); Expect.notType>(future); Expect.notType>>(future); return future.then((v) => expectFutureInt(v, 18)); }); asyncEnd(); } // Checks that future is a Future> containing the value Future // which then contains the value 42. Future expectFutureFutureInt(dynamic future, int n) { Expect.type>>(future); asyncStart(); return future.then((dynamic v) { Expect.type>(v, "$n"); return expectFutureInt(v, n).then(asyncSuccess); }); } Future expectFutureInt(dynamic future, int n) { Expect.type>(future); asyncStart(); return future.then((dynamic v) { Expect.type(v, "$n"); Expect.equals(n, v); asyncEnd(); }); }