// Copyright (c) 2012, 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 future_test;

import 'package:async_helper/async_helper.dart';
import "package:expect/expect.dart";
import 'dart:async';

const Duration MS = const Duration(milliseconds: 1);

void testValue() {
  final future = new Future<String>.value("42");
  asyncStart();
  future.then((x) {
    Expect.equals("42", x);
    asyncEnd();
  });
}

void testSync() {
  compare(func) {
    // Compare the results of the following two futures.
    Future f1 = new Future.sync(func);
    Future f2 = new Future.value().then((_) => func());
    f2.catchError((_) {}); // I'll get the error later.
    f1.then((v1) {
      f2.then((v2) {
        Expect.equals(v1, v2);
      });
    }, onError: (e1) {
      f2.then((_) {
        Expect.fail("Expected error");
      }, onError: (e2) {
        Expect.equals(e1, e2);
      });
    });
  }

  Future val = new Future.value(42);
  Future err1 = new Future.error("Error")..catchError((_) {});
  try {
    throw [];
  } catch (e, st) {
    Future err2 = new Future.error(e, st)..catchError((_) {});
  }
  compare(() => 42);
  compare(() => val);
  compare(() {
    throw "Flif";
  });
  compare(() => err1);
  bool hasExecuted = false;
  compare(() {
    hasExecuted = true;
    return 499;
  });
  Expect.isTrue(hasExecuted);
}

void testNeverComplete() {
  final completer = new Completer<int>();
  final future = completer.future;
  future.then((v) => Expect.fail("Value not expected"));
  future.catchError((e) => Expect.fail("Value not expected"));
}

void testComplete() {
  final completer = new Completer<int>();
  final future = completer.future;
  Expect.isFalse(completer.isCompleted);

  completer.complete(3);
  Expect.isTrue(completer.isCompleted);

  future.then((v) => Expect.equals(3, v));
}

// Tests for [then]

void testCompleteWithSuccessHandlerBeforeComplete() {
  final completer = new Completer<int>();
  final future = completer.future;

  int? after;

  asyncStart();
  future.then((int v) {
    after = v;
  }).then((_) {
    Expect.equals(3, after);
    asyncEnd();
  });

  completer.complete(3);
  Expect.isNull(after);
}

void testCompleteWithSuccessHandlerAfterComplete() {
  final completer = new Completer<int>();
  final future = completer.future;

  int? after;
  completer.complete(3);
  Expect.isNull(after);

  asyncStart();
  future.then((int v) {
    after = v;
  }).then((_) {
    Expect.equals(3, after);
    asyncEnd();
  });
}

void testCompleteManySuccessHandlers() {
  final completer = new Completer<int>();
  final future = completer.future;
  late int before;
  late int after1;
  late int after2;

  var futures = <Future<int>>[];
  futures.add(future.then((int v) {
    before = v;
    return v;
  }));
  completer.complete(3);
  futures.add(future.then((int v) {
    after1 = v;
    return v;
  }));
  futures.add(future.then((int v) {
    after2 = v;
    return v;
  }));

  asyncStart();
  Future.wait(futures).then((_) {
    Expect.equals(3, before);
    Expect.equals(3, after1);
    Expect.equals(3, after2);
    asyncEnd();
  });
}

// Tests for [catchError]

void testException() {
  final completer = new Completer<int?>();
  final future = completer.future;
  final ex = new Exception();

  asyncStart();
  future.then((v) {
    throw "Value not expected";
    return null;
  }).catchError((error) {
    Expect.equals(error, ex);
    asyncEnd();
  }, test: (e) => e == ex);
  completer.completeError(ex);
}

void testExceptionHandler() {
  final completer = new Completer<int?>();
  final future = completer.future;
  final ex = new Exception();

  var ex2;
  var done = future.catchError((error) {
    ex2 = error;
  });

  Expect.isFalse(completer.isCompleted);
  completer.completeError(ex);
  Expect.isTrue(completer.isCompleted);

  asyncStart();
  done.then((_) {
    Expect.equals(ex, ex2);
    asyncEnd();
  });
}

