Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(759)

Unified Diff: pkg/unittest/core_matchers.dart

Issue 11301046: Restructure pkg/unittest and pkg/webdriver to follow the pub conventions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/unittest/core_matchers.dart
===================================================================
--- pkg/unittest/core_matchers.dart (revision 14313)
+++ pkg/unittest/core_matchers.dart (working copy)
@@ -1,698 +0,0 @@
-// 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 unittest;
-
-/**
- * Returns a matcher that matches empty strings, maps or collections.
- */
-const Matcher isEmpty = const _Empty();
-
-class _Empty extends BaseMatcher {
- const _Empty();
- bool matches(item, MatchState matchState) {
- if (item is Map || item is Collection) {
- return item.isEmpty;
- } else if (item is String) {
- return item.length == 0;
- } else {
- return false;
- }
- }
- Description describe(Description description) =>
- description.add('empty');
-}
-
-/** A matcher that matches any null value. */
-const Matcher isNull = const _IsNull();
-
-/** A matcher that matches any non-null value. */
-const Matcher isNotNull = const _IsNotNull();
-
-class _IsNull extends BaseMatcher {
- const _IsNull();
- bool matches(item, MatchState matchState) => item == null;
- Description describe(Description description) =>
- description.add('null');
-}
-
-class _IsNotNull extends BaseMatcher {
- const _IsNotNull();
- bool matches(item, MatchState matchState) => item != null;
- Description describe(Description description) =>
- description.add('not null');
-}
-
-/** A matcher that matches the Boolean value true. */
-const Matcher isTrue = const _IsTrue();
-
-/** A matcher that matches anything except the Boolean value true. */
-const Matcher isFalse = const _IsFalse();
-
-class _IsTrue extends BaseMatcher {
- const _IsTrue();
- bool matches(item, MatchState matchState) => item == true;
- Description describe(Description description) =>
- description.add('true');
-}
-
-class _IsFalse extends BaseMatcher {
- const _IsFalse();
- bool matches(item, MatchState matchState) => item != true;
- Description describe(Description description) =>
- description.add('false');
-}
-
-/**
- * Returns a matches that matches if the value is the same instance
- * as [object] (`===`).
- */
-Matcher same(expected) => new _IsSameAs(expected);
-
-class _IsSameAs extends BaseMatcher {
- final _expected;
- const _IsSameAs(this._expected);
- bool matches(item, MatchState matchState) => item === _expected;
- // If all types were hashable we could show a hash here.
- Description describe(Description description) =>
- description.add('same instance as ').addDescriptionOf(_expected);
-}
-
-/**
- * Returns a matcher that does a deep recursive match. This only works
- * with scalars, Maps and Iterables. To handle cyclic structures a
- * recursion depth [limit] can be provided. The default limit is 100.
- */
-Matcher equals(expected, [limit=100]) =>
- new _DeepMatcher(expected, limit);
-
-class _DeepMatcher extends BaseMatcher {
- final _expected;
- final int _limit;
- var count;
-
- _DeepMatcher(this._expected, [limit = 1000]) : this._limit = limit;
-
- String _compareIterables(expected, actual, matcher, depth) {
- if (actual is !Iterable) {
- return 'is not Iterable';
- }
- var expectedIterator = expected.iterator();
- var actualIterator = actual.iterator();
- var position = 0;
- String reason = null;
- while (reason == null) {
- if (expectedIterator.hasNext) {
- if (actualIterator.hasNext) {
- Description r = matcher(expectedIterator.next(),
- actualIterator.next(),
- 'mismatch at position ${position}',
- depth);
- if (r != null) reason = r.toString();
- ++position;
- } else {
- reason = 'shorter than expected';
- }
- } else if (actualIterator.hasNext) {
- reason = 'longer than expected';
- } else {
- return null;
- }
- }
- return reason;
- }
-
- Description _recursiveMatch(expected, actual, String location, int depth) {
- Description reason = null;
- // If _limit is 1 we can only recurse one level into object.
- bool canRecurse = depth == 0 || _limit > 1;
- if (expected == actual) {
- // Do nothing.
- } else if (depth > _limit) {
- reason = new StringDescription('recursion depth limit exceeded');
- } else {
- if (expected is Iterable && canRecurse) {
- String r = _compareIterables(expected, actual,
- _recursiveMatch, depth+1);
- if (r != null) reason = new StringDescription(r);
- } else if (expected is Map && canRecurse) {
- if (actual is !Map) {
- reason = new StringDescription('expected a map');
- } else if (expected.length != actual.length) {
- reason = new StringDescription('different map lengths');
- } else {
- for (var key in expected.keys) {
- if (!actual.containsKey(key)) {
- reason = new StringDescription('missing map key ');
- reason.addDescriptionOf(key);
- break;
- }
- reason = _recursiveMatch(expected[key], actual[key],
- 'with key <${key}> ${location}', depth+1);
- if (reason != null) {
- break;
- }
- }
- }
- } else {
- // If we have recursed, show the expected value too; if not,
- // expect() will show it for us.
- reason = new StringDescription();
- if (depth > 1) {
- reason.add('expected ').addDescriptionOf(expected).add(' but was ').
- addDescriptionOf(actual);
- } else {
- reason.add('was ').addDescriptionOf(actual);
- }
- }
- }
- if (reason != null && location.length > 0) {
- reason.add(' ').add(location);
- }
- return reason;
- }
-
- String _match(expected, actual) {
- Description reason = _recursiveMatch(expected, actual, '', 0);
- return reason == null ? null : reason.toString();
- }
-
- // TODO(gram) - see if we can make use of matchState here to avoid
- // recursing again in describeMismatch.
- bool matches(item, MatchState matchState) => _match(_expected, item) == null;
-
- Description describe(Description description) =>
- description.addDescriptionOf(_expected);
-
- Description describeMismatch(item, Description mismatchDescription,
- MatchState matchState, bool verbose) =>
- mismatchDescription.add(_match(_expected, item));
-}
-
-/** A matcher that matches any value. */
-const Matcher anything = const _IsAnything();
-
-class _IsAnything extends BaseMatcher {
- const _IsAnything();
- bool matches(item, MatchState matchState) => true;
- Description describe(Description description) =>
- description.add('anything');
-}
-
-/**
- * Returns a matcher that matches if an object is an instance
- * of [type] (or a subtype).
- *
- * As types are not first class objects in Dart we can only
- * approximate this test by using a generic wrapper class.
- *
- * For example, to test whether 'bar' is an instance of type
- * 'Foo', we would write:
- *
- * expect(bar, new isInstanceOf<Foo>());
- *
- * To get better error message, supply a name when creating the
- * Type wrapper; e.g.:
- *
- * expect(bar, new isInstanceOf<Foo>('Foo'));
- *
- * Note that this does not currently work in dart2js; it will
- * match any type, and isNot(new isInstanceof<T>()) will always
- * fail. This is because dart2js currently ignores template type
- * parameters.
- */
-class isInstanceOf<T> extends BaseMatcher {
- final String _name;
- const isInstanceOf([name = 'specified type']) : this._name = name;
- bool matches(obj, MatchState matchState) => obj is T;
- // The description here is lame :-(
- Description describe(Description description) =>
- description.add('an instance of ${_name}');
-}
-
-/**
- * This can be used to match two kinds of objects:
- *
- * * A [Function] that throws an exception when called. The function cannot
- * take any arguments. If you want to test that a function expecting
- * arguments throws, wrap it in another zero-argument function that calls
- * the one you want to test.
- *
- * * A [Future] that completes with an exception. Note that this creates an
- * asynchronous expectation. The call to `expect()` that includes this will
- * return immediately and execution will continue. Later, when the future
- * completes, the actual expectation will run.
- */
-const Matcher throws = const Throws();
-
-/**
- * This can be used to match two kinds of objects:
- *
- * * A [Function] that throws an exception when called. The function cannot
- * take any arguments. If you want to test that a function expecting
- * arguments throws, wrap it in another zero-argument function that calls
- * the one you want to test.
- *
- * * A [Future] that completes with an exception. Note that this creates an
- * asynchronous expectation. The call to `expect()` that includes this will
- * return immediately and execution will continue. Later, when the future
- * completes, the actual expectation will run.
- *
- * In both cases, when an exception is thrown, this will test that the exception
- * object matches [matcher]. If [matcher] is not an instance of [Matcher], it
- * will implicitly be treated as `equals(matcher)`.
- */
-Matcher throwsA(matcher) => new Throws(wrapMatcher(matcher));
-
-/**
- * A matcher that matches a function call against no exception.
- * The function will be called once. Any exceptions will be silently swallowed.
- * The value passed to expect() should be a reference to the function.
- * Note that the function cannot take arguments; to handle this
- * a wrapper will have to be created.
- */
-const Matcher returnsNormally = const _ReturnsNormally();
-
-class Throws extends BaseMatcher {
- final Matcher _matcher;
-
- const Throws([Matcher matcher]) :
- this._matcher = matcher;
-
- bool matches(item, MatchState matchState) {
- if (item is Future) {
- // Queue up an asynchronous expectation that validates when the future
- // completes.
- item.onComplete(expectAsync1((future) {
- if (future.hasValue) {
- expect(false, isTrue, reason:
- "Expected future to fail, but succeeded with '${future.value}'.");
- } else if (_matcher != null) {
- var reason;
- if (future.stackTrace != null) {
- var stackTrace = future.stackTrace.toString();
- stackTrace = " ${stackTrace.replaceAll("\n", "\n ")}";
- reason = "Actual exception trace:\n$stackTrace";
- }
- expect(future.exception, _matcher, reason: reason);
- }
- }));
-
- // It hasn't failed yet.
- return true;
- }
-
- try {
- item();
- return false;
- } catch (e, s) {
- if (_matcher == null ||_matcher.matches(e, matchState)) {
- return true;
- } else {
- matchState.state = {
- 'exception' :e,
- 'stack': s
- };
- return false;
- }
- }
- }
-
- Description describe(Description description) {
- if (_matcher == null) {
- return description.add("throws an exception");
- } else {
- return description.add('throws an exception which matches ').
- addDescriptionOf(_matcher);
- }
- }
-
- Description describeMismatch(item, Description mismatchDescription,
- MatchState matchState,
- bool verbose) {
- if (_matcher == null || matchState.state == null) {
- return mismatchDescription.add(' no exception');
- } else {
- mismatchDescription.
- add(' exception ').addDescriptionOf(matchState.state['exception']);
- if (verbose) {
- mismatchDescription.add(' at ').
- add(matchState.state['stack'].toString());
- }
- mismatchDescription.add(' does not match ').addDescriptionOf(_matcher);
- return mismatchDescription;
- }
- }
-}
-
-class _ReturnsNormally extends BaseMatcher {
- const _ReturnsNormally();
-
- bool matches(f, MatchState matchState) {
- try {
- f();
- return true;
- } catch (e, s) {
- matchState.state = {
- 'exception' : e,
- 'stack': s
- };
- return false;
- }
- }
-
- Description describe(Description description) =>
- description.add("return normally");
-
- Description describeMismatch(item, Description mismatchDescription,
- MatchState matchState,
- bool verbose) {
- mismatchDescription.add(' threw ').
- addDescriptionOf(matchState.state['exception']);
- if (verbose) {
- mismatchDescription.add(' at ').
- add(matchState.state['stack'].toString());
- }
- return mismatchDescription;
- }
-}
-
-/*
- * Matchers for different exception types. Ideally we should just be able to
- * use something like:
- *
- * final Matcher throwsException =
- * const _Throws(const isInstanceOf<Exception>());
- *
- * Unfortunately instanceOf is not working with dart2js.
- *
- * Alternatively, if static functions could be used in const expressions,
- * we could use:
- *
- * bool _isException(x) => x is Exception;
- * final Matcher isException = const _Predicate(_isException, "Exception");
- * final Matcher throwsException = const _Throws(isException);
- *
- * But currently using static functions in const expressions is not supported.
- * For now the only solution for all platforms seems to be separate classes
- * for each exception type.
- */
-
-abstract class TypeMatcher extends BaseMatcher {
- final String _name;
- const TypeMatcher(this._name);
- Description describe(Description description) =>
- description.add(_name);
-}
-
-/** A matcher for FormatExceptions. */
-const isFormatException = const _FormatException();
-
-/** A matcher for functions that throw FormatException. */
-const Matcher throwsFormatException =
- const Throws(isFormatException);
-
-class _FormatException extends TypeMatcher {
- const _FormatException() : super("FormatException");
- bool matches(item, MatchState matchState) => item is FormatException;
-}
-
-/** A matcher for Exceptions. */
-const isException = const _Exception();
-
-/** A matcher for functions that throw Exception. */
-const Matcher throwsException = const Throws(isException);
-
-class _Exception extends TypeMatcher {
- const _Exception() : super("Exception");
- bool matches(item, MatchState matchState) => item is Exception;
-}
-
-/** A matcher for ArgumentErrors. */
-const isArgumentError = const _ArgumentError();
-
-/** A matcher for functions that throw ArgumentError. */
-const Matcher throwsArgumentError =
- const Throws(isArgumentError);
-
-class _ArgumentError extends TypeMatcher {
- const _ArgumentError() : super("ArgumentError");
- bool matches(item, MatchState matchState) => item is ArgumentError;
-}
-
-/** A matcher for IllegalJSRegExpExceptions. */
-const isIllegalJSRegExpException = const _IllegalJSRegExpException();
-
-/** A matcher for functions that throw IllegalJSRegExpException. */
-const Matcher throwsIllegalJSRegExpException =
- const Throws(isIllegalJSRegExpException);
-
-class _IllegalJSRegExpException extends TypeMatcher {
- const _IllegalJSRegExpException() : super("IllegalJSRegExpException");
- bool matches(item, MatchState matchState) => item is IllegalJSRegExpException;
-}
-
-/** A matcher for IndexOutOfRangeExceptions. */
-const isIndexOutOfRangeException = const _IndexOutOfRangeException();
-
-/** A matcher for functions that throw IndexOutOfRangeException. */
-const Matcher throwsIndexOutOfRangeException =
- const Throws(isIndexOutOfRangeException);
-
-class _IndexOutOfRangeException extends TypeMatcher {
- const _IndexOutOfRangeException() : super("IndexOutOfRangeException");
- bool matches(item, MatchState matchState) => item is IndexOutOfRangeException;
-}
-
-/** A matcher for NoSuchMethodErrors. */
-const isNoSuchMethodError = const _NoSuchMethodError();
-
-/** A matcher for functions that throw NoSuchMethodError. */
-const Matcher throwsNoSuchMethodError =
- const Throws(isNoSuchMethodError);
-
-class _NoSuchMethodError extends TypeMatcher {
- const _NoSuchMethodError() : super("NoSuchMethodError");
- bool matches(item, MatchState matchState) => item is NoSuchMethodError;
-}
-
-/** A matcher for NotImplementedExceptions. */
-const isNotImplementedException = const _NotImplementedException();
-
-/** A matcher for functions that throw Exception. */
-const Matcher throwsNotImplementedException =
- const Throws(isNotImplementedException);
-
-class _NotImplementedException extends TypeMatcher {
- const _NotImplementedException() : super("NotImplementedException");
- bool matches(item, MatchState matchState) => item is NotImplementedException;
-}
-
-/** A matcher for NullPointerExceptions. */
-const isNullPointerException = const _NullPointerException();
-
-/** A matcher for functions that throw NotNullPointerException. */
-const Matcher throwsNullPointerException =
- const Throws(isNullPointerException);
-
-class _NullPointerException extends TypeMatcher {
- const _NullPointerException() : super("NullPointerException");
- bool matches(item, MatchState matchState) => item is NullPointerException;
-}
-
-/** A matcher for UnsupportedError. */
-const isUnsupportedError = const _UnsupportedError();
-
-/** A matcher for functions that throw UnsupportedError. */
-const Matcher throwsUnsupportedError = const Throws(isUnsupportedError);
-
-class _UnsupportedError extends TypeMatcher {
- const _UnsupportedError() :
- super("UnsupportedError");
- bool matches(item, MatchState matchState) => item is UnsupportedError;
-}
-
-/** A matcher for Map types. */
-const isMap = const _IsMap();
-
-class _IsMap extends TypeMatcher {
- const _IsMap() : super("Map");
- bool matches(item, MatchState matchState) => item is Map;
-}
-
-/** A matcher for List types. */
-const isList = const _IsList();
-
-class _IsList extends TypeMatcher {
- const _IsList() : super("List");
- bool matches(item, MatchState matchState) => item is List;
-}
-
-/**
- * Returns a matcher that matches if an object has a length property
- * that matches [matcher].
- */
-Matcher hasLength(matcher) =>
- new _HasLength(wrapMatcher(matcher));
-
-class _HasLength extends BaseMatcher {
- final Matcher _matcher;
- const _HasLength([Matcher matcher = null]) : this._matcher = matcher;
-
- bool matches(item, MatchState matchState) {
- return _matcher.matches(item.length, matchState);
- }
-
- Description describe(Description description) =>
- description.add('an object with length of ').
- addDescriptionOf(_matcher);
-
- Description describeMismatch(item, Description mismatchDescription,
- MatchState matchState, bool verbose) {
- super.describeMismatch(item, mismatchDescription, matchState, verbose);
- try {
- // We want to generate a different description if there is no length
- // property. This is harmless code that will throw if no length property
- // but subtle enough that an optimizer shouldn't strip it out.
- if (item.length * item.length >= 0) {
- return mismatchDescription.add(' with length of ').
- addDescriptionOf(item.length);
- }
- } catch (e) {
- return mismatchDescription.add(' has no length property');
- }
- }
-}
-
-/**
- * Returns a matcher that matches if the match argument contains
- * the expected value. For [String]s this means substring matching;
- * for [Map]s is means the map has the key, and for [Collection]s it
- * means the collection has a matching element. In the case of collections,
- * [expected] can itself be a matcher.
- */
-Matcher contains(expected) => new _Contains(expected);
-
-class _Contains extends BaseMatcher {
-
- final _expected;
-
- const _Contains(this._expected);
-
- bool matches(item, MatchState matchState) {
- if (item is String) {
- return item.indexOf(_expected) >= 0;
- } else if (item is Collection) {
- if (_expected is Matcher) {
- return item.some((e) => _expected.matches(e, matchState));
- } else {
- return item.some((e) => e == _expected);
- }
- } else if (item is Map) {
- return item.containsKey(_expected);
- }
- return false;
- }
-
- Description describe(Description description) =>
- description.add('contains ').addDescriptionOf(_expected);
-}
-
-/**
- * Returns a matcher that matches if the match argument is in
- * the expected value. This is the converse of [contains].
- */
-Matcher isIn(expected) => new _In(expected);
-
-class _In extends BaseMatcher {
-
- final _expected;
-
- const _In(this._expected);
-
- bool matches(item, MatchState matchState) {
- if (_expected is String) {
- return _expected.indexOf(item) >= 0;
- } else if (_expected is Collection) {
- return _expected.some((e) => e == item);
- } else if (_expected is Map) {
- return _expected.containsKey(item);
- }
- return false;
- }
-
- Description describe(Description description) =>
- description.add('is in ').addDescriptionOf(_expected);
-}
-
-/**
- * Returns a matcher that uses an arbitrary function that returns
- * true or false for the actual value.
- */
-Matcher predicate(f, [description ='satisfies function']) =>
- new _Predicate(f, description);
-
-class _Predicate extends BaseMatcher {
-
- final _matcher;
- final String _description;
-
- const _Predicate(this._matcher, this._description);
-
- bool matches(item, MatchState matchState) => _matcher(item);
-
- Description describe(Description description) =>
- description.add(_description);
-}
-
-/**
- * A useful utility class for implementing other matchers through inheritance.
- * Derived classes should call the base constructor with a feature name and
- * description, and an instance matcher, and should implement the
- * [featureValueOf] abstract method.
- *
- * The feature description will typically describe the item and the feature,
- * while the feature name will just name the feature. For example, we may
- * have a Widget class where each Widget has a price; we could make a
- * FeatureMatcher that can make assertions about prices with:
- *
- * class HasPrice extends FeatureMatcher {
- * const HasPrice(matcher) :
- * super("Widget with price that is", "price", matcher);
- * featureValueOf(actual) => actual.price;
- * }
- *
- * and then use this for example like:
- *
- * expect(inventoryItem, new HasPrice(greaterThan(0)));
- */
-class CustomMatcher extends BaseMatcher {
- final String _featureDescription;
- final String _featureName;
- final Matcher _matcher;
-
- const CustomMatcher(this._featureDescription, this._featureName,
- this._matcher);
-
- /** Override this to extract the interesting feature.*/
- featureValueOf(actual) => actual;
-
- bool matches(item, MatchState matchState) {
- var f = featureValueOf(item);
- if (_matcher.matches(f, matchState)) return true;
- matchState.state = { 'innerState': matchState.state, 'feature': f };
- return false;
- }
-
- Description describe(Description description) =>
- description.add(_featureDescription).add(' ').addDescriptionOf(_matcher);
-
- Description describeMismatch(item, Description mismatchDescription,
- MatchState matchState, bool verbose) {
- mismatchDescription.add(_featureName).add(' ');
- _matcher.describeMismatch(matchState.state['feature'], mismatchDescription,
- matchState.state['innerState'], verbose);
- return mismatchDescription;
- }
-}

Powered by Google App Engine
This is Rietveld 408576698