| 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 [Collection]s in which all elements | 
 |    7  * match the given [matcher]. | 
 |    8  */ | 
 |    9 Matcher everyElement(matcher) => new _EveryElement(wrapMatcher(matcher)); | 
 |   10  | 
 |   11 class _EveryElement extends _CollectionMatcher { | 
 |   12   Matcher _matcher; | 
 |   13  | 
 |   14   _EveryElement(Matcher this._matcher); | 
 |   15  | 
 |   16   bool matches(item) { | 
 |   17     return item.every((e) => _matcher.matches(e)); | 
 |   18   } | 
 |   19  | 
 |   20   Description describe(Description description) => | 
 |   21       description.add('every element ').addDescriptionOf(_matcher); | 
 |   22 } | 
 |   23  | 
 |   24 /** | 
 |   25  * Returns a matcher which matches [Collection]s in which at least one | 
 |   26  * element matches the given [matcher]. | 
 |   27  */ | 
 |   28 Matcher someElement(matcher) => new _SomeElement(wrapMatcher(matcher)); | 
 |   29  | 
 |   30 class _SomeElement extends _CollectionMatcher { | 
 |   31   Matcher _matcher; | 
 |   32  | 
 |   33   _SomeElement(this._matcher); | 
 |   34  | 
 |   35   bool matches(item) { | 
 |   36     return item.some( (e) => _matcher.matches(e) ); | 
 |   37   } | 
 |   38  | 
 |   39   Description describe(Description description) => | 
 |   40       description.add('some element ').addDescriptionOf(_matcher); | 
 |   41 } | 
 |   42  | 
 |   43 /** | 
 |   44  * Returns a matcher which matches [Iterable]s that have the same | 
 |   45  * length and the same elements as [expected], and in the same order. | 
 |   46  */ | 
 |   47 Matcher orderedEquals(Iterable expected) => new _OrderedEquals(expected); | 
 |   48  | 
 |   49 class _OrderedEquals extends BaseMatcher { | 
 |   50   Iterable _expected; | 
 |   51  | 
 |   52   _OrderedEquals(this._expected); | 
 |   53  | 
 |   54   String _test(item) { | 
 |   55     return _compareIterables(_expected, item, | 
 |   56       (expected, actual, location) => expected == actual? null : location); | 
 |   57   } | 
 |   58  | 
 |   59   bool matches(item) => (_test(item) == null); | 
 |   60  | 
 |   61   Description describe(Description description) => | 
 |   62       description.add('equals ').addDescriptionOf(_expected).add(' ordered'); | 
 |   63  | 
 |   64   Description describeMismatch(item, Description mismatchDescription) => | 
 |   65       mismatchDescription.add(_test(item)); | 
 |   66 } | 
 |   67  | 
 |   68 /** | 
 |   69  * Returns a matcher which matches [Iterable]s that have the same | 
 |   70  * length and the same elements as [expected], but not necessarily in | 
 |   71  * the same order. Note that this is O(n^2) so should only be used on | 
 |   72  * small objects. | 
 |   73  */ | 
 |   74 Matcher unorderedEquals(Iterable expected) => | 
 |   75     new _UnorderedEquals(expected); | 
 |   76  | 
 |   77 class _UnorderedEquals extends BaseMatcher { | 
 |   78   Iterable _expected; | 
 |   79  | 
 |   80   _UnorderedEquals(Iterable this._expected); | 
 |   81  | 
 |   82   String _test(item) { | 
 |   83     if (item is !Iterable) { | 
 |   84       return 'not iterable'; | 
 |   85     } | 
 |   86     // Check the lengths are the same. | 
 |   87     var expectedLength = 0; | 
 |   88     if (_expected is Collection) { | 
 |   89       Collection cast = _expected; // "_expected as Collection" | 
 |   90       expectedLength = cast.length; | 
 |   91     } else { | 
 |   92       for (var element in _expected) { | 
 |   93         ++expectedLength; | 
 |   94       } | 
 |   95     } | 
 |   96     var actualLength = 0; | 
 |   97     if (item is Collection) { | 
 |   98       actualLength = item.length; | 
 |   99     } else { | 
 |  100       for (var element in item) { | 
 |  101         ++actualLength; | 
 |  102       } | 
 |  103     } | 
 |  104     if (expectedLength > actualLength) { | 
 |  105       return 'has too few elements (${actualLength} < ${expectedLength})'; | 
 |  106     } else if (expectedLength < actualLength) { | 
 |  107       return 'has too many elements (${actualLength} > ${expectedLength})'; | 
 |  108     } | 
 |  109     List<bool> matched = new List<bool>(actualLength); | 
 |  110     var expectedPosition = 0; | 
 |  111     for (var expectedElement in _expected) { | 
 |  112       var actualPosition = 0; | 
 |  113       var gotMatch = false; | 
 |  114       for (var actualElement in item) { | 
 |  115         if (!matched[actualPosition]) { | 
 |  116           if (expectedElement == actualElement) { | 
 |  117             matched[actualPosition] = gotMatch = true; | 
 |  118             break; | 
 |  119           } | 
 |  120         } | 
 |  121         ++actualPosition; | 
 |  122       } | 
 |  123       if (!gotMatch) { | 
 |  124         return 'has no match for element ${expectedElement} ' | 
 |  125                'at position ${expectedPosition}'; | 
 |  126       } | 
 |  127       ++expectedPosition; | 
 |  128     } | 
 |  129     return null; | 
 |  130   } | 
 |  131  | 
 |  132   bool matches(item) => (_test(item) == null); | 
 |  133  | 
 |  134   Description describe(Description description) => | 
 |  135       description.add('equals ').addDescriptionOf(_expected).add(' unordered'); | 
 |  136  | 
 |  137   Description describeMismatch(item, Description mismatchDescription) => | 
 |  138       mismatchDescription.add(_test(item)); | 
 |  139 } | 
 |  140  | 
 |  141 /** | 
 |  142  * Collection matchers match against [Collection]s. We add this intermediate | 
 |  143  * class to give better mismatch error messages than the base Matcher class. | 
 |  144  */ | 
 |  145  | 
 |  146 /*abstract*/ class _CollectionMatcher extends BaseMatcher { | 
 |  147   const _CollectionMatcher(); | 
 |  148   Description describeMismatch(item, Description mismatchDescription) { | 
 |  149     if (item is !Collection) { | 
 |  150       return mismatchDescription. | 
 |  151           addDescriptionOf(item). | 
 |  152           add(' not a collection'); | 
 |  153     } else { | 
 |  154       return super.describeMismatch(item, mismatchDescription); | 
 |  155     } | 
 |  156   } | 
 |  157 } | 
| OLD | NEW |