void testExceptionHandlerReturnsTrue() {
  final completer = new Completer<int?>();
  final future = completer.future;
  final ex = new Exception();

  bool reached = false;
  future.catchError((e) {});
  future.catchError((e) {
    reached = true;
  }, test: (e) => false).catchError((e) {});
  Expect.isFalse(completer.isCompleted);
  completer.completeError(ex);
  Expect.isTrue(completer.isCompleted);
  Expect.isFalse(reached);
}

void testExceptionHandlerReturnsTrue2() {
  final completer = new Completer<int?>();
  final future = completer.future;
  final ex = new Exception();

  bool reached = false;
  var done = future.catchError((e) {}, test: (e) => false).catchError((e) {
    reached = true;
  });
  completer.completeError(ex);

  asyncStart();
  done.then((_) {
    Expect.isTrue(reached);
    asyncEnd();
  });
}

void testExceptionHandlerReturnsFalse() {
  final completer = new Completer<int?>();
  final future = completer.future;
  final ex = new Exception();

  bool reached = false;

  future.catchError((e) {});

  future.catchError((e) {
    reached = true;
  }, test: (e) => false).catchError((e) {});

  completer.completeError(ex);

  Expect.isFalse(reached);
}

void testFutureAsStreamCompleteAfter() {
  var completer = new Completer();
  bool gotValue = false;
  asyncStart();
  completer.future.asStream().listen((data) {
    Expect.isFalse(gotValue);
    gotValue = true;
    Expect.equals("value", data);
  }, onDone: () {
    Expect.isTrue(gotValue);
    asyncEnd();
  });
  completer.complete("value");
}

void testFutureAsStreamCompleteBefore() {
  var completer = new Completer();
  bool gotValue = false;
  asyncStart();
  completer.complete("value");
  completer.future.asStream().listen((data) {
    Expect.isFalse(gotValue);
    gotValue = true;
    Expect.equals("value", data);
  }, onDone: () {
    Expect.isTrue(gotValue);
    asyncEnd();
  });
}

void testFutureAsStreamCompleteImmediate() {
  bool gotValue = false;
  asyncStart();
  new Future.value("value").asStream().listen((data) {
    Expect.isFalse(gotValue);
    gotValue = true;
    Expect.equals("value", data);
  }, onDone: () {
    Expect.isTrue(gotValue);
    asyncEnd();
  });
}

void testFutureAsStreamCompleteErrorAfter() {
  var completer = new Completer();
  bool gotError = false;
  asyncStart();
  completer.future.asStream().listen((data) {
    Expect.fail("Unexpected data");
  }, onError: (error) {
    Expect.isFalse(gotError);
    gotError = true;
    Expect.equals("error", error);
  }, onDone: () {
    Expect.isTrue(gotError);
    asyncEnd();
  });
  completer.completeError("error");
}

void testFutureAsStreamWrapper() {
  var completer = new Completer();
  bool gotValue = false;
  asyncStart();
  completer.complete("value");
  completer.future
      .catchError((_) {
        throw "not possible";
      }) // Returns a future wrapper.
      .asStream()
      .listen((data) {
        Expect.isFalse(gotValue);
        gotValue = true;
        Expect.equals("value", data);
      }, onDone: () {
        Expect.isTrue(gotValue);
        asyncEnd();
      });
}

void testFutureWhenCompleteValue() {
  asyncStart();
  int counter = 2;
  countDown() {
    if (--counter == 0) asyncEnd();
  }

  var completer = new Completer();
  Future future = completer.future;
  Future later = future.whenComplete(countDown);
  later.then((v) {
    Expect.equals(42, v);
    countDown();
  });
  completer.complete(42);
}

void testFutureWhenCompleteError() {
  asyncStart();
  int counter = 2;
  countDown() {
    if (--counter == 0) asyncEnd();
  }

  var completer = new Completer();
  Future future = completer.future;
  Future later = future.whenComplete(countDown);
  later.catchError((error) {
    Expect.equals("error", error);
    countDown();
  });
  completer.completeError("error");
}

void testFutureWhenCompleteValueNewError() {
  asyncStart();
  int counter = 2;
  countDown() {
    if (--counter == 0) asyncEnd();
  }

  var completer = new Completer();
  Future future = completer.future;
  Future later = future.whenComplete(() {
    countDown();
    throw "new error";
  });
  later.catchError((error) {
    Expect.equals("new error", error);
    countDown();
  });
  completer.complete(42);
}

