@@ -19,18 +19,14 @@ extension Test.Case {
19
19
/// ([103416861](rdar://103416861))
20
20
/// }
21
21
struct Generator < S> : Sendable where S: Sequence & Sendable , S. Element: Sendable {
22
- /// A closure that produces the underlying sequence of argument values.
22
+ /// The underlying sequence of argument values.
23
23
///
24
- /// The resulting sequence _must_ be iterable multiple times. Hence,
25
- /// initializers accept only _collections_, not sequences. The constraint
26
- /// here is only to `Sequence` to allow the storage of computed sequences
27
- /// over collections (such as `CartesianProduct` or `Zip2Sequence`) that are
28
- /// safe to iterate multiple times.
29
- ///
30
- /// This property is a closure rather than an instance of `S` so that it can
31
- /// be lazily evaluated rather than requiring evaluation as soon as the
32
- /// owning instance of ``Test`` is initialized.
33
- private var _sequence : @Sendable ( ) async -> S
24
+ /// The sequence _must_ be iterable multiple times. Hence, initializers
25
+ /// accept only _collections_, not sequences. The constraint here is only to
26
+ /// `Sequence` to allow the storage of computed sequences over collections
27
+ /// (such as `CartesianProduct` or `Zip2Sequence`) that are safe to iterate
28
+ /// multiple times.
29
+ private var _sequence : S
34
30
35
31
/// A closure that maps an element from `_sequence` to a test case instance.
36
32
///
@@ -43,12 +39,12 @@ extension Test.Case {
43
39
/// Initialize an instance of this type.
44
40
///
45
41
/// - Parameters:
46
- /// - sequence: A closure that produces the sequence of argument values
47
- /// for which test cases should be generated.
48
- /// - mapElement: A function that maps each element in the result of
49
- /// `sequence` to a corresponding instance of ``Test/Case``.
42
+ /// - sequence: The sequence of argument values for which test cases
43
+ /// should be generated.
44
+ /// - mapElement: A function that maps each element in `sequence` to a
45
+ /// corresponding instance of ``Test/Case``.
50
46
private init (
51
- sequence: @escaping @ Sendable ( ) async -> S ,
47
+ sequence: S ,
52
48
mapElement: @escaping @Sendable ( _ element: S . Element ) -> Test . Case
53
49
) {
54
50
_sequence = sequence
@@ -65,9 +61,7 @@ extension Test.Case {
65
61
) where S == CollectionOfOne < Void > {
66
62
// A beautiful hack to give us the right number of cases: iterate over a
67
63
// collection containing a single Void value.
68
- self . init {
69
- CollectionOfOne ( ( ) )
70
- } mapElement: { _ in
64
+ self . init ( sequence: CollectionOfOne ( ( ) ) ) { _ in
71
65
Test . Case ( arguments: [ ] , body: testFunction)
72
66
}
73
67
}
@@ -89,7 +83,7 @@ extension Test.Case {
89
83
/// be preferred.
90
84
@_disfavoredOverload
91
85
init (
92
- arguments collection: @escaping @ Sendable ( ) async -> S ,
86
+ arguments collection: S ,
93
87
parameters: [ Test . ParameterInfo ] ,
94
88
testFunction: @escaping @Sendable ( S . Element) async throws -> Void
95
89
) where S: Collection {
@@ -128,13 +122,11 @@ extension Test.Case {
128
122
/// - testFunction: The test function to which each generated test case
129
123
/// passes an argument value from `collection`.
130
124
init < C1, C2> (
131
- arguments collection1: @escaping @ Sendable ( ) async -> C1 , _ collection2: @escaping @ Sendable ( ) async -> C2 ,
125
+ arguments collection1: C1 , _ collection2: C2 ,
132
126
parameters: [ Test . ParameterInfo ] ,
133
127
testFunction: @escaping @Sendable ( C1 . Element, C2 . Element) async throws -> Void
134
128
) where S == CartesianProduct < C1 , C2 > {
135
- self . init {
136
- await cartesianProduct ( collection1 ( ) , collection2 ( ) )
137
- } mapElement: { element in
129
+ self . init ( sequence: cartesianProduct ( collection1, collection2) ) { element in
138
130
Test . Case ( values: [ element. 0 , element. 1 ] , parameters: parameters) {
139
131
try await testFunction ( element. 0 , element. 1 )
140
132
}
@@ -160,7 +152,7 @@ extension Test.Case {
160
152
/// ([103416861](rdar://103416861))
161
153
/// }
162
154
private init < E1, E2> (
163
- sequence: @escaping @ Sendable ( ) async -> S ,
155
+ sequence: S ,
164
156
parameters: [ Test . ParameterInfo ] ,
165
157
testFunction: @escaping @Sendable ( ( E1, E2) ) async throws -> Void
166
158
) where S. Element == ( E1 , E2 ) , E1: Sendable , E2: Sendable {
@@ -198,7 +190,7 @@ extension Test.Case {
198
190
/// ([103416861](rdar://103416861))
199
191
/// }
200
192
init < E1, E2> (
201
- arguments collection: @escaping @ Sendable ( ) async -> S ,
193
+ arguments collection: S ,
202
194
parameters: [ Test . ParameterInfo ] ,
203
195
testFunction: @escaping @Sendable ( ( E1, E2) ) async throws -> Void
204
196
) where S: Collection , S. Element == ( E1 , E2 ) {
@@ -216,7 +208,7 @@ extension Test.Case {
216
208
/// - testFunction: The test function to which each generated test case
217
209
/// passes an argument value from `zippedCollections`.
218
210
init < C1, C2> (
219
- arguments zippedCollections: @escaping @ Sendable ( ) async -> Zip2Sequence < C1 , C2 > ,
211
+ arguments zippedCollections: Zip2Sequence < C1 , C2 > ,
220
212
parameters: [ Test . ParameterInfo ] ,
221
213
testFunction: @escaping @Sendable ( ( C1 . Element, C2 . Element) ) async throws -> Void
222
214
) where S == Zip2Sequence < C1 , C2 > , C1: Collection , C2: Collection {
@@ -240,7 +232,7 @@ extension Test.Case {
240
232
/// collections of 2-tuples because the `Element` tuple type for
241
233
/// `Dictionary` includes labels (`(key: Key, value: Value)`).
242
234
init < Key, Value> (
243
- arguments dictionary: @escaping @ Sendable ( ) async -> Dictionary < Key , Value > ,
235
+ arguments dictionary: Dictionary < Key , Value > ,
244
236
parameters: [ Test . ParameterInfo ] ,
245
237
testFunction: @escaping @Sendable ( ( Key, Value) ) async throws -> Void
246
238
) where S == Dictionary < Key , Value > {
@@ -261,17 +253,14 @@ extension Test.Case {
261
253
}
262
254
}
263
255
264
- // MARK: - Sequence generation
256
+ // MARK: - Sequence
265
257
266
- extension Test . Case . Generator {
267
- /// Generate a sequence of test cases corresponding to the sequence of
268
- /// elements passed to this instance during instantiation.
269
- ///
270
- /// - Returns:
271
- /// A sequence of ``Test/Case`` instances.
272
- ///
273
- /// Each call to this function generates a new sequence.
274
- func generate( ) async -> some Sequence < Test . Case > {
275
- await _sequence ( ) . lazy. map ( _mapElement)
258
+ extension Test . Case . Generator : Sequence {
259
+ func makeIterator( ) -> some IteratorProtocol < Test . Case > {
260
+ _sequence. lazy. map ( _mapElement) . makeIterator ( )
261
+ }
262
+
263
+ var underestimatedCount : Int {
264
+ _sequence. underestimatedCount
276
265
}
277
266
}
0 commit comments