Index: lib/unittest/map_matchers.dart |
=================================================================== |
--- lib/unittest/map_matchers.dart (revision 0) |
+++ lib/unittest/map_matchers.dart (revision 0) |
@@ -0,0 +1,124 @@ |
+// 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 that matches empty maps. |
+ */ |
+IMatcher emptyMap() => new _EmptyMap(); |
Bob Nystrom
2012/05/30 23:23:51
Can we just have a single isEmpty matcher? Why als
gram
2012/06/01 17:33:15
I combined the matchers for string, map and collec
Bob Nystrom
2012/06/01 18:22:22
Agreed. We do lots of other type tests in this lib
|
+ |
+class _EmptyMap extends _MapMatcher { |
+ bool matches(item) => item is Map && item.isEmpty(); |
+ IDescription describe(IDescription description) => |
+ description.append('empty'); |
+} |
+ |
+/** |
+ * Returns a matcher that matches maps containing the given [key] |
+ */ |
+IMatcher mapContainsKey(key) => new _MapContainsKey(key); |
+ |
+class _MapContainsKey extends _MapMatcher { |
+ var _key; |
+ |
+ _MapContainsKey(this._key); |
+ |
+ bool matches(item) => item is Map && item.containsKey(_key); |
Bob Nystrom
2012/05/30 23:23:51
Does it add value to test the type here, or should
gram
2012/06/01 17:33:15
Done.
|
+ |
+ IDescription describe(IDescription description) => |
+ description.append('contains key ').appendDescriptionOf(_key); |
+} |
+ |
+/** |
+ * Returns a matcher which matches maps containing the given [value]. |
+ */ |
+IMatcher mapContainsValue(value) => new _MapContainsValue(value); |
+ |
+class _MapContainsValue extends _MapMatcher { |
+ var _value; |
+ |
+ _MapContainsValue(this._value); |
+ |
+ bool matches(item) => item is Map && item.containsValue(_value); |
+ IDescription describe(IDescription description) => |
+ description.append('contains value ').appendDescriptionOf(_value); |
+} |
+ |
+/** |
+ * Returns a matcher which matches maps containing the key-value pair |
+ * with [key] => [value]. |
+ */ |
+IMatcher mapContains(key, value) => |
+ new _MapContainsMapping(key, wrapMatcher(value)); |
+ |
+class _MapContainsMapping extends _MapMatcher { |
+ var _key; |
+ IMatcher _valueMatcher; |
+ |
+ _MapContainsMapping(this._key, IMatcher this._valueMatcher); |
+ |
+ bool matches(item) => |
+ item is Map && |
+ item.containsKey(_key) && |
+ _valueMatcher.matches(item[_key]); |
+ |
+ IDescription describe(IDescription description) => |
Bob Nystrom
2012/05/30 23:23:51
I would use a full {} body for this since it's mul
gram
2012/06/01 17:33:15
Done.
|
+ description.append('contains pair '). |
+ appendDescriptionOf(_key). |
+ append(' => '). |
+ appendDescriptionOf(_valueMatcher); |
+ |
+ IDescription describeMismatch(item, IDescription mismatchDescription) { |
+ if (item is Map) { |
+ if (!item.containsKey(_key)) { |
+ return mismatchDescription. |
+ appendDescriptionOf(item). |
Bob Nystrom
2012/05/30 23:23:51
Indent another 2.
gram
2012/06/01 17:33:15
Done.
|
+ append("' doesn't contain key '"). |
+ appendDescriptionOf(_key); |
+ } else { |
+ return mismatchDescription. |
+ append(' contains key '). |
Bob Nystrom
2012/05/30 23:23:51
Ditto.
gram
2012/06/01 17:33:15
Done.
|
+ appendDescriptionOf(_key). |
+ append(' but with value '); |
+ _valueMatcher.describeMismatch(item[_key], mismatchDescription); |
+ return mismatchDescription; |
+ } |
+ } else { |
+ return super.describeMismatch(item, mismatchDescription); |
+ } |
+ } |
+} |
+ |
+/** |
+ * Returns a matcher which matches maps whose length matches |
+ * the given [matcher]. This is different from hasLength(), which |
+ * works on any types that have length properties. |
+ */ |
+IMatcher mapLength(matcher) => new _MapLength(wrapMatcher(matcher)); |
Bob Nystrom
2012/05/30 23:23:51
This feels unnecessary to me. Can we remove it?
gram
2012/06/01 17:33:15
Done.
|
+ |
+class _MapLength extends _MapMatcher { |
+ IMatcher _matcher; |
+ |
+ _MapLength(this._matcher); |
+ |
+ bool matches(item) => item is Map && _matcher.matches(item.length); |
+ |
+ IDescription describe(IDescription description) => |
+ description.append('map length '). |
+ appendDescriptionOf(_matcher); |
+} |
+ |
+// Map matchers match against a Map. We add this intermediate |
Bob Nystrom
2012/05/30 23:23:51
Make this a doc comment.
gram
2012/06/01 17:33:15
Removed.
|
+// class to give better mismatch error messages than the base Matcher class. |
+ |
+class _MapMatcher extends Matcher { |
+ IDescription describeMismatch(item, IDescription mismatchDescription) { |
+ if (!(item is Map)) { |
+ return mismatchDescription. |
+ appendDescriptionOf(item). |
+ append(' not a map'); |
+ } else { |
+ return super.describeMismatch(item, mismatchDescription); |
+ } |
+ } |
+} |