Chromium Code Reviews| 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); |
| + } |
| + } |
| +} |