// 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.

/// Helper utilities for testing.
library;

import 'dart:async';

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

/// A zero-millisecond timer should wait until after all microtasks.
Future flushMicrotasks() => Future<void>.delayed(Duration.zero);

typedef OptionalArgAction = void Function([dynamic a, dynamic b]);

/// A generic unreachable callback function.
///
/// Returns a function that fails the test if it is ever called.
OptionalArgAction unreachable(String name) =>
    ([a, b]) => fail('Unreachable: $name');

/// A matcher that runs a callback in its own zone and asserts that that zone
/// emits an error that matches [matcher].
Matcher throwsZoned(Matcher matcher) => predicate((void Function() callback) {
      var firstError = true;
      runZonedGuarded(
          callback,
          expectAsync2((error, stackTrace) {
            if (firstError) {
              expect(error, matcher);
              firstError = false;
            } else {
              registerException(error, stackTrace);
            }
          }, max: -1));
      return true;
    });

/// A matcher that runs a callback in its own zone and asserts that that zone
/// emits a [TypeError].
final throwsZonedTypeError = throwsZoned(isA<TypeError>());

/// A matcher that matches a callback or future that throws a [TypeError].
final throwsTypeError = throwsA(isA<TypeError>());

/// A badly behaved stream which throws if it's ever listened to.
///
/// Can be used to test cases where a stream should not be used.
class UnusableStream<T> extends Stream<T> {
  @override
  StreamSubscription<T> listen(void Function(T event)? onData,
      {Function? onError, void Function()? onDone, bool? cancelOnError}) {
    throw UnimplementedError('Gotcha!');
  }
}

/// A dummy [StreamSink] for testing the routing of the [done] and [close]
/// futures.
///
/// The [completer] field allows the user to control the future returned by
/// [done] and [close].
class CompleterStreamSink<T> implements StreamSink<T> {
  final completer = Completer<void>();

  @override
  Future get done => completer.future;

  @override
  void add(T event) {}
  @override
  void addError(Object error, [StackTrace? stackTrace]) {}
  @override
  Future addStream(Stream<T> stream) async {}
  @override
  Future close() => completer.future;
}

/// A [StreamSink] that collects all events added to it as results.
///
/// This is used for testing code that interacts with sinks.
class TestSink<T> implements StreamSink<T> {
  /// The results corresponding to events that have been added to the sink.
  final results = <Result<T>>[];

  /// Whether [close] has been called.
  bool get isClosed => _isClosed;
  var _isClosed = false;

  @override
  Future get done => _doneCompleter.future;
  final _doneCompleter = Completer<void>();

  final void Function() _onDone;

  /// Creates a new sink.
  ///
  /// If [onDone] is passed, it's called when the user calls [close]. Its result
  /// is piped to the [done] future.
  TestSink({void Function()? onDone}) : _onDone = onDone ?? (() {});

  @override
  void add(T event) {
    results.add(Result<T>.value(event));
  }

  @override
  void addError(Object error, [StackTrace? stackTrace]) {
    results.add(Result<T>.error(error, stackTrace));
  }

  @override
  Future addStream(Stream<T> stream) {
    var completer = Completer.sync();
    stream.listen(add, onError: addError, onDone: completer.complete);
    return completer.future;
  }

  @override
  Future close() {
    _isClosed = true;
    _doneCompleter.complete(Future.microtask(_onDone));
    return done;
  }
}
