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

Side by Side Diff: lib/unittest/string_matchers.dart

Issue 10441104: New expectation functions plus convert old tests to use these. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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
(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 if the match argument is a string and
7 * is equal to [value] when compared case-insensitively.
8 */
9 IMatcher equalsIgnoringCase(String value) => new _IsEqualIgnoringCase(value);
10
11 class _IsEqualIgnoringCase extends _StringMatcher {
12 final String _value;
13 String _matchValue;
14
15 _IsEqualIgnoringCase(this._value) {
16 _matchValue = _value.toLowerCase();
17 }
18
19 bool matches(item) => item is String && _matchValue == item.toLowerCase();
20
21 IDescription describe(IDescription description) =>
22 description.addDescriptionOf(_value).add(' ignoring case');
23 }
24
25 /**
26 * Returns a matcher which matches if the match argument is a string and
27 * is equal to [value] when compared with all runs of whitespace
28 * collapsed to single spaces and leading and trailing whitespace removed.
29 *
30 * For example, `equalsIgnoringCase("hello world")` will match
31 * "hello world", " hello world" and "hello world ".
32 */
33 IMatcher equalsIgnoringWhitespace(_string) =>
34 new _IsEqualIgnoringWhiteSpace(_string);
35
36 class _IsEqualIgnoringWhiteSpace extends _StringMatcher {
Bob Nystrom 2012/06/01 18:22:23 This is private so it matters less, but for consis
gram 2012/06/01 22:22:00 Done.
37 final String _value;
38 String _matchValue;
39
40 _IsEqualIgnoringWhiteSpace(this._value) {
41 _matchValue = _collapseWhitespace(_value);
42 }
43
44 bool matches(item) =>
45 item is String && _matchValue == _collapseWhitespace(item);
46
47 IDescription describe(IDescription description) =>
48 description.addDescriptionOf(_matchValue).add(' ignoring whitespace');
49
50 IDescription describeMismatch(item, IDescription mismatchDescription) {
51 if (item is String) {
52 return mismatchDescription.add('was ').
53 addDescriptionOf(_collapseWhitespace(item));
54 } else {
55 return super.describeMismatch(item, mismatchDescription);
56 }
57 }
58
59 // Utility function to collapse whitespace runs
Bob Nystrom 2012/06/01 18:22:23 Doc comment?
gram 2012/06/01 22:22:00 Done.
60
61 String _collapseWhitespace(_string) {
62 bool isWhitespace(String ch) => (' \n\r\t'.indexOf(ch) >= 0);
63 StringBuffer result = new StringBuffer();
64 bool skipSpace = true;
65 for (var i = 0; i < _string.length; i++) {
66 var character = _string[i];
67 if (isWhitespace(character)) {
68 if (!skipSpace) {
69 result.add(' ');
70 skipSpace = true;
71 }
72 } else {
73 result.add(character);
74 skipSpace = false;
75 }
76 }
77 return result.toString().trim();
78 }
79 }
80
81 /**
82 * Returns a matcher that matches if the match argument is a string and
83 * starts with [prefixString].
84 */
85 IMatcher startsWith(String prefixString) => new _StringStartsWith(prefixString);
86
87 class _StringStartsWith extends _StringMatcher {
88 final String _prefix;
89
90 const _StringStartsWith(this._prefix);
91
92 bool matches(item) => item is String && item.startsWith(_prefix);
93
94 IDescription describe(IDescription description) =>
95 description.add('a string starting with ').addDescriptionOf(_prefix);
96 }
97
98 /**
99 * Returns a matcher that matches if the match argument is a string and
100 * ends with [suffixString].
101 */
102 IMatcher endsWith(String suffixString) => new _StringEndsWith(suffixString);
103
104 class _StringEndsWith extends _StringMatcher {
105
106 final String _suffix;
107
108 const _StringEndsWith(this._suffix);
109
110 bool matches(item) => item is String && item.endsWith(_suffix);
111
112 IDescription describe(IDescription description) =>
113 description.add('a string ending with ').addDescriptionOf(_suffix);
114 }
115
116 /**
117 * Returns a matcher that matches if the match argument is a string and
118 * contains a given list of [substrings] in relative order.
119 *
120 * For example, `stringContainsInOrder(["a", "e", "i", "o", "u"])` will match
Bob Nystrom 2012/06/01 18:22:23 Yay markdown!
gram 2012/06/01 22:22:00 Done.
121 * "abcdefghijklmnopqrstuvwxyz".
122 */
123 IMatcher stringContainsInOrder(substrings) =>
124 new _StringContainsInOrder(substrings);
125
126 class _StringContainsInOrder extends _StringMatcher {
127
128 final List<String> _substrings;
129
130 const _StringContainsInOrder(this._substrings);
131
132 bool matches(item) {
133 if (!(item is String)) {
134 return false;
135 }
136 var from_index = 0;
137 for (var s in _substrings) {
138 from_index = item.indexOf(s, from_index);
139 if (from_index < 0)
140 return false;
141 }
142 return true;
143 }
144
145 IDescription describe(IDescription description) =>
146 description.addList('a string containing ', ', ', ' in order',
147 _substrings);
148 }
149
150 /**
151 * Returns a matcher that matches if the match argument is a string and
152 * matches the regular expression given by [re]. [re] can be a RegExp
153 * instance or a string; in the latter case it will be used to create
154 * a RegExp instance.
155 */
156 IMatcher matches(re) => new _MatchesRegExp(re);
157
158 class _MatchesRegExp extends _StringMatcher {
159 RegExp _regexp;
160
161 _MatchesRegExp(re) {
162 if (re is String) {
163 _regexp = new RegExp(re);
164 } else if (re is RegExp) {
165 _regexp = re;
166 } else {
167 throw new IllegalArgumentException('matches requires a regexp or string');
168 }
169 }
170
171 bool matches(String item) => _regexp.hasMatch(item);
172
173 IDescription describe(IDescription description) =>
174 description.add("match '${_regexp.pattern}'");
175 }
176
177 // String matchers match against a string. We add this intermediate
178 // class to give better mismatch error messages than the base Matcher class.
179 /*abstract*/ class _StringMatcher extends Matcher {
180 const _StringMatcher();
181 IDescription describeMismatch(item, IDescription mismatchDescription) {
182 if (!(item is String)) {
183 return mismatchDescription.
184 addDescriptionOf(item).
185 add(' not a string');
186 } else {
187 return super.describeMismatch(item, mismatchDescription);
188 }
189 }
190 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698