// 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: (dynamic 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;
  }
}