void testFutureWhenCompleteErrorNewError() {
  asyncStart();
  int counter = 2;
  countDown() {
    if (--counter == 0) asyncEnd();
  }

  var completer = new Completer();
  Future future = completer.future;
  Future later = future.whenComplete(() {
    countDown();
    throw "new error";
  });
  later.catchError((error) {
    Expect.equals("new error", error);
    countDown();
  });
  completer.completeError("error");
}

void testFutureWhenCompletePreValue() {
  asyncStart();
  int counter = 2;
  countDown() {
    if (--counter == 0) asyncEnd();
  }

  var completer = new Completer();
  Future future = completer.future;
  completer.complete(42);
  Timer.run(() {
    Future later = future.whenComplete(countDown);
    later.then((v) {
      Expect.equals(42, v);
      countDown();
    });
  });
}

void testFutureWhenValueFutureValue() {
  asyncStart();
  int counter = 3;
  countDown(int expect) {
    Expect.equals(expect, counter);
    if (--counter == 0) asyncEnd();
  }

  var completer = new Completer();
  completer.future.whenComplete(() {
    countDown(3);
    var completer2 = new Completer();
    new Timer(MS * 10, () {
      countDown(2);
      completer2.complete(37);
    });
    return completer2.future;
  }).then((v) {
    Expect.equals(42, v);
    countDown(1);
  });

  completer.complete(42);
}

void testFutureWhenValueFutureError() {
  asyncStart();
  int counter = 3;
  countDown(int expect) {
    Expect.equals(expect, counter);
    if (--counter == 0) asyncEnd();
  }

  var completer = new Completer();
  completer.future.whenComplete(() {
    countDown(3);
    var completer2 = new Completer();
    new Timer(MS * 10, () {
      countDown(2);
      completer2.completeError("Fail");
    });
    return completer2.future;
  }).then((v) {
    Expect.fail("should fail async");
  }, onError: (error) {
    Expect.equals("Fail", error);
    countDown(1);
  });

  completer.complete(42);
}

void testFutureWhenErrorFutureValue() {
  asyncStart();
  int counter = 3;
  countDown(int expect) {
    Expect.equals(expect, counter);
    if (--counter == 0) asyncEnd();
  }

  var completer = new Completer();
  completer.future.whenComplete(() {
    countDown(3);
    var completer2 = new Completer();
    new Timer(MS * 10, () {
      countDown(2);
      completer2.complete(37);
    });
    return completer2.future;
  }).then((v) {
    Expect.fail("should fail async");
  }, onError: (error) {
    Expect.equals("Error", error);
    countDown(1);
  });

  completer.completeError("Error");
}

void testFutureWhenErrorFutureError() {
  asyncStart();
  int counter = 3;
  countDown(int expect) {
    Expect.equals(expect, counter);
    if (--counter == 0) asyncEnd();
  }

  var completer = new Completer();
  completer.future.whenComplete(() {
    countDown(3);
    var completer2 = new Completer();
    new Timer(MS * 10, () {
      countDown(2);
      completer2.completeError("Fail");
    });
    return completer2.future;
  }).then((v) {
    Expect.fail("should fail async");
  }, onError: (error) {
    Expect.equals("Fail", error);
    countDown(1);
  });

  completer.completeError("Error");
}

void testFutureThenThrowsAsync() {
  final completer = new Completer<int?>();
  final future = completer.future;
  int error = 42;

  asyncStart();
  future.then((v) {
    throw error;
    return null;
  }).catchError((e) {
    Expect.identical(error, e);
    asyncEnd();
  });
  completer.complete(0);
}

void testFutureCatchThrowsAsync() {
  final completer = new Completer<int?>();
  final future = completer.future;
  int error = 42;

  asyncStart();
  future.catchError((e) {
    throw error;
  }).catchError((e) {
    Expect.identical(error, e);
    asyncEnd();
  });
  completer.completeError(0);
}

