// Copyright (c) 2011, 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 futures_test;

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

Future testWaitEmpty() {
  final futures = new List<Future>();
  return Future.wait(futures);
}

Future testCompleteAfterWait() {
  final futures = new List<Future>();
  final c = new Completer<Object>();
  futures.add(c.future);
  Future future = Future.wait(futures);
  c.complete(null);
  return future;
}

Future testCompleteBeforeWait() {
  final futures = new List<Future>();
  final c = new Completer();
  futures.add(c.future);
  c.complete(null);
  return Future.wait(futures);
}

Future testWaitWithMultipleValues() {
  final futures = new List<Future>();
  final c1 = new Completer();
  final c2 = new Completer();
  futures.add(c1.future);
  futures.add(c2.future);
  c1.complete(1);
  c2.complete(2);
  return Future.wait(futures).then((values) {
    Expect.listEquals([1, 2], values);
  });
}

Future testWaitWithSingleError() {
  final futures = new List<Future>();
  final c1 = new Completer();
  final c2 = new Completer();
  futures.add(c1.future);
  futures.add(c2.future);
  c1.complete();
  c2.completeError('correct error');

  return Future.wait(futures).then((_) {
    throw 'incorrect error';
  }).catchError((error, stackTrace) {
    Expect.equals('correct error', error);
    Expect.isNotNull(stackTrace);
  });
}

Future testWaitWithMultipleErrors() {
  final futures = new List<Future>();
  final c1 = new Completer();
  final c2 = new Completer();
  futures.add(c1.future);
  futures.add(c2.future);
  c1.completeError('correct error');
  c2.completeError('incorrect error 1');

  return Future.wait(futures).then((_) {
    throw 'incorrect error 2';
  }).catchError((error, stackTrace) {
    Expect.equals('correct error', error);
    Expect.isNotNull(stackTrace);
  });
}

// Regression test for https://github.com/dart-lang/sdk/issues/41656
Future testWaitWithErrorAndNonErrorEager() {
  return Future(() {
    var f1 = Future(() => throw "Error");
    var f2 = Future(() => 3);
    return Future.wait([f1, f2], eagerError: true);
  }).then((_) => 0, onError: (_) => -1);
}

Future testWaitWithMultipleErrorsEager() {
  final futures = new List<Future>();
  final c1 = new Completer();
  final c2 = new Completer();
  futures.add(c1.future);
  futures.add(c2.future);
  c1.completeError('correct error');
  c2.completeError('incorrect error 1');

  return Future.wait(futures, eagerError: true).then((_) {
    throw 'incorrect error 2';
  }).catchError((error, stackTrace) {
    Expect.equals('correct error', error);
    Expect.isNotNull(stackTrace);
  });
}

StackTrace get currentStackTrace {
  try {
    throw 0;
  } catch (e, st) {
    return st;
  }
  throw "unreachable";
}

Future testWaitWithSingleErrorWithStackTrace() {
  final futures = new List<Future>();
  final c1 = new Completer();
  final c2 = new Completer();
  futures.add(c1.future);
  futures.add(c2.future);
  c1.complete();
  c2.completeError('correct error', currentStackTrace);

  return Future.wait(futures).then((_) {
    throw 'incorrect error';
  }).catchError((error, stackTrace) {
    Expect.equals('correct error', error);
    Expect.isNotNull(stackTrace);
  });
}

Future testWaitWithMultipleErrorsWithStackTrace() {
  final futures = new List<Future>();
  final c1 = new Completer();
  final c2 = new Completer();
  futures.add(c1.future);
  futures.add(c2.future);
  c1.completeError('correct error', currentStackTrace);
  c2.completeError('incorrect error 1');

  return Future.wait(futures).then((_) {
    throw 'incorrect error 2';
  }).catchError((error, stackTrace) {
    Expect.equals('correct error', error);
    Expect.isNotNull(stackTrace);
  });
}

