Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of matcher; | 5 part of matcher; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Returns a matcher that matches empty strings, maps or iterables | 8 * Returns a matcher that matches empty strings, maps or iterables |
| 9 * (including collections). | 9 * (including collections). |
| 10 */ | 10 */ |
| (...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 842 * A useful utility class for implementing other matchers through inheritance. | 842 * A useful utility class for implementing other matchers through inheritance. |
| 843 * Derived classes should call the base constructor with a feature name and | 843 * Derived classes should call the base constructor with a feature name and |
| 844 * description, and an instance matcher, and should implement the | 844 * description, and an instance matcher, and should implement the |
| 845 * [featureValueOf] abstract method. | 845 * [featureValueOf] abstract method. |
| 846 * | 846 * |
| 847 * The feature description will typically describe the item and the feature, | 847 * The feature description will typically describe the item and the feature, |
| 848 * while the feature name will just name the feature. For example, we may | 848 * while the feature name will just name the feature. For example, we may |
| 849 * have a Widget class where each Widget has a price; we could make a | 849 * have a Widget class where each Widget has a price; we could make a |
| 850 * [CustomMatcher] that can make assertions about prices with: | 850 * [CustomMatcher] that can make assertions about prices with: |
| 851 * | 851 * |
| 852 <<<<<<< .mine | |
| 853 * class HasPrice extends CustomMatcher { | 852 * class HasPrice extends CustomMatcher { |
| 854 * const HasPrice(matcher) : | 853 * const HasPrice(matcher) : |
| 855 ======= | |
| 856 * class HasPrice extends CustomMatcher { | |
| 857 * HasPrice(matcher) : | |
| 858 >>>>>>> .r25321 | |
| 859 * super("Widget with price that is", "price", matcher); | 854 * super("Widget with price that is", "price", matcher); |
| 860 * featureValueOf(actual) => actual.price; | 855 * featureValueOf(actual) => actual.price; |
| 861 * } | 856 * } |
| 862 * | 857 * |
| 863 * and then use this for example like: | 858 * and then use this for example like: |
| 864 * | 859 * |
| 865 * expect(inventoryItem, new HasPrice(greaterThan(0))); | 860 * expect(inventoryItem, new HasPrice(greaterThan(0))); |
| 866 */ | 861 */ |
| 867 class CustomMatcher extends Matcher { | 862 class CustomMatcher extends Matcher { |
| 868 final String _featureDescription; | 863 final String _featureDescription; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 892 var innerDescription = new StringDescription(); | 887 var innerDescription = new StringDescription(); |
| 893 _matcher.describeMismatch(matchState['feature'], innerDescription, | 888 _matcher.describeMismatch(matchState['feature'], innerDescription, |
| 894 matchState['state'], verbose); | 889 matchState['state'], verbose); |
| 895 if (innerDescription.length > 0) { | 890 if (innerDescription.length > 0) { |
| 896 mismatchDescription.add(' which ').add(innerDescription.toString()); | 891 mismatchDescription.add(' which ').add(innerDescription.toString()); |
| 897 } | 892 } |
| 898 return mismatchDescription; | 893 return mismatchDescription; |
| 899 } | 894 } |
| 900 } | 895 } |
| 901 | 896 |
| 897 /** | |
| 898 * Returns a matcher that checks if a class instance has a property | |
| 899 * with name [name], and optionally, if that property in turn satisfies | |
| 900 * a [matcher]. | |
| 901 */ | |
| 902 Matcher hasProperty(String name, [matcher]) => | |
| 903 new _HasProperty(name, matcher == null ? null : wrapMatcher(matcher)); | |
| 904 | |
| 905 class _HasProperty extends Matcher { | |
| 906 final String _name; | |
| 907 final Matcher _matcher; | |
| 908 | |
| 909 const _HasProperty(this._name, [this._matcher]); | |
| 910 | |
| 911 bool matches(item, Map matchState) { | |
| 912 if (item is! Object) { | |
| 913 addStateInfo(matchState, {'reason': 'Not an object'}); | |
| 914 return false; | |
| 915 } | |
| 916 var mirror = reflect(item); | |
| 917 var classMirror = mirror.type; | |
| 918 var symbol = new Symbol(_name); | |
| 919 if (!classMirror.getters.containsKey(symbol)) { | |
| 920 addStateInfo(matchState, {'reason': 'No property named $_name'}); | |
| 921 return false; | |
| 922 } | |
| 923 if (_matcher == null) return true; | |
| 924 var result = mirror.getField(symbol); | |
| 925 var resultMatches = _matcher.matches(result.reflectee, matchState); | |
| 926 if (!resultMatches) { | |
| 927 addStateInfo(matchState, {'value': result.reflectee}); | |
| 928 } | |
| 929 return resultMatches; | |
| 930 } | |
| 931 | |
| 932 Description describe(Description description) { | |
| 933 description.add('has property $_name'); | |
|
Siggi Cherem (dart-lang)
2013/07/31 00:23:30
might be good to quote the name "$_name"
| |
| 934 if (_matcher != null) { | |
| 935 description.add(' which matches ').addDescriptionOf(_matcher); | |
| 936 } | |
| 937 return description; | |
| 938 } | |
| 939 | |
| 940 Description describeMismatch(item, Description mismatchDescription, | |
| 941 Map matchState, bool verbose) { | |
| 942 var reason = matchState == null ? null : matchState['reason']; | |
| 943 if (reason != null) { | |
| 944 mismatchDescription.add(reason); | |
| 945 } else { | |
| 946 mismatchDescription.add('has property $_name with value '). | |
|
Siggi Cherem (dart-lang)
2013/07/31 00:23:30
same here, so it reads:
has property "length" with
| |
| 947 addDescriptionOf(matchState['value']); | |
| 948 var innerDescription = new StringDescription(); | |
| 949 _matcher.describeMismatch(matchState['value'], innerDescription, | |
| 950 matchState['state'], verbose); | |
| 951 if (innerDescription.length > 0) { | |
| 952 mismatchDescription.add(' which ').add(innerDescription.toString()); | |
| 953 } | |
| 954 } | |
| 955 return mismatchDescription; | |
| 956 } | |
| 957 } | |
| 958 | |
| OLD | NEW |