void testFutureCatchRethrowsAsync() {
  final completer = new Completer<int?>();
  final future = completer.future;
  var error;

  asyncStart();
  future.catchError((e) {
    error = e;
    throw e;
  }).catchError((e) {
    Expect.identical(error, e);
    asyncEnd();
  });
  completer.completeError(0);
}

void testFutureWhenThrowsAsync() {
  final completer = new Completer<int?>();
  final future = completer.future;
  var error = 42;

  asyncStart();
  future.whenComplete(() {
    throw error;
  }).catchError((e) {
    Expect.identical(error, e);
    asyncEnd();
  });
  completer.complete(0);
}

void testCompleteWithError() {
  final completer = new Completer<int?>();
  final future = completer.future;
  var error = 42;

  asyncStart();
  future.catchError((e) {
    Expect.identical(error, e);
    asyncEnd();
  });

  completer.completeError(error);
}

void testCompleteWithFutureSuccess() {
  asyncStart();
  final completer = new Completer<int>();
  final completer2 = new Completer<int>();
  completer.complete(completer2.future);
  completer.future.then((v) {
    Expect.equals(42, v);
    asyncEnd();
  });
  completer2.complete(42);
}

void testCompleteWithFutureSuccess2() {
  asyncStart();
  final completer = new Completer<int>();
  final result = new Future<int>.value(42);
  completer.complete(result);
  completer.future.then((v) {
    Expect.equals(42, v);
    asyncEnd();
  });
}

void testCompleteWithFutureError() {
  asyncStart();
  final completer = new Completer<int>();
  final completer2 = new Completer<int>();
  completer.complete(completer2.future);
  completer.future.then((v) {
    Expect.fail("Should not happen");
    asyncEnd();
  }, onError: (e) {
    Expect.equals("ERROR-tcwfe", e);
    asyncEnd();
  });
  completer2.completeError("ERROR-tcwfe");
}

void testCompleteWithFutureError2() {
  asyncStart();
  final completer = new Completer<int>();
  var result = new Future<int>.error("ERROR-tcwfe2");
  completer.complete(result);
  completer.future.then((v) {
    Expect.fail("Should not happen");
    asyncEnd();
  }, onError: (e) {
    Expect.equals("ERROR-tcwfe2", e);
    asyncEnd();
  });
}

void testCompleteErrorWithFuture() {
  asyncStart();
  final completer = new Completer<int>();
  completer.completeError(new Future.value(42));
  completer.future.then((_) {
    Expect.fail("Shouldn't happen");
  }, onError: (e, s) {
    Future f = e;
    f.then((v) {
      Expect.equals(42, v);
      asyncEnd();
    });
  });
}

void testCompleteWithCustomFutureSuccess() {
  asyncStart();
  final completer = new Completer<int>();
  final completer2 = new Completer<int>();
  completer.complete(new CustomFuture<int>(completer2.future));
  completer.future.then((v) {
    Expect.equals(42, v);
    asyncEnd();
  });
  completer2.complete(42);
}

void testCompleteWithCustomFutureError() {
  asyncStart();
  final completer = new Completer<int>();
  final completer2 = new Completer<int>();
  completer.complete(new CustomFuture<int>(completer2.future));
  completer.future.then((v) {
    Expect.fail("Should not happen");
    asyncEnd();
  }, onError: (e) {
    Expect.equals("ERROR-tcwcfe", e);
    asyncEnd();
  });
  completer2.completeError("ERROR-tcwcfe");
}

void testCompleteErrorWithCustomFuture() {
  asyncStart();
  final completer = new Completer<int>();
  var future = new CustomFuture<int>(new Future.value(42));
  completer.completeError(future);
  completer.future.then((_) {
    Expect.fail("Shouldn't happen");
  }, onError: (e) {
    Future f = e;
    f.then((v) {
      Expect.equals(42, v);
      asyncEnd();
    });
  });
}

void testChainedFutureValue() {
  final completer = new Completer();
  final future = completer.future;
  asyncStart();

  future.then((v) => new Future.value(v * 2)).then((v) {
    Expect.equals(42, v);
    asyncEnd();
  });
  completer.complete(21);
}

