OLD | NEW |
---|---|
(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 } | |
OLD | NEW |