// 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 matcher.expect;

import 'core_matchers.dart';
import 'description.dart';
import 'interfaces.dart';
import 'util.dart';

/// The objects thrown by the default failure handler.
class TestFailure extends Error {
  final String message;

  TestFailure(this.message);

  String toString() => message;
}

/// Failed matches are reported using a default IFailureHandler.
/// The default implementation simply throws [TestFailure]s;
/// this can be replaced by some other implementation of
/// IFailureHandler by calling configureExpectHandler.
abstract class FailureHandler {
  /// This handles failures given a textual decription
  void fail(String reason);

  /// This handles failures given the actual [value], the [matcher]
  /// the [reason] (argument from [expect]), some additonal [matchState]
  /// generated by the [matcher], and a verbose flag which controls in
  /// some cases how much [matchState] information is used. It will use
  /// these to create a detailed error message (typically by calling
  /// an [ErrorFormatter]) and then call [fail] with this message.
  void failMatch(
      actual, Matcher matcher, String reason, Map matchState, bool verbose);
}

/// The ErrorFormatter type is used for functions that
/// can be used to build up error reports upon [expect] failures.
/// There is one built-in implementation ([defaultErrorFormatter])
/// which is used by the default failure handler. If the failure handler
/// is replaced it may be desirable to replace the [stringDescription]
/// error formatter with another.
typedef String ErrorFormatter(
    actual, Matcher matcher, String reason, Map matchState, bool verbose);

/// This Function is used by certain Matchers to catch certain exceptions.
///
/// Some matchers, like those for Futures and exception testing,
/// can fail in asynchronous sections, and throw exceptions.
/// A user of this library will typically want to catch and handle
/// such exceptions. The [wrapAsync] property is a function that
/// can wrap callbacks used by these Matchers so that they can be
/// used safely. For example, the unittest library will set this
/// to be `expectAsync`. By default this is an identity function.
Function wrapAsync = (Function f, [id]) => f;

/// Assert that [actual] matches [matcher].
///
/// This is the main assertion function. [reason] is optional and is typically
/// not supplied, as a reason is generated from the matcher; if [reason]
/// is included it is appended to the reason generated by the matcher.
///
/// [matcher] can be a value in which case it will be wrapped in an
/// [equals] matcher.
///
/// If the assertion fails, then the default behavior is to throw a
/// [TestFailure], but this behavior can be changed by calling
/// [configureExpectFailureHandler] and providing an alternative handler that
/// implements the [IFailureHandler] interface. It is also possible to
/// pass a [failureHandler] to [expect] as a final parameter for fine-
/// grained control.
///
/// In some cases extra diagnostic info can be produced on failure (for
/// example, stack traces on mismatched exceptions). To enable these,
/// [verbose] should be specified as true;
void expect(actual, matcher,
    {String reason, FailureHandler failureHandler, bool verbose: false}) {
  matcher = wrapMatcher(matcher);
  bool doesMatch;
  var matchState = {};
  try {
    doesMatch = matcher.matches(actual, matchState);
  } catch (e, trace) {
    doesMatch = false;
    if (reason == null) {
      reason = '${(e is String) ? e : e.toString()} at $trace';
    }
  }
  if (!doesMatch) {
    if (failureHandler == null) {
      failureHandler = getOrCreateExpectFailureHandler();
    }
    failureHandler.failMatch(actual, matcher, reason, matchState, verbose);
  }
}

void fail(String message, {FailureHandler failureHandler}) {
  if (failureHandler == null) {
    failureHandler = getOrCreateExpectFailureHandler();
  }
  failureHandler.fail(message);
}

// The handler for failed asserts.
FailureHandler _assertFailureHandler = null;

// The default failure handler that throws [TestFailure]s.
class DefaultFailureHandler implements FailureHandler {
  DefaultFailureHandler() {
    if (_assertErrorFormatter == null) {
      _assertErrorFormatter = _defaultErrorFormatter;
    }
  }
  void fail(String reason) {
    throw new TestFailure(reason);
  }
  void failMatch(
      actual, Matcher matcher, String reason, Map matchState, bool verbose) {
    fail(_assertErrorFormatter(actual, matcher, reason, matchState, verbose));
  }
}

/// Changes the default failure handler for [expect].
///
/// [handler] is a reference to the new handler; if this is omitted
/// or null then the failure handler is reset to the default, which
/// throws [TestFailure]s on [expect] assertion failures.
void configureExpectFailureHandler([FailureHandler handler = null]) {
  if (handler == null) {
    handler = new DefaultFailureHandler();
  }
  _assertFailureHandler = handler;
}

FailureHandler getOrCreateExpectFailureHandler() {
  if (_assertFailureHandler == null) {
    configureExpectFailureHandler();
  }
  return _assertFailureHandler;
}

// The error message formatter for failed asserts.
ErrorFormatter _assertErrorFormatter = null;

// The default error formatter implementation.
String _defaultErrorFormatter(
    actual, Matcher matcher, String reason, Map matchState, bool verbose) {
  var description = new StringDescription();
  description.add('Expected: ').addDescriptionOf(matcher).add('\n');
  description.add('  Actual: ').addDescriptionOf(actual).add('\n');

  var mismatchDescription = new StringDescription();
  matcher.describeMismatch(actual, mismatchDescription, matchState, verbose);

  if (mismatchDescription.length > 0) {
    description.add('   Which: ${mismatchDescription}\n');
  }
  if (reason != null) {
    description.add(reason).add('\n');
  }
  return description.toString();
}

/// Changes the failure message formatter for expect().
///
/// [formatter] is a reference to the new formatter; if this is omitted or
/// null then the failure formatter is reset to the default. The new
/// formatter is returned; this allows custom expect handlers to easily
/// get a reference to the default formatter.
ErrorFormatter configureExpectFormatter([ErrorFormatter formatter = null]) {
  if (formatter == null) {
    formatter = _defaultErrorFormatter;
  }
  return _assertErrorFormatter = formatter;
}
