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

import 'dart:async';

import 'package:stack_trace/stack_trace.dart';
import 'package:test/test.dart';

/// Runs [callback] in a microtask callback.
void inMicrotask(void Function() callback) => scheduleMicrotask(callback);

/// Runs [callback] in a one-shot timer callback.
void inOneShotTimer(void Function() callback) => Timer.run(callback);

/// Runs [callback] once in a periodic timer callback.
void inPeriodicTimer(void Function() callback) {
  var count = 0;
  Timer.periodic(Duration(milliseconds: 1), (timer) {
    count++;
    if (count != 5) return;
    timer.cancel();
    callback();
  });
}

/// Runs [callback] within a long asynchronous Future chain.
void inFutureChain(void Function() callback) {
  Future(() {})
      .then((_) => Future(() {}))
      .then((_) => Future(() {}))
      .then((_) => Future(() {}))
      .then((_) => Future(() {}))
      .then((_) => callback())
      .then((_) => Future(() {}));
}

void inNewFuture(void Function() callback) {
  Future(callback);
}

void inSyncFuture(void Function() callback) {
  Future.sync(callback);
}

/// Returns a Future that completes to an error using a completer.
///
/// If [trace] is passed, it's used as the stack trace for the error.
Future completerErrorFuture([StackTrace trace]) {
  var completer = Completer();
  completer.completeError('error', trace);
  return completer.future;
}

/// Returns a Stream that emits an error using a controller.
///
/// If [trace] is passed, it's used as the stack trace for the error.
Stream controllerErrorStream([StackTrace trace]) {
  var controller = StreamController();
  controller.addError('error', trace);
  return controller.stream;
}

/// Runs [callback] within [asyncFn], then converts any errors raised into a
/// [Chain] with [Chain.forTrace].
Future<Chain> chainForTrace(
    void Function(void Function()) asyncFn, void Function() callback) {
  var completer = Completer<Chain>();
  asyncFn(() {
    // We use `new Future.value().then(...)` here as opposed to [new Future] or
    // [new Future.sync] because those methods don't pass the exception through
    // the zone specification before propagating it, so there's no chance to
    // attach a chain to its stack trace. See issue 15105.
    Future.value().then((_) => callback()).catchError(completer.completeError);
  });

  return completer.future
      .catchError((_, StackTrace stackTrace) => Chain.forTrace(stackTrace));
}

/// Runs [callback] in a [Chain.capture] zone and returns a Future that
/// completes to the stack chain for an error thrown by [callback].
///
/// [callback] is expected to throw the string `"error"`.
Future<Chain> captureFuture(void Function() callback) {
  var completer = Completer<Chain>();
  Chain.capture(callback, onError: (error, chain) {
    expect(error, equals('error'));
    completer.complete(chain);
  });
  return completer.future;
}
