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

part of matcher;

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

  TestFailure(this.message);

  String toString() => message;
}

/**
 * Useful utility for nesting match states.
 */

void addStateInfo(Map matchState, Map values) {
  var innerState = new Map.from(matchState);
  matchState.clear();
  matchState['state'] = innerState;
  matchState.addAll(values);
}

/**
 * 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 expectAsync1. By default this is an identity function.
 */
Function wrapAsync = (f, [id]) => f;

/**
 * This is the main assertion function. It asserts that [actual]
 * matches the [matcher]. [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);
}

/**
 * Takes an argument and returns an equivalent matcher.
 * If the argument is already a matcher this does nothing,
 * else if the argument is a function, it generates a predicate
 * function matcher, else it generates an equals matcher.
 */
Matcher wrapMatcher(x) {
  if (x is Matcher) {
    return x;
  } else if (x is Function) {
    return predicate(x);
  } else {
    return equals(x);
  }
}

// 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 or resets to the default the 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 or resets to default 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;
}

