// 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 new List(0);
  } 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;
  int before;
  int after1;
  int after2;

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

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

  // Regression test for fix to issue:
  // https://github.com/dart-lang/sdk/issues/43445
  asyncStart();
  Future.wait<int>(<Future<int>>[]).then((list) {
    Expect.equals(0, list.length);
    Expect.type<List<int>>(list);
    Expect.notType<List<Null>>(list);
    Expect.notType<List<Never>>(list);
    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";
  }).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;
  }).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(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(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(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 testCompleteErrorWithNull() {
  final completer = new Completer<int>();
  Expect.throwsTypeError(() {
    completer.completeError(null);
  });
}

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 = new List(3);
    List cleanup = new List(3);
    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, 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 = new List<Future>(3);
    List cleanup = new List(3);
    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, 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();
  runZoned(() {
    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();
    });
  }, onError: (e, s) {
    int index = e;
    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();
  });
}

void testWaitSyncError2() {
  asyncStart();
  Future.wait([null]).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.wait([null]).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, [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, null]) {
    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("Completer.future", new Completer<int>().future);
  testType("Future.error", new Future<int>.error("ERR")..catchError((_) {}));
}

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.equals(UglyFuture(4), v);
    });

    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.equals(UglyFuture(4), v);

    // We no longer flatten recursively in situations like this.
    var w = new Future.value(42).then((_) => f);
    Expect.equals(UglyFuture(4), 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();
  testCompleteErrorWithNull();

  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>(action(T result), {Function onError}) =>
      _realFuture.then(action, onError: onError);
  Future<T> catchError(Function onError, {bool test(e)}) =>
      _realFuture.catchError(onError, test: test);
  Future<T> whenComplete(action()) => _realFuture.whenComplete(action);
  Future<T> timeout(Duration timeLimit, {void 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;
  final int _badness;
  UglyFuture(int badness)
      : _badness = 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;
  }

  int get hashCode => _badness;
  bool operator ==(Object other) =>
      other is UglyFuture && _badness == other._badness;

  String toString() => "UglyFuture($_badness)";
}