void testChainedFutureValueDelay() {
  final completer = new Completer();
  final future = completer.future;
  asyncStart();

  future
      .then((v) =>
          new Future.delayed(const Duration(milliseconds: 10), () => v * 2))
      .then((v) {
    Expect.equals(42, v);
    asyncEnd();
  });
  completer.complete(21);
}

void testChainedFutureValue2Delay() {
  asyncStart();

  new Future.delayed(const Duration(milliseconds: 10)).then((v) {
    Expect.isNull(v);
    asyncEnd();
  });
}

void testChainedFutureError() {
  final completer = new Completer();
  final future = completer.future;
  asyncStart();

  future.then((v) => new Future.error("Fehler")).then((v) {
    Expect.fail("unreachable!");
  }, onError: (error) {
    Expect.equals("Fehler", error);
    asyncEnd();
  });
  completer.complete(21);
}

void testSyncFuture_i13368() {
  asyncStart();

  final future = new Future<int>.sync(() {
    return new Future<int>.value(42);
  });

  future.then((int val) {
    Expect.equals(val, 42);
    asyncEnd();
  });
}

void testWaitCleanUp() {
  asyncStart();
  // Creates three futures with different completion times, and where some fail.
  // The `mask` specifies which futures fail (values 1-7),
  // and `permute` defines the order of completion. values 0-5.
  void doTest(int mask, int permute) {
    asyncStart();
    String stringId = "waitCleanup-$mask-$permute";
    List<Future?> futures = <Future?>[null, null, null];
    List cleanup = [null, null, null];
    int permuteTmp = permute;
    for (int i = 0; i < 3; i++) {
      bool throws = (mask & (1 << i)) != 0;
      var future = new Future.delayed(new Duration(milliseconds: 100 * (i + 1)),
          () => (throws ? throw "Error $i($mask-$permute)" : i));
      int mod = 3 - i;
      int position = permuteTmp % mod;
      permuteTmp = permuteTmp ~/ mod;
      while (futures[position] != null) position++;
      futures[position] = future;
      cleanup[i] = throws;
    }
    void cleanUp(index) {
      Expect.isFalse(cleanup[index]);
      cleanup[index] = true;
    }

    Future.wait(futures.map((future) => future!), cleanUp: cleanUp).then((_) {
      Expect.fail("No error: $stringId");
    }, onError: (e, s) {
      Expect.listEquals([true, true, true], cleanup);
      asyncEnd();
    });
  }

  for (int i = 1; i < 8; i++) {
    for (int j = 0; j < 6; j++) {
      doTest(i, j);
    }
  }
  asyncEnd();
}

void testWaitCleanUpEager() {
  asyncStart();
  // Creates three futures with different completion times, and where some fail.
  // The `mask` specifies which futures fail (values 1-7),
  // and `permute` defines the order of completion. values 0-5.
  void doTest(int mask, int permute) {
    asyncStart();
    asyncStart();
    bool done = false;
    String stringId = "waitCleanup-$mask-$permute";
    List<Future?> futures = <Future?>[null, null, null];
    List cleanup = [null, null, null];
    int permuteTmp = permute;
    for (int i = 0; i < 3; i++) {
      bool throws = (mask & (1 << i)) != 0;
      var future = new Future.delayed(new Duration(milliseconds: 100 * (i + 1)),
          () => (throws ? throw "Error $i($mask-$permute)" : i));
      int mod = 3 - i;
      int position = permuteTmp % mod;
      permuteTmp = permuteTmp ~/ mod;
      while (futures[position] != null) position++;
      futures[position] = future;
      cleanup[i] = throws;
    }
    void checkDone() {
      if (done) return;
      if (cleanup.every((v) => v)) {
        done = true;
        asyncEnd();
      }
    }

    void cleanUp(index) {
      Expect.isFalse(cleanup[index]);
      cleanup[index] = true;
      // Cleanup might happen before and after the wait().then() callback.
      checkDone();
    }

    Future.wait(futures.map((future) => future!),
            eagerError: true, cleanUp: cleanUp)
        .then((_) {
      Expect.fail("No error: $stringId");
    }, onError: (e, s) {
      asyncEnd();
      checkDone();
    });
  }

  for (int i = 1; i < 8; i++) {
    for (int j = 0; j < 6; j++) {
      doTest(i, j);
    }
  }
  asyncEnd();
}

