@@ -26,19 +26,20 @@ import 'package:checks/context.dart';
2626/// Collections may be nested to a maximum depth of 1000. Recursive collections
2727/// are not allowed.
2828/// {@endtemplate}
29- Iterable <String >? deepCollectionEquals (Object actual, Object expected) {
29+ Iterable <String > Function ()? deepCollectionEquals (
30+ Object actual, Object expected) {
3031 try {
3132 return _deepCollectionEquals (actual, expected, 0 );
3233 } on _ExceededDepthError {
33- return ['exceeds the depth limit of $_maxDepth ' ];
34+ return () => ['exceeds the depth limit of $_maxDepth ' ];
3435 }
3536}
3637
3738const _maxDepth = 1000 ;
3839
3940class _ExceededDepthError extends Error {}
4041
41- Iterable <String >? _deepCollectionEquals (
42+ Iterable <String > Function () ? _deepCollectionEquals (
4243 Object actual, Object expected, int depth) {
4344 assert (actual is Iterable || actual is Map );
4445 assert (expected is Iterable || expected is Map );
@@ -50,7 +51,7 @@ Iterable<String>? _deepCollectionEquals(
5051 final currentExpected = toCheck.expected;
5152 final path = toCheck.path;
5253 final currentDepth = toCheck.depth;
53- Iterable <String >? rejectionWhich;
54+ Iterable <String > Function () ? rejectionWhich;
5455 if (currentExpected is Set ) {
5556 rejectionWhich = _findSetDifference (
5657 currentActual, currentExpected, path, currentDepth);
@@ -67,10 +68,10 @@ Iterable<String>? _deepCollectionEquals(
6768 return null ;
6869}
6970
70- List <String >? _findIterableDifference (Object ? actual,
71+ List <String > Function () ? _findIterableDifference (Object ? actual,
7172 Iterable <Object ?> expected, _Path path, Queue <_Search > queue, int depth) {
7273 if (actual is ! Iterable ) {
73- return ['${path }is not an Iterable' ];
74+ return () => ['${path }is not an Iterable' ];
7475 }
7576 var actualIterator = actual.iterator;
7677 var expectedIterator = expected.iterator;
@@ -79,16 +80,16 @@ List<String>? _findIterableDifference(Object? actual,
7980 var expectedNext = expectedIterator.moveNext ();
8081 if (! expectedNext && ! actualNext) break ;
8182 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+ ];
8687 }
8788 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+ ];
9293 }
9394 var actualValue = actualIterator.current;
9495 var expectedValue = expectedIterator.current;
@@ -99,22 +100,23 @@ List<String>? _findIterableDifference(Object? actual,
99100 } else if (expectedValue is Condition ) {
100101 final failure = softCheck (actualValue, expectedValue);
101102 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+ ];
111113 }
112114 } else {
113115 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+ ];
118120 }
119121 }
120122 }
@@ -134,30 +136,30 @@ bool _elementMatches(Object? actual, Object? expected, int depth) {
134136 return expected == actual;
135137}
136138
137- Iterable <String >? _findSetDifference (
139+ Iterable <String > Function () ? _findSetDifference (
138140 Object ? actual, Set <Object ?> expected, _Path path, int depth) {
139141 if (actual is ! Set ) {
140- return ['${path }is not a Set' ];
142+ return () => ['${path }is not a Set' ];
141143 }
142144 return unorderedCompare (
143145 actual,
144146 expected,
145147 (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+ ],
154156 );
155157}
156158
157- Iterable <String >? _findMapDifference (
159+ Iterable <String > Function () ? _findMapDifference (
158160 Object ? actual, Map <Object ?, Object ?> expected, _Path path, int depth) {
159161 if (actual is ! Map ) {
160- return ['${path }is not a Map' ];
162+ return () => ['${path }is not a Map' ];
161163 }
162164 Iterable <String > describeEntry (MapEntry <Object ?, Object ?> entry) {
163165 final key = literal (entry.key);
@@ -175,16 +177,16 @@ Iterable<String>? _findMapDifference(
175177 (actual, expected) =>
176178 _elementMatches (actual.key, expected.key, depth) &&
177179 _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+ ],
188190 );
189191}
190192
@@ -241,12 +243,14 @@ class _Search {
241243/// Runtime is at least `O(|actual||expected|)` , and for collections with many
242244/// elements which compare as equal the runtime can reach
243245/// `O((|actual| + |expected|)^2.5)` .
244- Iterable <String >? unorderedCompare <T , E >(
246+ Iterable <String > Function () ? unorderedCompare <T , E >(
245247 Iterable <T > actual,
246248 Iterable <E > expected,
247249 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) {
250254 final indexedExpected = expected.toList ();
251255 final indexedActual = actual.toList ();
252256 final adjacency = < List <int >> [];
0 commit comments