Future testWaitWithMultipleErrorsWithStackTraceEager() {
  final futures = new List<Future>();
  final c1 = new Completer();
  final c2 = new Completer();
  futures.add(c1.future);
  futures.add(c2.future);
  c1.completeError('correct error', currentStackTrace);
  c2.completeError('incorrect error 1');

  return Future.wait(futures, eagerError: true).then((_) {
    throw 'incorrect error 2';
  }).catchError((error, stackTrace) {
    Expect.equals('correct error', error);
    Expect.isNotNull(stackTrace);
  });
}

Future testEagerWait() {
  var st;
  try {
    throw 0;
  } catch (e, s) {
    st = s;
  }
  final c1 = new Completer();
  final c2 = new Completer();
  final futures = <Future>[c1.future, c2.future];
  final waited = Future.wait(futures, eagerError: true);
  final result = waited.then((v) {
    throw "should not be called";
  }, onError: (e, s) {
    Expect.equals(e, 42);
    Expect.identical(st, s);
  }).whenComplete(() {
    return new Future(() => true);
  });
  c1.completeError(42, st);
  return result;
}

Future testForEachEmpty() {
  return Future.forEach([], (_) {
    throw 'should not be called';
  });
}

Future testForEach() {
  final seen = <int>[];
  return Future.forEach([1, 2, 3, 4, 5], (n) {
    seen.add(n);
    return new Future.value();
  }).then((_) => Expect.listEquals([1, 2, 3, 4, 5], seen));
}

Future testForEachSync() {
  final seen = <int>[];
  return Future.forEach([1, 2, 3, 4, 5], seen.add)
      .then((_) => Expect.listEquals([1, 2, 3, 4, 5], seen));
}

Future testForEachWithException() {
  final seen = <int>[];
  return Future.forEach([1, 2, 3, 4, 5], (n) {
    if (n == 4) throw 'correct exception';
    seen.add(n);
    return new Future.value();
  }).then((_) {
    throw 'incorrect exception';
  }).catchError((error) {
    Expect.equals('correct exception', error);
  });
}

Future testDoWhile() {
  var count = 0;
  return Future.doWhile(() {
    count++;
    return new Future(() => count < 10);
  }).then((_) => Expect.equals(10, count));
}

Future testDoWhileSync() {
  var count = 0;
  return Future.doWhile(() {
    count++;
    return count < 10;
  }).then((_) => Expect.equals(10, count));
}

Future testDoWhileWithException() {
  var count = 0;
  return Future.doWhile(() {
    count++;
    if (count == 4) throw 'correct exception';
    return new Future(() => true);
  }).then((_) {
    throw 'incorrect exception';
  }).catchError((error) {
    Expect.equals('correct exception', error);
  }).whenComplete(() {
    return new Future(() => false);
  });
}

main() {
  final futures = new List<Future>();

  futures.add(testWaitEmpty());
  futures.add(testCompleteAfterWait());
  futures.add(testCompleteBeforeWait());
  futures.add(testWaitWithMultipleValues());
  futures.add(testWaitWithSingleError());
  futures.add(testWaitWithMultipleErrors());
  futures.add(testWaitWithErrorAndNonErrorEager());
  futures.add(testWaitWithMultipleErrorsEager());
  futures.add(testWaitWithSingleErrorWithStackTrace());
  futures.add(testWaitWithMultipleErrorsWithStackTrace());
  futures.add(testWaitWithMultipleErrorsWithStackTraceEager());
  futures.add(testEagerWait());
  futures.add(testForEachEmpty());
  futures.add(testForEach());
  futures.add(testForEachSync());
  futures.add(testForEachWithException());
  futures.add(testDoWhile());
  futures.add(testDoWhileSync());
  futures.add(testDoWhileWithException());

  asyncStart();
  Future.wait(futures).then((List list) {
    Expect.equals(19, list.length);
    asyncEnd();
  });
}