void testWaitCleanUpError() {
  var cms = const Duration(milliseconds: 100);
  var cleanups = new List.filled(3, false);
  var uncaughts = new List.filled(3, false);
  asyncStart();
  asyncStart();
  asyncStart();
  runZonedGuarded(() {
    Future<List<int>?>.value(Future.wait([
      new Future.delayed(cms, () => 0),
      new Future.delayed(cms * 2, () => throw 1),
      new Future.delayed(cms * 3, () => 2)
    ], cleanUp: (index) {
      Expect.isTrue(index == 0 || index == 2, "$index");
      Expect.isFalse(cleanups[index]);
      cleanups[index] = true;
      throw index;
    })).catchError((e) {
      Expect.equals(e, 1);
      asyncEnd();
    });
  }, (e, s) {
    int index = e as int;
    Expect.isTrue(index == 0 || index == 2, "$index");
    Expect.isFalse(uncaughts[index]);
    uncaughts[index] = true;
    asyncEnd();
  });
}

void testWaitSyncError() {
  var cms = const Duration(milliseconds: 100);
  var cleanups = new List.filled(3, false);
  asyncStart();
  asyncStart();
  runZoned(() {
    Future.wait(
        new Iterable.generate(5, (i) {
          if (i != 3) return new Future.delayed(cms * (i + 1), () => i);
          throw "throwing synchronously in iterable";
        }), cleanUp: (index) {
      Expect.isFalse(cleanups[index]);
      cleanups[index] = true;
      if (cleanups.every((x) => x)) asyncEnd();
    });
  }, onError: (e, s) {
    asyncEnd();
  });
}

// Creates an Iterable that throws when iterated. Used to validate how
// Future.wait() handles a synchronous error occurring inside its own code.
Iterable<Future> badIterable() sync* {
  throw "!";
}

void testWaitSyncError2() {
  asyncStart();
  Future<List?>.value(Future.wait(badIterable())).catchError((e, st) {
    // Makes sure that the `catchError` is invoked.
    // Regression test: an earlier version of `Future.wait` would propagate
    // the error too soon for the code to install an error handler.
    // `testWaitSyncError` didn't show this problem, because the `runZoned`
    // was already installed.
    asyncEnd();
  });
}

// Future.wait transforms synchronous errors into asynchronous ones.
// This function tests that zones can intercept them.
void testWaitSyncError3() {
  var caughtError;
  var count = 0;

  AsyncError? errorCallback(Zone self, ZoneDelegate parent, Zone zone,
      Object error, StackTrace? stackTrace) {
    Expect.equals(0, count);
    count++;
    caughtError = error;
    return parent.errorCallback(zone, error, stackTrace);
  }

  asyncStart();
  runZoned(() {
    Future<List?>.value(Future.wait(badIterable())).catchError((e, st) {
      Expect.identical(e, caughtError);
      Expect.equals(1, count);
      asyncEnd();
    });
  }, zoneSpecification: new ZoneSpecification(errorCallback: errorCallback));
}

void testBadFuture() {
  var bad = new BadFuture();
  // Completing with bad future (then call throws) puts error in result.
  asyncStart();
  Completer completer = new Completer();
  completer.complete(bad);
  completer.future.then((_) {
    Expect.fail("unreachable");
  }, onError: (e, s) {
    Expect.isTrue(completer.isCompleted);
    asyncEnd();
  });

  asyncStart();
  var f = new Future.value().then((_) => bad);
  f.then((_) {
    Expect.fail("unreachable");
  }, onError: (e, s) {
    asyncEnd();
  });
}

