3
3
// BSD-style license that can be found in the LICENSE file.
4
4
5
5
import 'interfaces.dart' ;
6
+ import 'typed_matcher.dart' ;
6
7
import 'util.dart' ;
7
8
8
9
/// Returns a matcher that matches the isEmpty property.
@@ -69,15 +70,17 @@ const Matcher isNaN = const _IsNaN();
69
70
/// A matcher that matches any non-NaN value.
70
71
const Matcher isNotNaN = const _IsNotNaN ();
71
72
72
- class _IsNaN extends Matcher {
73
+ class _IsNaN extends TypedMatcher < num > {
73
74
const _IsNaN ();
74
- bool matches (item, Map matchState) => double .nan.compareTo (item) == 0 ;
75
+ bool typedMatches (num item, Map matchState) =>
76
+ double .nan.compareTo (item) == 0 ;
75
77
Description describe (Description description) => description.add ('NaN' );
76
78
}
77
79
78
- class _IsNotNaN extends Matcher {
80
+ class _IsNotNaN extends TypedMatcher < num > {
79
81
const _IsNotNaN ();
80
- bool matches (item, Map matchState) => double .nan.compareTo (item) != 0 ;
82
+ bool typedMatches (num item, Map matchState) =>
83
+ double .nan.compareTo (item) != 0 ;
81
84
Description describe (Description description) => description.add ('not NaN' );
82
85
}
83
86
@@ -131,10 +134,10 @@ class isInstanceOf<T> extends Matcher {
131
134
/// a wrapper will have to be created.
132
135
const Matcher returnsNormally = const _ReturnsNormally ();
133
136
134
- class _ReturnsNormally extends Matcher {
137
+ class _ReturnsNormally extends TypedMatcher < Function > {
135
138
const _ReturnsNormally ();
136
139
137
- bool matches ( f, Map matchState) {
140
+ bool typedMatches ( Function f, Map matchState) {
138
141
try {
139
142
f ();
140
143
return true ;
@@ -147,8 +150,8 @@ class _ReturnsNormally extends Matcher {
147
150
Description describe (Description description) =>
148
151
description.add ("return normally" );
149
152
150
- Description describeMismatch (
151
- item, Description mismatchDescription, Map matchState, bool verbose) {
153
+ Description describeTypedMismatch ( Function item,
154
+ Description mismatchDescription, Map matchState, bool verbose) {
152
155
mismatchDescription.add ('threw ' ).addDescriptionOf (matchState['exception' ]);
153
156
if (verbose) {
154
157
mismatchDescription.add (' at ' ).add (matchState['stack' ].toString ());
@@ -256,11 +259,12 @@ class _Contains extends Matcher {
256
259
const _Contains (this ._expected);
257
260
258
261
bool matches (item, Map matchState) {
262
+ var expected = _expected;
259
263
if (item is String ) {
260
- return item.contains ((_expected as Pattern ) );
264
+ return expected is Pattern && item.contains (expected );
261
265
} else if (item is Iterable ) {
262
- if (_expected is Matcher ) {
263
- return item.any ((e) => (_expected as Matcher ) .matches (e, matchState));
266
+ if (expected is Matcher ) {
267
+ return item.any ((e) => expected .matches (e, matchState));
264
268
} else {
265
269
return item.contains (_expected);
266
270
}
@@ -286,27 +290,29 @@ class _Contains extends Matcher {
286
290
287
291
/// Returns a matcher that matches if the match argument is in
288
292
/// the expected value. This is the converse of [contains] .
289
- Matcher isIn (expected) => new _In (expected);
293
+ Matcher isIn (expected) {
294
+ if (expected is Iterable ) {
295
+ return new _In (expected, expected.contains);
296
+ } else if (expected is String ) {
297
+ return new _In <Pattern >(expected, expected.contains);
298
+ } else if (expected is Map ) {
299
+ return new _In (expected, expected.containsKey);
300
+ }
290
301
291
- class _In extends Matcher {
292
- final Object _expected;
302
+ throw new ArgumentError .value (
303
+ expected, 'expected' , 'Only Iterable, Map, and String are supported.' );
304
+ }
293
305
294
- const _In (this ._expected);
306
+ class _In <T > extends TypedMatcher <T > {
307
+ final Object _source;
308
+ final bool Function (T ) _containsFunction;
295
309
296
- bool matches (item, Map matchState) {
297
- var expected = _expected;
298
- if (expected is String ) {
299
- return expected.contains (item as Pattern );
300
- } else if (expected is Iterable ) {
301
- return expected.contains (item);
302
- } else if (expected is Map ) {
303
- return expected.containsKey (item);
304
- }
305
- return false ;
306
- }
310
+ const _In (this ._source, this ._containsFunction);
311
+
312
+ bool typedMatches (T item, Map matchState) => _containsFunction (item);
307
313
308
314
Description describe (Description description) =>
309
- description.add ('is in ' ).addDescriptionOf (_expected );
315
+ description.add ('is in ' ).addDescriptionOf (_source );
310
316
}
311
317
312
318
/// Returns a matcher that uses an arbitrary function that returns
@@ -321,13 +327,13 @@ Matcher predicate<T>(bool f(T value),
321
327
322
328
typedef bool _PredicateFunction <T >(T value);
323
329
324
- class _Predicate <T > extends Matcher {
330
+ class _Predicate <T > extends TypedMatcher < T > {
325
331
final _PredicateFunction <T > _matcher;
326
332
final String _description;
327
333
328
334
_Predicate (this ._matcher, this ._description);
329
335
330
- bool matches ( item, Map matchState) => _matcher (item as T );
336
+ bool typedMatches ( T item, Map matchState) => _matcher (item);
331
337
332
338
Description describe (Description description) =>
333
339
description.add (_description);
0 commit comments