2
2
// for details. All rights reserved. Use of this source code is governed by a
3
3
// BSD-style license that can be found in the LICENSE file.
4
4
5
+ import 'feature_matcher.dart' ;
5
6
import 'interfaces.dart' ;
6
7
import 'type_matcher.dart' ;
7
8
import 'util.dart' ;
@@ -70,15 +71,17 @@ const Matcher isNaN = const _IsNaN();
70
71
/// A matcher that matches any non-NaN value.
71
72
const Matcher isNotNaN = const _IsNotNaN ();
72
73
73
- class _IsNaN extends Matcher {
74
+ class _IsNaN extends FeatureMatcher < num > {
74
75
const _IsNaN ();
75
- bool matches (item, Map matchState) => double .nan.compareTo (item) == 0 ;
76
+ bool typedMatches (num item, Map matchState) =>
77
+ double .nan.compareTo (item) == 0 ;
76
78
Description describe (Description description) => description.add ('NaN' );
77
79
}
78
80
79
- class _IsNotNaN extends Matcher {
81
+ class _IsNotNaN extends FeatureMatcher < num > {
80
82
const _IsNotNaN ();
81
- bool matches (item, Map matchState) => double .nan.compareTo (item) != 0 ;
83
+ bool typedMatches (num item, Map matchState) =>
84
+ double .nan.compareTo (item) != 0 ;
82
85
Description describe (Description description) => description.add ('not NaN' );
83
86
}
84
87
@@ -122,10 +125,10 @@ class isInstanceOf<T> extends TypeMatcher<T> {
122
125
/// a wrapper will have to be created.
123
126
const Matcher returnsNormally = const _ReturnsNormally ();
124
127
125
- class _ReturnsNormally extends Matcher {
128
+ class _ReturnsNormally extends FeatureMatcher < Function > {
126
129
const _ReturnsNormally ();
127
130
128
- bool matches ( f, Map matchState) {
131
+ bool typedMatches ( Function f, Map matchState) {
129
132
try {
130
133
f ();
131
134
return true ;
@@ -138,8 +141,8 @@ class _ReturnsNormally extends Matcher {
138
141
Description describe (Description description) =>
139
142
description.add ("return normally" );
140
143
141
- Description describeMismatch (
142
- item, Description mismatchDescription, Map matchState, bool verbose) {
144
+ Description describeTypedMismatch ( Function item,
145
+ Description mismatchDescription, Map matchState, bool verbose) {
143
146
mismatchDescription.add ('threw ' ).addDescriptionOf (matchState['exception' ]);
144
147
if (verbose) {
145
148
mismatchDescription.add (' at ' ).add (matchState['stack' ].toString ());
@@ -210,11 +213,12 @@ class _Contains extends Matcher {
210
213
const _Contains (this ._expected);
211
214
212
215
bool matches (item, Map matchState) {
216
+ var expected = _expected;
213
217
if (item is String ) {
214
- return item.contains ((_expected as Pattern ) );
218
+ return expected is Pattern && item.contains (expected );
215
219
} else if (item is Iterable ) {
216
- if (_expected is Matcher ) {
217
- return item.any ((e) => (_expected as Matcher ) .matches (e, matchState));
220
+ if (expected is Matcher ) {
221
+ return item.any ((e) => expected .matches (e, matchState));
218
222
} else {
219
223
return item.contains (_expected);
220
224
}
@@ -240,27 +244,29 @@ class _Contains extends Matcher {
240
244
241
245
/// Returns a matcher that matches if the match argument is in
242
246
/// the expected value. This is the converse of [contains] .
243
- Matcher isIn (expected) => new _In (expected);
247
+ Matcher isIn (expected) {
248
+ if (expected is Iterable ) {
249
+ return new _In (expected, expected.contains);
250
+ } else if (expected is String ) {
251
+ return new _In <Pattern >(expected, expected.contains);
252
+ } else if (expected is Map ) {
253
+ return new _In (expected, expected.containsKey);
254
+ }
244
255
245
- class _In extends Matcher {
246
- final Object _expected;
256
+ throw new ArgumentError .value (
257
+ expected, 'expected' , 'Only Iterable, Map, and String are supported.' );
258
+ }
247
259
248
- const _In (this ._expected);
260
+ class _In <T > extends FeatureMatcher <T > {
261
+ final Object _source;
262
+ final bool Function (T ) _containsFunction;
249
263
250
- bool matches (item, Map matchState) {
251
- var expected = _expected;
252
- if (expected is String ) {
253
- return expected.contains (item as Pattern );
254
- } else if (expected is Iterable ) {
255
- return expected.contains (item);
256
- } else if (expected is Map ) {
257
- return expected.containsKey (item);
258
- }
259
- return false ;
260
- }
264
+ const _In (this ._source, this ._containsFunction);
265
+
266
+ bool typedMatches (T item, Map matchState) => _containsFunction (item);
261
267
262
268
Description describe (Description description) =>
263
- description.add ('is in ' ).addDescriptionOf (_expected );
269
+ description.add ('is in ' ).addDescriptionOf (_source );
264
270
}
265
271
266
272
/// Returns a matcher that uses an arbitrary function that returns
@@ -275,13 +281,13 @@ Matcher predicate<T>(bool f(T value),
275
281
276
282
typedef bool _PredicateFunction <T >(T value);
277
283
278
- class _Predicate <T > extends Matcher {
284
+ class _Predicate <T > extends FeatureMatcher < T > {
279
285
final _PredicateFunction <T > _matcher;
280
286
final String _description;
281
287
282
288
_Predicate (this ._matcher, this ._description);
283
289
284
- bool matches ( item, Map matchState) => _matcher (item as T );
290
+ bool typedMatches ( T item, Map matchState) => _matcher (item);
285
291
286
292
Description describe (Description description) =>
287
293
description.add (_description);
0 commit comments