void testTypes() {
  // Test that future is a Future<int> and not something less precise.
  testType(name, future, [int depth = 2]) {
    var desc = "$name${".whenComplete" * (2 - depth)}";
    Expect.isTrue(future is Future<int>, "$desc is Future<int>");
    Expect.isFalse(future is Future<String>, "$desc is! Future<String>");
    var stream = future.asStream();
    Expect.isTrue(stream is Stream<int>, "$desc.asStream() is Stream<int>");
    Expect.isFalse(
        stream is Stream<String>, "$desc.asStream() is! Stream<String>");
    if (depth > 0) {
      testType(name, future.whenComplete(() {}), depth - 1);
    }
  }

  for (var value in [42]) {
    testType("Future($value)", new Future<int>(() => value));
    testType("Future.delayed($value)",
        new Future<int>.delayed(Duration.zero, () => value));
    testType(
        "Future.microtask($value)", new Future<int>.microtask(() => value));
    testType("Future.sync($value)", new Future<int>.sync(() => value));
    testType("Future.sync(future($value))",
        new Future<int>.sync(() => new Future<int>.value(value)));
    testType("Future.value($value)", new Future<int>.value(value));
    testType(
        "Future.error", new Future<int>.error("ERR")..catchError((_) => value));
  }
  testType("Completer.future", new Completer<int>().future);
}

void testAnyValue() {
  asyncStart();
  var cs = new List.generate(3, (_) => new Completer());
  var result = Future.any(cs.map((x) => x.future));

  result.then((v) {
    Expect.equals(42, v);
    asyncEnd();
  }, onError: (e, s) {
    Expect.fail("Unexpected error: $e");
  });

  cs[1].complete(42);
  cs[2].complete(10);
  cs[0].complete(20);
}

void testAnyError() {
  asyncStart();
  var cs = new List.generate(3, (_) => new Completer());
  var result = Future.any(cs.map((x) => x.future));

  result.then((v) {
    Expect.fail("Unexpected value: $v");
  }, onError: (e, s) {
    Expect.equals(42, e);
    asyncEnd();
  });

  cs[1].completeError(42);
  cs[2].complete(10);
  cs[0].complete(20);
}

void testAnyIgnoreIncomplete() {
  asyncStart();
  var cs = new List.generate(3, (_) => new Completer());
  var result = Future.any(cs.map((x) => x.future));

  result.then((v) {
    Expect.equals(42, v);
    asyncEnd();
  }, onError: (e, s) {
    Expect.fail("Unexpected error: $e");
  });

  cs[1].complete(42);
  // The other two futures never complete.
}

void testAnyIgnoreError() {
  asyncStart();
  var cs = new List.generate(3, (_) => new Completer());
  var result = Future.any(cs.map((x) => x.future));

  result.then((v) {
    Expect.equals(42, v);
    asyncEnd();
  }, onError: (e, s) {
    Expect.fail("Unexpected error: $e");
  });

  cs[1].complete(42);
  // The errors are ignored, not uncaught.
  cs[2].completeError("BAD");
  cs[0].completeError("BAD");
}

void testFutureResult() {
  asyncStart();
  () async {
    var f = new UglyFuture(5);
    // Sanity check that our future is as mis-behaved as we think.
    f.then((v) {
      Expect.isTrue(v is Future);
    });

    var v = await f;
    // The static type of await is Flatten(static-type-of-expression), so it
    // suggests that it flattens. In practice it currently doesn't.
    // The specification doesn't say anything special, so v should be the
    // completion value of the UglyFuture future which is a future.
    Expect.isTrue(v is Future);

    // This used to hit an assert in checked mode.
    // The CL adding this test changed the behavior to actually flatten the
    // the future returned by the then-callback.
    var w = new Future.value(42).then((_) => f);
    Expect.equals(42, await w);
    asyncEnd();
  }();
}

void testFutureOfFuture() async {
  // Plain Future.
  asyncStart();
  var future = Future<Future<int>>.value(Future<int>.value(42));
  Expect.type<Future<Future<int>>>(future);
  future.then((innerFuture) {
    Expect.type<Future<int>>(innerFuture);
    innerFuture.then((number) {
      Expect.equals(42, number);
      asyncEnd();
    });
  });

  // With completer.
  asyncStart();
  var completer = Completer<Future<int>>();
  Expect.type<Future<Future<int>>>(completer.future);
  completer.future.then((innerFuture) {
    Expect.type<Future<int>>(innerFuture);
    innerFuture.then((number) {
      Expect.equals(42, number);
      asyncEnd();
    });
  });
  completer.complete(Future<int>.value(42));
}

