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 Matcher 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 Description describe(Description 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 Matcher equalsIgnoringWhitespace(_string) => |
| 34 new _IsEqualIgnoringWhitespace(_string); |
| 35 |
| 36 class _IsEqualIgnoringWhitespace extends _StringMatcher { |
| 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 Description describe(Description description) => |
| 48 description.addDescriptionOf(_matchValue).add(' ignoring whitespace'); |
| 49 |
| 50 Description describeMismatch(item, Description 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 |
| 60 /** |
| 61 * Utility function to collapse whitespace runs to single spaces |
| 62 * and strip leading/trailing whitespace. |
| 63 */ |
| 64 String collapseWhitespace(_string) { |
| 65 bool isWhitespace(String ch) => (' \n\r\t'.indexOf(ch) >= 0); |
| 66 StringBuffer result = new StringBuffer(); |
| 67 bool skipSpace = true; |
| 68 for (var i = 0; i < _string.length; i++) { |
| 69 var character = _string[i]; |
| 70 if (isWhitespace(character)) { |
| 71 if (!skipSpace) { |
| 72 result.add(' '); |
| 73 skipSpace = true; |
| 74 } |
| 75 } else { |
| 76 result.add(character); |
| 77 skipSpace = false; |
| 78 } |
| 79 } |
| 80 return result.toString().trim(); |
| 81 } |
| 82 |
| 83 /** |
| 84 * Returns a matcher that matches if the match argument is a string and |
| 85 * starts with [prefixString]. |
| 86 */ |
| 87 Matcher startsWith(String prefixString) => new _StringStartsWith(prefixString); |
| 88 |
| 89 class _StringStartsWith extends _StringMatcher { |
| 90 final String _prefix; |
| 91 |
| 92 const _StringStartsWith(this._prefix); |
| 93 |
| 94 bool matches(item) => item is String && item.startsWith(_prefix); |
| 95 |
| 96 Description describe(Description description) => |
| 97 description.add('a string starting with ').addDescriptionOf(_prefix); |
| 98 } |
| 99 |
| 100 /** |
| 101 * Returns a matcher that matches if the match argument is a string and |
| 102 * ends with [suffixString]. |
| 103 */ |
| 104 Matcher endsWith(String suffixString) => new _StringEndsWith(suffixString); |
| 105 |
| 106 class _StringEndsWith extends _StringMatcher { |
| 107 |
| 108 final String _suffix; |
| 109 |
| 110 const _StringEndsWith(this._suffix); |
| 111 |
| 112 bool matches(item) => item is String && item.endsWith(_suffix); |
| 113 |
| 114 Description describe(Description description) => |
| 115 description.add('a string ending with ').addDescriptionOf(_suffix); |
| 116 } |
| 117 |
| 118 /** |
| 119 * Returns a matcher that matches if the match argument is a string and |
| 120 * contains a given list of [substrings] in relative order. |
| 121 * |
| 122 * For example, `stringContainsInOrder(["a", "e", "i", "o", "u"])` will match |
| 123 * "abcdefghijklmnopqrstuvwxyz". |
| 124 */ |
| 125 Matcher stringContainsInOrder(substrings) => |
| 126 new _StringContainsInOrder(substrings); |
| 127 |
| 128 class _StringContainsInOrder extends _StringMatcher { |
| 129 |
| 130 final List<String> _substrings; |
| 131 |
| 132 const _StringContainsInOrder(this._substrings); |
| 133 |
| 134 bool matches(item) { |
| 135 if (!(item is String)) { |
| 136 return false; |
| 137 } |
| 138 var from_index = 0; |
| 139 for (var s in _substrings) { |
| 140 from_index = item.indexOf(s, from_index); |
| 141 if (from_index < 0) |
| 142 return false; |
| 143 } |
| 144 return true; |
| 145 } |
| 146 |
| 147 Description describe(Description description) => |
| 148 description.addAll('a string containing ', ', ', ' in order', |
| 149 _substrings); |
| 150 } |
| 151 |
| 152 /** |
| 153 * Returns a matcher that matches if the match argument is a string and |
| 154 * matches the regular expression given by [re]. [re] can be a RegExp |
| 155 * instance or a string; in the latter case it will be used to create |
| 156 * a RegExp instance. |
| 157 */ |
| 158 Matcher matches(re) => new _MatchesRegExp(re); |
| 159 |
| 160 class _MatchesRegExp extends _StringMatcher { |
| 161 RegExp _regexp; |
| 162 |
| 163 _MatchesRegExp(re) { |
| 164 if (re is String) { |
| 165 _regexp = new RegExp(re); |
| 166 } else if (re is RegExp) { |
| 167 _regexp = re; |
| 168 } else { |
| 169 throw new IllegalArgumentException('matches requires a regexp or string'); |
| 170 } |
| 171 } |
| 172 |
| 173 bool matches(String item) => _regexp.hasMatch(item); |
| 174 |
| 175 Description describe(Description description) => |
| 176 description.add("match '${_regexp.pattern}'"); |
| 177 } |
| 178 |
| 179 // String matchers match against a string. We add this intermediate |
| 180 // class to give better mismatch error messages than the base Matcher class. |
| 181 /*abstract*/ class _StringMatcher extends BaseMatcher { |
| 182 const _StringMatcher(); |
| 183 Description describeMismatch(item, Description mismatchDescription) { |
| 184 if (!(item is String)) { |
| 185 return mismatchDescription. |
| 186 addDescriptionOf(item). |
| 187 add(' not a string'); |
| 188 } else { |
| 189 return super.describeMismatch(item, mismatchDescription); |
| 190 } |
| 191 } |
| 192 } |
OLD | NEW |