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

Side by Side Diff: pkg/unittest/lib/src/collection_matchers.dart

Issue 14173003: Remove Collection, Collections and clean up List/Set/Queue implementations of retain/remove. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 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
« no previous file with comments | « pkg/unittest/lib/matcher.dart ('k') | pkg/unittest/lib/src/core_matchers.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of matcher;
6
7 /**
8 * Returns a matcher which matches [Collection]s in which all elements
9 * match the given [matcher].
10 */
11 Matcher everyElement(matcher) => new _EveryElement(wrapMatcher(matcher));
12
13 class _EveryElement extends _CollectionMatcher {
14 Matcher _matcher;
15
16 _EveryElement(Matcher this._matcher);
17
18 bool matches(item, MatchState matchState) {
19 if (item is! Iterable) {
20 return false;
21 }
22 var i = 0;
23 for (var element in item) {
24 if (!_matcher.matches(element, matchState)) {
25 matchState.state = {
26 'index': i,
27 'element': element,
28 'state': matchState.state
29 };
30 return false;
31 }
32 ++i;
33 }
34 return true;
35 }
36
37 Description describe(Description description) =>
38 description.add('every element ').addDescriptionOf(_matcher);
39
40 Description describeMismatch(item, Description mismatchDescription,
41 MatchState matchState, bool verbose) {
42 if (matchState.state != null) {
43 var index = matchState.state['index'];
44 var element = matchState.state['element'];
45 return _matcher.describeMismatch(element, mismatchDescription,
46 matchState.state['state'], verbose).add(' at position $index');
47 }
48 return super.describeMismatch(item, mismatchDescription,
49 matchState, verbose);
50 }
51 }
52
53 /**
54 * Returns a matcher which matches [Collection]s in which at least one
55 * element matches the given [matcher].
56 */
57 Matcher someElement(matcher) => new _SomeElement(wrapMatcher(matcher));
58
59 class _SomeElement extends _CollectionMatcher {
60 Matcher _matcher;
61
62 _SomeElement(this._matcher);
63
64 bool matches(item, MatchState matchState) {
65 return item.any((e) => _matcher.matches(e, matchState));
66 }
67
68 Description describe(Description description) =>
69 description.add('some element ').addDescriptionOf(_matcher);
70 }
71
72 /**
73 * Returns a matcher which matches [Iterable]s that have the same
74 * length and the same elements as [expected], and in the same order.
75 * This is equivalent to equals but does not recurse.
76 */
77
78 Matcher orderedEquals(Iterable expected) => new _OrderedEquals(expected);
79
80 class _OrderedEquals extends BaseMatcher {
81 final Iterable _expected;
82 Matcher _matcher;
83
84 _OrderedEquals(this._expected) {
85 _matcher = equals(_expected, 1);
86 }
87
88 bool matches(item, MatchState matchState) =>
89 (item is Iterable) && _matcher.matches(item, matchState);
90
91 Description describe(Description description) =>
92 description.add('equals ').addDescriptionOf(_expected).add(' ordered');
93
94 Description describeMismatch(item, Description mismatchDescription,
95 MatchState matchState, bool verbose) {
96 if (item is !Iterable) {
97 return mismatchDescription.add('not an Iterable');
98 } else {
99 return _matcher.describeMismatch(item, mismatchDescription,
100 matchState, verbose);
101 }
102 }
103 }
104 /**
105 * Returns a matcher which matches [Iterable]s that have the same
106 * length and the same elements as [expected], but not necessarily in
107 * the same order. Note that this is O(n^2) so should only be used on
108 * small objects.
109 */
110 Matcher unorderedEquals(Iterable expected) =>
111 new _UnorderedEquals(expected);
112
113 class _UnorderedEquals extends BaseMatcher {
114 Iterable _expected;
115
116 _UnorderedEquals(Iterable this._expected);
117
118 String _test(item) {
119 if (item is !Iterable) {
120 return 'not iterable';
121 }
122 // Check the lengths are the same.
123 var expectedLength = 0;
124 if (_expected is Collection) {
125 Collection cast = _expected; // "_expected as Collection"
126 expectedLength = cast.length;
127 } else {
128 for (var element in _expected) {
129 ++expectedLength;
130 }
131 }
132 var actualLength = 0;
133 if (item is Collection) {
134 actualLength = item.length;
135 } else {
136 for (var element in item) {
137 ++actualLength;
138 }
139 }
140 if (expectedLength > actualLength) {
141 return 'has too few elements (${actualLength} < ${expectedLength})';
142 } else if (expectedLength < actualLength) {
143 return 'has too many elements (${actualLength} > ${expectedLength})';
144 }
145 List<bool> matched = new List<bool>(actualLength);
146 for (var i = 0; i < actualLength; i++) {
147 matched[i] = false;
148 }
149 var expectedPosition = 0;
150 for (var expectedElement in _expected) {
151 var actualPosition = 0;
152 var gotMatch = false;
153 for (var actualElement in item) {
154 if (!matched[actualPosition]) {
155 if (expectedElement == actualElement) {
156 matched[actualPosition] = gotMatch = true;
157 break;
158 }
159 }
160 ++actualPosition;
161 }
162 if (!gotMatch) {
163 Description reason = new StringDescription();
164 reason.add('has no match for element ').
165 addDescriptionOf(expectedElement).
166 add(' at position ${expectedPosition}');
167 return reason.toString();
168 }
169 ++expectedPosition;
170 }
171 return null;
172 }
173
174 bool matches(item, MatchState mismatchState) => (_test(item) == null);
175
176 Description describe(Description description) =>
177 description.add('equals ').addDescriptionOf(_expected).add(' unordered');
178
179 Description describeMismatch(item, Description mismatchDescription,
180 MatchState matchState, bool verbose) =>
181 mismatchDescription.add(_test(item));
182 }
183
184 /**
185 * Collection matchers match against [Collection]s. We add this intermediate
186 * class to give better mismatch error messages than the base Matcher class.
187 */
188 abstract class _CollectionMatcher extends BaseMatcher {
189 const _CollectionMatcher();
190 Description describeMismatch(item, Description mismatchDescription,
191 MatchState matchState, bool verbose) {
192 if (item is! Iterable) {
193 return mismatchDescription.
194 addDescriptionOf(item).
195 add(' not an Iterable');
196 } else {
197 return super.describeMismatch(item, mismatchDescription, matchState,
198 verbose);
199 }
200 }
201 }
OLDNEW
« no previous file with comments | « pkg/unittest/lib/matcher.dart ('k') | pkg/unittest/lib/src/core_matchers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698