main() {
  asyncStart();

  testValue();
  testSync();
  testNeverComplete();

  testComplete();
  testCompleteWithSuccessHandlerBeforeComplete();
  testCompleteWithSuccessHandlerAfterComplete();
  testCompleteManySuccessHandlers();
  testCompleteWithError();

  testCompleteWithFutureSuccess();
  testCompleteWithFutureSuccess2();
  testCompleteWithFutureError();
  testCompleteWithFutureError2();
  testCompleteErrorWithFuture();
  testCompleteWithCustomFutureSuccess();
  testCompleteWithCustomFutureError();
  testCompleteErrorWithCustomFuture();

  testException();
  testExceptionHandler();
  testExceptionHandlerReturnsTrue();
  testExceptionHandlerReturnsTrue2();
  testExceptionHandlerReturnsFalse();

  testFutureAsStreamCompleteAfter();
  testFutureAsStreamCompleteBefore();
  testFutureAsStreamCompleteImmediate();
  testFutureAsStreamCompleteErrorAfter();
  testFutureAsStreamWrapper();

  testFutureWhenCompleteValue();
  testFutureWhenCompleteError();
  testFutureWhenCompleteValueNewError();
  testFutureWhenCompleteErrorNewError();

  testFutureWhenValueFutureValue();
  testFutureWhenErrorFutureValue();
  testFutureWhenValueFutureError();
  testFutureWhenErrorFutureError();

  testFutureThenThrowsAsync();
  testFutureCatchThrowsAsync();
  testFutureWhenThrowsAsync();
  testFutureCatchRethrowsAsync();

  testChainedFutureValue();
  testChainedFutureValueDelay();
  testChainedFutureError();

  testSyncFuture_i13368();

  testWaitCleanUp();
  testWaitCleanUpError();
  testWaitSyncError();
  testWaitSyncError2();
  testWaitSyncError3();

  testBadFuture();

  testTypes();

  testAnyValue();
  testAnyError();
  testAnyIgnoreIncomplete();
  testAnyIgnoreError();

  testFutureResult();

  testFutureOfFuture();

  asyncEnd();
}

/// A well-behaved Future that isn't recognizable as a _Future.
class CustomFuture<T> implements Future<T> {
  Future<T> _realFuture;
  CustomFuture(this._realFuture);
  Future<S> then<S>(FutureOr<S> action(T result), {Function? onError}) =>
      _realFuture.then(action, onError: onError);
  Future<T> catchError(Function onError, {bool test(Object e)?}) =>
      _realFuture.catchError(onError, test: test);
  Future<T> whenComplete(action()) => _realFuture.whenComplete(action);
  Future<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()?}) =>
      _realFuture.timeout(timeLimit, onTimeout: onTimeout);
  Stream<T> asStream() => _realFuture.asStream();
  String toString() => "CustomFuture@${_realFuture.hashCode}";
  int get hashCode => _realFuture.hashCode;
}

/// A bad future that throws on every method.
class BadFuture<T> implements Future<T> {
  Future<S> then<S>(action(T result), {Function? onError}) {
    throw "then GOTCHA!";
  }

  Future<T> catchError(Function onError, {bool test(Object e)?}) {
    throw "catch GOTCHA!";
  }

  Future<T> whenComplete(action()) {
    throw "finally GOTCHA!";
  }

  Stream<T> asStream() {
    throw "asStream GOTCHA!";
  }

  Future<T> timeout(Duration duration, {onTimeout()?}) {
    throw "timeout GOTCHA!";
  }
}

// An evil future that completes with another future.
class UglyFuture implements Future<dynamic> {
  final _result;
  UglyFuture(int badness)
      : _result = (badness == 0) ? 42 : new UglyFuture(badness - 1);
  Future<S> then<S>(action(value), {Function? onError}) {
    var c = new Completer<S>();
    c.complete(new Future<S>.microtask(() => action(_result)));
    return c.future;
  }

  Future catchError(onError, {test}) => this; // Never an error.
  Future whenComplete(action()) {
    return new Future.microtask(action).then((_) => this);
  }

  Stream asStream() {
    return (new StreamController()
          ..add(_result)
          ..close())
        .stream;
  }

  Future timeout(Duration duration, {onTimeout()?}) {
    return this;
  }
}
