@@ -110,59 +110,70 @@ Matcher equals(expected, [int limit = 100]) => expected is String
110
110
? new _StringEqualsMatcher (expected)
111
111
: new _DeepMatcher (expected, limit);
112
112
113
+ typedef _RecursiveMatcher = List <String > Function (
114
+ dynamic , dynamic , String , int );
115
+
113
116
class _DeepMatcher extends Matcher {
114
117
final _expected;
115
118
final int _limit;
116
119
117
120
_DeepMatcher (this ._expected, [int limit = 1000 ]) : this ._limit = limit;
118
121
119
122
// Returns a pair (reason, location)
120
- List _compareIterables (expected, actual, matcher, depth, location) {
121
- if (actual is ! Iterable ) return ['is not Iterable' , location];
122
-
123
- var expectedIterator = expected.iterator;
124
- var actualIterator = actual.iterator;
125
- for (var index = 0 ;; index++ ) {
126
- // Advance in lockstep.
127
- var expectedNext = expectedIterator.moveNext ();
128
- var actualNext = actualIterator.moveNext ();
129
-
130
- // If we reached the end of both, we succeeded.
131
- if (! expectedNext && ! actualNext) return null ;
132
-
133
- // Fail if their lengths are different.
134
- var newLocation = '$location [$index ]' ;
135
- if (! expectedNext) return ['longer than expected' , newLocation];
136
- if (! actualNext) return ['shorter than expected' , newLocation];
137
-
138
- // Match the elements.
139
- var rp = matcher (
140
- expectedIterator.current, actualIterator.current, newLocation, depth);
141
- if (rp != null ) return rp;
123
+ List <String > _compareIterables (Iterable expected, Object actual,
124
+ _RecursiveMatcher matcher, int depth, String location) {
125
+ if (actual is Iterable ) {
126
+ var expectedIterator = expected.iterator;
127
+ var actualIterator = actual.iterator;
128
+ for (var index = 0 ;; index++ ) {
129
+ // Advance in lockstep.
130
+ var expectedNext = expectedIterator.moveNext ();
131
+ var actualNext = actualIterator.moveNext ();
132
+
133
+ // If we reached the end of both, we succeeded.
134
+ if (! expectedNext && ! actualNext) return null ;
135
+
136
+ // Fail if their lengths are different.
137
+ var newLocation = '$location [$index ]' ;
138
+ if (! expectedNext) return ['longer than expected' , newLocation];
139
+ if (! actualNext) return ['shorter than expected' , newLocation];
140
+
141
+ // Match the elements.
142
+ var rp = matcher (expectedIterator.current, actualIterator.current,
143
+ newLocation, depth);
144
+ if (rp != null ) return rp;
145
+ }
146
+ } else {
147
+ return ['is not Iterable' , location];
142
148
}
143
149
}
144
150
145
- List _compareSets (Set expected, actual, matcher, depth, location) {
146
- if (actual is ! Iterable ) return ['is not Iterable' , location];
147
- actual = actual.toSet ();
151
+ List <String > _compareSets (Set expected, Object actual,
152
+ _RecursiveMatcher matcher, int depth, String location) {
153
+ if (actual is Iterable ) {
154
+ Set other = actual.toSet ();
148
155
149
- for (var expectedElement in expected) {
150
- if (actual.every ((actualElement) =>
151
- matcher (expectedElement, actualElement, location, depth) != null )) {
152
- return ['does not contain $expectedElement ' , location];
156
+ for (var expectedElement in expected) {
157
+ if (other.every ((actualElement) =>
158
+ matcher (expectedElement, actualElement, location, depth) != null )) {
159
+ return ['does not contain $expectedElement ' , location];
160
+ }
153
161
}
154
- }
155
162
156
- if (actual.length > expected.length) {
157
- return ['larger than expected' , location];
158
- } else if (actual.length < expected.length) {
159
- return ['smaller than expected' , location];
163
+ if (other.length > expected.length) {
164
+ return ['larger than expected' , location];
165
+ } else if (other.length < expected.length) {
166
+ return ['smaller than expected' , location];
167
+ } else {
168
+ return null ;
169
+ }
160
170
} else {
161
- return null ;
171
+ return [ 'is not Iterable' , location] ;
162
172
}
163
173
}
164
174
165
- List _recursiveMatch (expected, actual, String location, int depth) {
175
+ List <String > _recursiveMatch (
176
+ Object expected, Object actual, String location, int depth) {
166
177
// If the expected value is a matcher, try to match it.
167
178
if (expected is Matcher ) {
168
179
var matchState = {};
@@ -193,25 +204,24 @@ class _DeepMatcher extends Matcher {
193
204
expected, actual, _recursiveMatch, depth + 1 , location);
194
205
} else if (expected is Map ) {
195
206
if (actual is ! Map ) return ['expected a map' , location];
196
-
197
- var err = (expected.length == actual.length)
198
- ? ''
199
- : 'has different length and ' ;
207
+ var map = (actual as Map );
208
+ var err =
209
+ (expected.length == map.length) ? '' : 'has different length and ' ;
200
210
for (var key in expected.keys) {
201
- if (! actual .containsKey (key)) {
211
+ if (! map .containsKey (key)) {
202
212
return ["${err }is missing map key '$key '" , location];
203
213
}
204
214
}
205
215
206
- for (var key in actual .keys) {
216
+ for (var key in map .keys) {
207
217
if (! expected.containsKey (key)) {
208
218
return ["${err }has extra map key '$key '" , location];
209
219
}
210
220
}
211
221
212
222
for (var key in expected.keys) {
213
223
var rp = _recursiveMatch (
214
- expected[key], actual [key], "$location ['$key ']" , depth + 1 );
224
+ expected[key], map [key], "$location ['$key ']" , depth + 1 );
215
225
if (rp != null ) return rp;
216
226
}
217
227
@@ -239,7 +249,7 @@ class _DeepMatcher extends Matcher {
239
249
String _match (expected, actual, Map matchState) {
240
250
var rp = _recursiveMatch (expected, actual, '' , 0 );
241
251
if (rp == null ) return null ;
242
- var reason;
252
+ String reason;
243
253
if (rp[0 ].length > 0 ) {
244
254
if (rp[1 ].length > 0 ) {
245
255
reason = "${rp [0 ]} at location ${rp [1 ]}" ;
@@ -567,18 +577,19 @@ class _In extends Matcher {
567
577
/// For example:
568
578
///
569
579
/// expect(v, predicate((x) => ((x % 2) == 0), "is even"))
570
- Matcher predicate (bool f (value), [String description = 'satisfies function' ]) =>
580
+ Matcher predicate <T >(bool f (T value),
581
+ [String description = 'satisfies function' ]) =>
571
582
new _Predicate (f, description);
572
583
573
- typedef bool _PredicateFunction ( value);
584
+ typedef bool _PredicateFunction < T >( T value);
574
585
575
- class _Predicate extends Matcher {
576
- final _PredicateFunction _matcher;
586
+ class _Predicate < T > extends Matcher {
587
+ final _PredicateFunction < T > _matcher;
577
588
final String _description;
578
589
579
- const _Predicate (this ._matcher, this ._description);
590
+ _Predicate (this ._matcher, this ._description);
580
591
581
- bool matches (item, Map matchState) => _matcher (item);
592
+ bool matches (item, Map matchState) => _matcher (item as T );
582
593
583
594
Description describe (Description description) =>
584
595
description.add (_description);
0 commit comments