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

Unified Diff: lib/unittest/collection_matchers.dart

Issue 10441104: New expectation functions plus convert old tests to use these. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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
« no previous file with comments | « no previous file | lib/unittest/core_matchers.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/unittest/collection_matchers.dart
===================================================================
--- lib/unittest/collection_matchers.dart (revision 0)
+++ lib/unittest/collection_matchers.dart (revision 0)
@@ -0,0 +1,157 @@
+// 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.
+
+/**
+ * Returns a matcher which matches [Collection]s in which all elements
+ * match the given [matcher].
+ */
+Matcher everyElement(matcher) => new _EveryElement(wrapMatcher(matcher));
+
+class _EveryElement extends _CollectionMatcher {
+ Matcher _matcher;
+
+ _EveryElement(Matcher this._matcher);
+
+ bool matches(item) {
+ return item.every((e) => _matcher.matches(e));
+ }
+
+ Description describe(Description description) =>
+ description.add('every element ').addDescriptionOf(_matcher);
+}
+
+/**
+ * Returns a matcher which matches [Collection]s in which at least one
+ * element matches the given [matcher].
+ */
+Matcher someElement(matcher) => new _SomeElement(wrapMatcher(matcher));
+
+class _SomeElement extends _CollectionMatcher {
+ Matcher _matcher;
+
+ _SomeElement(this._matcher);
+
+ bool matches(item) {
+ return item.some( (e) => _matcher.matches(e) );
+ }
+
+ Description describe(Description description) =>
+ description.add('some element ').addDescriptionOf(_matcher);
+}
+
+/**
+ * Returns a matcher which matches [Iterable]s that have the same
+ * length and the same elements as [expected], and in the same order.
+ */
+Matcher orderedEquals(Iterable expected) => new _OrderedEquals(expected);
+
+class _OrderedEquals extends BaseMatcher {
+ Iterable _expected;
+
+ _OrderedEquals(this._expected);
+
+ String _test(item) {
+ return _compareIterables(_expected, item,
+ (expected, actual, location) => expected == actual? null : location);
+ }
+
+ bool matches(item) => (_test(item) == null);
+
+ Description describe(Description description) =>
+ description.add('equals ').addDescriptionOf(_expected).add(' ordered');
+
+ Description describeMismatch(item, Description mismatchDescription) =>
+ mismatchDescription.add(_test(item));
+}
+
+/**
+ * Returns a matcher which matches [Iterable]s that have the same
+ * length and the same elements as [expected], but not necessarily in
+ * the same order. Note that this is O(n^2) so should only be used on
+ * small objects.
+ */
+Matcher unorderedEquals(Iterable expected) =>
+ new _UnorderedEquals(expected);
+
+class _UnorderedEquals extends BaseMatcher {
+ Iterable _expected;
+
+ _UnorderedEquals(Iterable this._expected);
+
+ String _test(item) {
+ if (item is !Iterable) {
+ return 'not iterable';
+ }
+ // Check the lengths are the same.
+ var expectedLength = 0;
+ if (_expected is Collection) {
+ Collection cast = _expected; // "_expected as Collection"
+ expectedLength = cast.length;
+ } else {
+ for (var element in _expected) {
+ ++expectedLength;
+ }
+ }
+ var actualLength = 0;
+ if (item is Collection) {
+ actualLength = item.length;
+ } else {
+ for (var element in item) {
+ ++actualLength;
+ }
+ }
+ if (expectedLength > actualLength) {
+ return 'has too few elements (${actualLength} < ${expectedLength})';
+ } else if (expectedLength < actualLength) {
+ return 'has too many elements (${actualLength} > ${expectedLength})';
+ }
+ List<bool> matched = new List<bool>(actualLength);
+ var expectedPosition = 0;
+ for (var expectedElement in _expected) {
+ var actualPosition = 0;
+ var gotMatch = false;
+ for (var actualElement in item) {
+ if (!matched[actualPosition]) {
+ if (expectedElement == actualElement) {
+ matched[actualPosition] = gotMatch = true;
+ break;
+ }
+ }
+ ++actualPosition;
+ }
+ if (!gotMatch) {
+ return 'has no match for element ${expectedElement} '
+ 'at position ${expectedPosition}';
+ }
+ ++expectedPosition;
+ }
+ return null;
+ }
+
+ bool matches(item) => (_test(item) == null);
+
+ Description describe(Description description) =>
+ description.add('equals ').addDescriptionOf(_expected).add(' unordered');
+
+ Description describeMismatch(item, Description mismatchDescription) =>
+ mismatchDescription.add(_test(item));
+}
+
+/**
+ * Collection matchers match against [Collection]s. We add this intermediate
+ * class to give better mismatch error messages than the base Matcher class.
+ */
+
+/*abstract*/ class _CollectionMatcher extends BaseMatcher {
+ const _CollectionMatcher();
+ Description describeMismatch(item, Description mismatchDescription) {
+ if (item is !Collection) {
+ return mismatchDescription.
+ addDescriptionOf(item).
+ add(' not a collection');
+ } else {
+ return super.describeMismatch(item, mismatchDescription);
+ }
+ }
+}
« no previous file with comments | « no previous file | lib/unittest/core_matchers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698