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

Side by Side Diff: pkg/matcher/lib/src/iterable_matchers.dart

Issue 306283002: pkg/matcher: cleanup, updates, deprecations, fixes (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of matcher; 5 library matcher.iterable_matchers;
6 6
7 /** 7 import 'core_matchers.dart';
8 * Returns a matcher which matches [Iterable]s in which all elements 8 import 'description.dart';
9 * match the given [matcher]. 9 import 'expect.dart';
10 */ 10 import 'interfaces.dart';
11
12 /// Returns a matcher which matches [Iterable]s in which all elements
13 /// match the given [matcher].
11 Matcher everyElement(matcher) => new _EveryElement(wrapMatcher(matcher)); 14 Matcher everyElement(matcher) => new _EveryElement(wrapMatcher(matcher));
12 15
13 class _EveryElement extends _IterableMatcher { 16 class _EveryElement extends _IterableMatcher {
14 Matcher _matcher; 17 final Matcher _matcher;
15 18
16 _EveryElement(Matcher this._matcher); 19 _EveryElement(Matcher this._matcher);
17 20
18 bool matches(item, Map matchState) { 21 bool matches(item, Map matchState) {
19 if (item is! Iterable) { 22 if (item is! Iterable) {
20 return false; 23 return false;
21 } 24 }
22 var i = 0; 25 var i = 0;
23 for (var element in item) { 26 for (var element in item) {
24 if (!_matcher.matches(element, matchState)) { 27 if (!_matcher.matches(element, matchState)) {
25 addStateInfo(matchState, {'index': i, 'element': element}); 28 addStateInfo(matchState, {'index': i, 'element': element});
26 return false; 29 return false;
27 } 30 }
28 ++i; 31 ++i;
29 } 32 }
30 return true; 33 return true;
31 } 34 }
32 35
33 Description describe(Description description) => 36 Description describe(Description description) =>
34 description.add('every element(').addDescriptionOf(_matcher).add(')'); 37 description.add('every element(').addDescriptionOf(_matcher).add(')');
35 38
36 Description describeMismatch(item, Description mismatchDescription, 39 Description describeMismatch(item, Description mismatchDescription,
37 Map matchState, bool verbose) { 40 Map matchState, bool verbose) {
38 if (matchState['index'] != null) { 41 if (matchState['index'] != null) {
39 var index = matchState['index']; 42 var index = matchState['index'];
40 var element = matchState['element']; 43 var element = matchState['element'];
41 mismatchDescription.add('has value ').addDescriptionOf(element). 44 mismatchDescription.add('has value ').addDescriptionOf(element).
42 add(' which '); 45 add(' which ');
43 var subDescription = new StringDescription(); 46 var subDescription = new StringDescription();
44 _matcher.describeMismatch(element, subDescription, 47 _matcher.describeMismatch(element, subDescription, matchState['state'],
45 matchState['state'], verbose); 48 verbose);
46 if (subDescription.length > 0) { 49 if (subDescription.length > 0) {
47 mismatchDescription.add(subDescription); 50 mismatchDescription.add(subDescription.toString());
48 } else { 51 } else {
49 mismatchDescription.add("doesn't match "); 52 mismatchDescription.add("doesn't match ");
50 _matcher.describe(mismatchDescription); 53 _matcher.describe(mismatchDescription);
51 } 54 }
52 mismatchDescription.add(' at index $index'); 55 mismatchDescription.add(' at index $index');
53 return mismatchDescription; 56 return mismatchDescription;
54 } 57 }
55 return super.describeMismatch(item, mismatchDescription, 58 return super.describeMismatch(item, mismatchDescription,
56 matchState, verbose); 59 matchState, verbose);
57 } 60 }
58 } 61 }
59 62
60 /** 63 /// Returns a matcher which matches [Iterable]s in which at least one
61 * Returns a matcher which matches [Iterable]s in which at least one 64 /// element matches the given [matcher].
62 * element matches the given [matcher].
63 */
64 Matcher anyElement(matcher) => new _AnyElement(wrapMatcher(matcher)); 65 Matcher anyElement(matcher) => new _AnyElement(wrapMatcher(matcher));
65 66
66 class _AnyElement extends _IterableMatcher { 67 class _AnyElement extends _IterableMatcher {
67 Matcher _matcher; 68 final Matcher _matcher;
68 69
69 _AnyElement(this._matcher); 70 _AnyElement(this._matcher);
70 71
71 bool matches(item, Map matchState) { 72 bool matches(item, Map matchState) {
72 return item.any((e) => _matcher.matches(e, matchState)); 73 return item.any((e) => _matcher.matches(e, matchState));
73 } 74 }
74 75
75 Description describe(Description description) => 76 Description describe(Description description) =>
76 description.add('some element ').addDescriptionOf(_matcher); 77 description.add('some element ').addDescriptionOf(_matcher);
77 } 78 }
78 79
79 /** 80 /// Returns a matcher which matches [Iterable]s that have the same
80 * Returns a matcher which matches [Iterable]s that have the same 81 /// length and the same elements as [expected], and in the same order.
81 * length and the same elements as [expected], and in the same order. 82 /// This is equivalent to equals but does not recurse.
82 * This is equivalent to equals but does not recurse.
83 */
84 83
85 Matcher orderedEquals(Iterable expected) => new _OrderedEquals(expected); 84 Matcher orderedEquals(Iterable expected) => new _OrderedEquals(expected);
86 85
87 class _OrderedEquals extends Matcher { 86 class _OrderedEquals extends Matcher {
88 final Iterable _expected; 87 final Iterable _expected;
89 Matcher _matcher; 88 Matcher _matcher;
90 89
91 _OrderedEquals(this._expected) { 90 _OrderedEquals(this._expected) {
92 _matcher = equals(_expected, 1); 91 _matcher = equals(_expected, 1);
93 } 92 }
94 93
95 bool matches(item, Map matchState) => 94 bool matches(item, Map matchState) =>
96 (item is Iterable) && _matcher.matches(item, matchState); 95 (item is Iterable) && _matcher.matches(item, matchState);
97 96
98 Description describe(Description description) => 97 Description describe(Description description) =>
99 description.add('equals ').addDescriptionOf(_expected).add(' ordered'); 98 description.add('equals ').addDescriptionOf(_expected).add(' ordered');
100 99
101 Description describeMismatch(item, Description mismatchDescription, 100 Description describeMismatch(item, Description mismatchDescription,
102 Map matchState, bool verbose) { 101 Map matchState, bool verbose) {
103 if (item is !Iterable) { 102 if (item is !Iterable) {
104 return mismatchDescription.add('is not an Iterable'); 103 return mismatchDescription.add('is not an Iterable');
105 } else { 104 } else {
106 return _matcher.describeMismatch(item, mismatchDescription, 105 return _matcher.describeMismatch(item, mismatchDescription,
107 matchState, verbose); 106 matchState, verbose);
108 } 107 }
109 } 108 }
110 } 109 }
111 110
112 /** 111 /// Returns a matcher which matches [Iterable]s that have the same
113 * Returns a matcher which matches [Iterable]s that have the same 112 /// length and the same elements as [expected], but not necessarily in
114 * length and the same elements as [expected], but not necessarily in 113 /// the same order. Note that this is O(n^2) so should only be used on
115 * the same order. Note that this is O(n^2) so should only be used on 114 /// small objects.
116 * small objects.
117 */
118 Matcher unorderedEquals(Iterable expected) => new _UnorderedEquals(expected); 115 Matcher unorderedEquals(Iterable expected) => new _UnorderedEquals(expected);
119 116
120 class _UnorderedEquals extends _UnorderedMatches { 117 class _UnorderedEquals extends _UnorderedMatches {
121 final List _expectedValues; 118 final List _expectedValues;
122 119
123 _UnorderedEquals(Iterable expected) 120 _UnorderedEquals(Iterable expected)
124 : super(expected.map(equals)), 121 : super(expected.map(equals)),
125 _expectedValues = expected.toList(); 122 _expectedValues = expected.toList();
126 123
127 Description describe(Description description) => 124 Description describe(Description description) =>
128 description 125 description
129 .add('equals ') 126 .add('equals ')
130 .addDescriptionOf(_expectedValues) 127 .addDescriptionOf(_expectedValues)
131 .add(' unordered'); 128 .add(' unordered');
132 } 129 }
133 130
134 /** 131 /// Iterable matchers match against [Iterable]s. We add this intermediate
135 * Iterable matchers match against [Iterable]s. We add this intermediate 132 /// class to give better mismatch error messages than the base Matcher class.
136 * class to give better mismatch error messages than the base Matcher class.
137 */
138 abstract class _IterableMatcher extends Matcher { 133 abstract class _IterableMatcher extends Matcher {
139 const _IterableMatcher(); 134 const _IterableMatcher();
140 Description describeMismatch(item, Description mismatchDescription, 135 Description describeMismatch(item, Description mismatchDescription,
141 Map matchState, bool verbose) { 136 Map matchState, bool verbose) {
142 if (item is! Iterable) { 137 if (item is! Iterable) {
143 return mismatchDescription. 138 return mismatchDescription.
144 addDescriptionOf(item). 139 addDescriptionOf(item).
145 add(' not an Iterable'); 140 add(' not an Iterable');
146 } else { 141 } else {
147 return super.describeMismatch(item, mismatchDescription, matchState, 142 return super.describeMismatch(item, mismatchDescription, matchState,
148 verbose); 143 verbose);
149 } 144 }
150 } 145 }
151 } 146 }
152 147
153 /** 148 /// Returns a matcher which matches [Iterable]s whose elements match the
154 * Returns a matcher which matches [Iterable]s whose elements match the matchers 149 /// matchers in [expected], but not necessarily in the same order.
155 * in [expected], but not necessarily in the same order. 150 ///
156 * 151 /// Note that this is `O(n^2)` and so should only be used on small objects.
157 * Note that this is `O(n^2)` and so should only be used on small objects.
158 */
159 Matcher unorderedMatches(Iterable expected) => new _UnorderedMatches(expected); 152 Matcher unorderedMatches(Iterable expected) => new _UnorderedMatches(expected);
160 153
161 class _UnorderedMatches extends Matcher { 154 class _UnorderedMatches extends Matcher {
162 final List<Matcher> _expected; 155 final List<Matcher> _expected;
163 156
164 _UnorderedMatches(Iterable expected) 157 _UnorderedMatches(Iterable expected)
165 : _expected = expected.map(wrapMatcher).toList(); 158 : _expected = expected.map(wrapMatcher).toList();
166 159
167 String _test(item) { 160 String _test(item) {
168 if (item is! Iterable) return 'not iterable'; 161 if (item is! Iterable) return 'not iterable';
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 description 202 description
210 .add('matches ') 203 .add('matches ')
211 .addAll('[', ', ', ']', _expected) 204 .addAll('[', ', ', ']', _expected)
212 .add(' unordered'); 205 .add(' unordered');
213 206
214 Description describeMismatch(item, Description mismatchDescription, 207 Description describeMismatch(item, Description mismatchDescription,
215 Map matchState, bool verbose) => 208 Map matchState, bool verbose) =>
216 mismatchDescription.add(_test(item)); 209 mismatchDescription.add(_test(item));
217 } 210 }
218 211
219 /** 212 /// A pairwise matcher for iterable. You can pass an arbitrary [comparator]
220 * A pairwise matcher for iterable. You can pass an arbitrary [comparator] 213 /// function that takes an expected and actual argument which will be applied
221 * function that takes an expected and actual argument which will be applied 214 /// to each pair in order. [description] should be a meaningful name for
222 * to each pair in order. [description] should be a meaningful name for 215 /// the comparator.
223 * the comparator. 216 Matcher pairwiseCompare(Iterable expected, bool comparator(a, b),
224 */
225 Matcher pairwiseCompare(Iterable expected, Function comparator,
226 String description) => 217 String description) =>
227 new _PairwiseCompare(expected, comparator, description); 218 new _PairwiseCompare(expected, comparator, description);
228 219
220 typedef bool _Comparator(a, b);
221
229 class _PairwiseCompare extends _IterableMatcher { 222 class _PairwiseCompare extends _IterableMatcher {
230 Iterable _expected; 223 final Iterable _expected;
231 Function _comparator; 224 final _Comparator _comparator;
232 String _description; 225 final String _description;
233 226
234 _PairwiseCompare(this._expected, this._comparator, this._description); 227 _PairwiseCompare(this._expected, this._comparator, this._description);
235 228
236 bool matches(item, Map matchState) { 229 bool matches(item, Map matchState) {
237 if (item is! Iterable) return false; 230 if (item is! Iterable) return false;
238 if (item.length != _expected.length) return false; 231 if (item.length != _expected.length) return false;
239 var iterator = item.iterator; 232 var iterator = item.iterator;
240 var i = 0; 233 var i = 0;
241 for (var e in _expected) { 234 for (var e in _expected) {
242 iterator.moveNext(); 235 iterator.moveNext();
(...skipping 20 matching lines...) Expand all
263 } else { 256 } else {
264 return mismatchDescription. 257 return mismatchDescription.
265 add('has '). 258 add('has ').
266 addDescriptionOf(matchState["actual"]). 259 addDescriptionOf(matchState["actual"]).
267 add(' which is not $_description '). 260 add(' which is not $_description ').
268 addDescriptionOf(matchState["expected"]). 261 addDescriptionOf(matchState["expected"]).
269 add(' at index ${matchState["index"]}'); 262 add(' at index ${matchState["index"]}');
270 } 263 }
271 } 264 }
272 } 265 }
273
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698