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

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

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

Powered by Google App Engine
This is Rietveld 408576698