// Copyright (c) 2013, 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.

/// This library is used for testing asynchronous tests.
/// If a test is asynchronous, it needs to notify the testing driver
/// about this (otherwise tests may get reported as passing after main()
/// finished even if the asynchronous operations fail).
///
/// This library provides four methods
///  - asyncStart(): Needs to be called before an asynchronous operation is
///                  scheduled.
///  - asyncEnd(): Needs to be called as soon as the asynchronous operation
///                ended.
///  - asyncSuccess(_): Variant of asyncEnd useful together with Future.then.
///  - asyncTest(f()): Helper method that wraps a computation that returns a
///                    Future with matching calls to asyncStart() and
///                    asyncSuccess(_).
/// After every asyncStart() called is matched with a corresponding
/// asyncEnd() or asyncSuccess(_) call, the testing driver will be notified that
/// the tests is done.
library async_helper;

import 'dart:async';

import 'package:expect/expect.dart';

bool _initialized = false;
int _asyncLevel = 0;

Exception _buildException(String msg) {
  return Exception('Fatal: $msg. This is most likely a bug in your test.');
}

/// Call this method before an asynchronous test is created.
///
/// If [count] is provided, expect [count] [asyncEnd] calls instead of just one.
void asyncStart([int count = 1]) {
  if (count <= 0) return;
  if (_initialized && _asyncLevel == 0) {
    throw _buildException('asyncStart() was called even though we are done '
        'with testing.');
  }
  if (!_initialized) {
    print('unittest-suite-wait-for-done');
    _initialized = true;
  }
  _asyncLevel += count;
}

/// Call this after an asynchronous test has ended successfully.
void asyncEnd() {
  if (_asyncLevel <= 0) {
    if (!_initialized) {
      throw _buildException('asyncEnd() was called before asyncStart().');
    } else {
      throw _buildException('asyncEnd() was called more often than '
          'asyncStart().');
    }
  }
  _asyncLevel--;
  if (_asyncLevel == 0) {
    print('unittest-suite-success');
  }
}

/// Call this after an asynchronous test has ended successfully. This is a helper
/// for calling [asyncEnd].
///
/// This method intentionally has a signature that matches `Future.then` as a
/// convenience for calling [asyncEnd] when a `Future` completes without error,
/// like this:
/// ```dart
/// asyncStart();
/// Future result = test();
/// result.then(asyncSuccess);
/// ```
void asyncSuccess(void _) {
  asyncEnd();
}

/// Helper method for performing asynchronous tests involving `Future`.
///
/// The function [test] must return a `Future` which completes without error
/// when the test is successful.
Future<void> asyncTest(Function() test) {
  asyncStart();
  return test().then(asyncSuccess);
}

/// Verifies that the asynchronous [result] throws a [T].
///
/// Fails if [result] completes with a value, or it completes with
/// an error which is not a [T].
///
/// Returns the accepted thrown object.
/// For example, to check the content of the thrown object,
/// you could write this:
/// ```
/// var e = await asyncExpectThrows<MyException>(asyncExpression)
/// Expect.isTrue(e.myMessage.contains("WARNING"));
/// ```
/// If `result` completes with an [ExpectException] error from another
/// failed test expectation, that error cannot be caught and accepted.
Future<T> asyncExpectThrows<T extends Object>(Future<void> result,
    [String reason = ""]) {
  // Delay computing the header text until the test has failed.
  // The header computation uses complicated language features,
  // and language tests should avoid doing complicated things
  // until after the actual test has had a chance to succeed.
  String header() {
    // Handle null being passed in from legacy code
    // while also avoiding producing an unnecessary null check warning here.
    if ((reason as dynamic) == null) reason = "";
    // Only include the type in the message if it's not `Object`.
    var type = Object() is! T ? "<$T>" : "";
    return "asyncExpectThrows$type($reason):";
  }

  // Unsound null-safety check.
  if ((result as dynamic) == null) {
    Expect.testError("${header()} result Future must not be null.");
  }

  // TODO(rnystrom): It might useful to validate that T is not bound to
  // ExpectException since that won't work.

  asyncStart();
  return result.then<T>((_) {
    throw ExpectException("${header()} Did not throw.");
  }, onError: (error, stack) {
    // A test failure doesn't count as throwing. Rethrow it.
    if (error is ExpectException) throw error;

    if (error is! T) {
      // Throws something unexpected.
      throw ExpectException(
          "${header()} Unexpected '${Error.safeToString(error)}'\n$stack");
    }

    asyncEnd();
    return error;
  });
}

/// Checks that the asynchronous [result] throws a [T] if and only if
/// [condition] is `true`.
///
/// When [condition] is `false`, [result] is expected to complete without
/// errors.
Future<T?> asyncExpectThrowsWhen<T extends Object>(
    bool condition, Future<void> result,
    [String reason = ""]) {
  return condition
      ? asyncExpectThrows<T>(result, reason)
      : result.then<T?>((_) => null);
}
