@@ -26,19 +26,20 @@ import 'package:checks/context.dart';
26
26
/// Collections may be nested to a maximum depth of 1000. Recursive collections
27
27
/// are not allowed.
28
28
/// {@endtemplate}
29
- Iterable <String >? deepCollectionEquals (Object actual, Object expected) {
29
+ Iterable <String > Function ()? deepCollectionEquals (
30
+ Object actual, Object expected) {
30
31
try {
31
32
return _deepCollectionEquals (actual, expected, 0 );
32
33
} on _ExceededDepthError {
33
- return ['exceeds the depth limit of $_maxDepth ' ];
34
+ return () => ['exceeds the depth limit of $_maxDepth ' ];
34
35
}
35
36
}
36
37
37
38
const _maxDepth = 1000 ;
38
39
39
40
class _ExceededDepthError extends Error {}
40
41
41
- Iterable <String >? _deepCollectionEquals (
42
+ Iterable <String > Function () ? _deepCollectionEquals (
42
43
Object actual, Object expected, int depth) {
43
44
assert (actual is Iterable || actual is Map );
44
45
assert (expected is Iterable || expected is Map );
@@ -50,7 +51,7 @@ Iterable<String>? _deepCollectionEquals(
50
51
final currentExpected = toCheck.expected;
51
52
final path = toCheck.path;
52
53
final currentDepth = toCheck.depth;
53
- Iterable <String >? rejectionWhich;
54
+ Iterable <String > Function () ? rejectionWhich;
54
55
if (currentExpected is Set ) {
55
56
rejectionWhich = _findSetDifference (
56
57
currentActual, currentExpected, path, currentDepth);
@@ -67,10 +68,10 @@ Iterable<String>? _deepCollectionEquals(
67
68
return null ;
68
69
}
69
70
70
- List <String >? _findIterableDifference (Object ? actual,
71
+ List <String > Function () ? _findIterableDifference (Object ? actual,
71
72
Iterable <Object ?> expected, _Path path, Queue <_Search > queue, int depth) {
72
73
if (actual is ! Iterable ) {
73
- return ['${path }is not an Iterable' ];
74
+ return () => ['${path }is not an Iterable' ];
74
75
}
75
76
var actualIterator = actual.iterator;
76
77
var expectedIterator = expected.iterator;
@@ -79,16 +80,16 @@ List<String>? _findIterableDifference(Object? actual,
79
80
var expectedNext = expectedIterator.moveNext ();
80
81
if (! expectedNext && ! actualNext) break ;
81
82
if (! expectedNext) {
82
- return [
83
- '${path }has more elements than expected' ,
84
- 'expected an iterable with $index element(s)'
85
- ];
83
+ return () => [
84
+ '${path }has more elements than expected' ,
85
+ 'expected an iterable with $index element(s)'
86
+ ];
86
87
}
87
88
if (! actualNext) {
88
- return [
89
- '${path }has too few elements' ,
90
- 'expected an iterable with at least ${index + 1 } element(s)'
91
- ];
89
+ return () => [
90
+ '${path }has too few elements' ,
91
+ 'expected an iterable with at least ${index + 1 } element(s)'
92
+ ];
92
93
}
93
94
var actualValue = actualIterator.current;
94
95
var expectedValue = expectedIterator.current;
@@ -99,22 +100,23 @@ List<String>? _findIterableDifference(Object? actual,
99
100
} else if (expectedValue is Condition ) {
100
101
final failure = softCheck (actualValue, expectedValue);
101
102
if (failure != null ) {
102
- final which = failure.rejection.which;
103
- return [
104
- 'has an element ${path .append (index )}that:' ,
105
- ...indent (failure.detail.actual.skip (1 )),
106
- ...indent (prefixFirst ('Actual: ' , failure.rejection.actual),
107
- failure.detail.depth + 1 ),
108
- if (which != null )
109
- ...indent (prefixFirst ('which ' , which), failure.detail.depth + 1 )
110
- ];
103
+ final which = failure.rejection.which? .call ();
104
+ return () => [
105
+ 'has an element ${path .append (index )}that:' ,
106
+ ...indent (failure.detail.actual.skip (1 )),
107
+ ...indent (prefixFirst ('Actual: ' , failure.rejection.actual ()),
108
+ failure.detail.depth + 1 ),
109
+ if (which != null )
110
+ ...indent (
111
+ prefixFirst ('which ' , which), failure.detail.depth + 1 )
112
+ ];
111
113
}
112
114
} else {
113
115
if (actualValue != expectedValue) {
114
- return [
115
- ...prefixFirst ('${path .append (index )}is ' , literal (actualValue)),
116
- ...prefixFirst ('which does not equal ' , literal (expectedValue))
117
- ];
116
+ return () => [
117
+ ...prefixFirst ('${path .append (index )}is ' , literal (actualValue)),
118
+ ...prefixFirst ('which does not equal ' , literal (expectedValue))
119
+ ];
118
120
}
119
121
}
120
122
}
@@ -134,30 +136,30 @@ bool _elementMatches(Object? actual, Object? expected, int depth) {
134
136
return expected == actual;
135
137
}
136
138
137
- Iterable <String >? _findSetDifference (
139
+ Iterable <String > Function () ? _findSetDifference (
138
140
Object ? actual, Set <Object ?> expected, _Path path, int depth) {
139
141
if (actual is ! Set ) {
140
- return ['${path }is not a Set' ];
142
+ return () => ['${path }is not a Set' ];
141
143
}
142
144
return unorderedCompare (
143
145
actual,
144
146
expected,
145
147
(actual, expected) => _elementMatches (actual, expected, depth),
146
- (expected, _, count) => [
147
- ...prefixFirst ('${path }has no element to match ' , literal (expected)),
148
- if (count > 1 ) 'or ${count - 1 } other elements' ,
149
- ],
150
- (actual, _, count) => [
151
- ...prefixFirst ('${path }has an unexpected element ' , literal (actual)),
152
- if (count > 1 ) 'and ${count - 1 } other unexpected elements' ,
153
- ],
148
+ (expected, _, count) => () => [
149
+ ...prefixFirst ('${path }has no element to match ' , literal (expected)),
150
+ if (count > 1 ) 'or ${count - 1 } other elements' ,
151
+ ],
152
+ (actual, _, count) => () => [
153
+ ...prefixFirst ('${path }has an unexpected element ' , literal (actual)),
154
+ if (count > 1 ) 'and ${count - 1 } other unexpected elements' ,
155
+ ],
154
156
);
155
157
}
156
158
157
- Iterable <String >? _findMapDifference (
159
+ Iterable <String > Function () ? _findMapDifference (
158
160
Object ? actual, Map <Object ?, Object ?> expected, _Path path, int depth) {
159
161
if (actual is ! Map ) {
160
- return ['${path }is not a Map' ];
162
+ return () => ['${path }is not a Map' ];
161
163
}
162
164
Iterable <String > describeEntry (MapEntry <Object ?, Object ?> entry) {
163
165
final key = literal (entry.key);
@@ -175,16 +177,16 @@ Iterable<String>? _findMapDifference(
175
177
(actual, expected) =>
176
178
_elementMatches (actual.key, expected.key, depth) &&
177
179
_elementMatches (actual.value, expected.value, depth),
178
- (expectedEntry, _, count) => [
179
- ...prefixFirst (
180
- '${path }has no entry to match ' , describeEntry (expectedEntry)),
181
- if (count > 1 ) 'or ${count - 1 } other entries' ,
182
- ],
183
- (actualEntry, _, count) => [
184
- ...prefixFirst (
185
- '${path }has unexpected entry ' , describeEntry (actualEntry)),
186
- if (count > 1 ) 'and ${count - 1 } other unexpected entries' ,
187
- ],
180
+ (expectedEntry, _, count) => () => [
181
+ ...prefixFirst (
182
+ '${path }has no entry to match ' , describeEntry (expectedEntry)),
183
+ if (count > 1 ) 'or ${count - 1 } other entries' ,
184
+ ],
185
+ (actualEntry, _, count) => () => [
186
+ ...prefixFirst (
187
+ '${path }has unexpected entry ' , describeEntry (actualEntry)),
188
+ if (count > 1 ) 'and ${count - 1 } other unexpected entries' ,
189
+ ],
188
190
);
189
191
}
190
192
@@ -241,12 +243,14 @@ class _Search {
241
243
/// Runtime is at least `O(|actual||expected|)` , and for collections with many
242
244
/// elements which compare as equal the runtime can reach
243
245
/// `O((|actual| + |expected|)^2.5)` .
244
- Iterable <String >? unorderedCompare <T , E >(
246
+ Iterable <String > Function () ? unorderedCompare <T , E >(
245
247
Iterable <T > actual,
246
248
Iterable <E > expected,
247
249
bool Function (T , E ) elementsEqual,
248
- Iterable <String > Function (E , int index, int count) unmatchedExpected,
249
- Iterable <String > Function (T , int index, int count) unmatchedActual) {
250
+ Iterable <String > Function () Function (E , int index, int count)
251
+ unmatchedExpected,
252
+ Iterable <String > Function () Function (T , int index, int count)
253
+ unmatchedActual) {
250
254
final indexedExpected = expected.toList ();
251
255
final indexedActual = actual.toList ();
252
256
final adjacency = < List <int >> [];
0 commit comments