13
13
import AsyncAlgorithms
14
14
15
15
final class TestChain2: XCTestCase {
16
- func test_chain( ) async {
17
- let chained = chain ( [ 1 , 2 , 3 ] . async , [ 4 , 5 , 6 ] . async )
16
+ func test_chain2_concatenates_elements_from_sequences_and_returns_nil_when_source_is_pastEnd( ) async {
17
+ let expected1 = [ 1 , 2 , 3 ]
18
+ let expected2 = [ 4 , 5 , 6 ]
19
+ let expected = expected1 + expected2
20
+ let chained = chain ( expected1. async , expected2. async )
21
+
18
22
var iterator = chained. makeAsyncIterator ( )
19
- var actual = [ Int] ( )
23
+ var collected = [ Int] ( )
20
24
while let item = await iterator. next ( ) {
21
- actual . append ( item)
25
+ collected . append ( item)
22
26
}
23
- XCTAssertEqual ( [ 1 , 2 , 3 , 4 , 5 , 6 ] , actual)
27
+ XCTAssertEqual ( expected, collected)
28
+
24
29
let pastEnd = await iterator. next ( )
25
30
XCTAssertNil ( pastEnd)
26
31
}
27
32
28
- func test_throwing_first ( ) async throws {
33
+ func test_chain2_outputs_elements_from_first_sequence_and_throws_when_first_throws ( ) async throws {
29
34
let chained = chain ( [ 1 , 2 , 3 ] . async . map { try throwOn ( 3 , $0) } , [ 4 , 5 , 6 ] . async )
30
35
var iterator = chained. makeAsyncIterator ( )
31
- var actual = [ Int] ( )
36
+
37
+ var collected = [ Int] ( )
32
38
do {
33
39
while let item = try await iterator. next ( ) {
34
- actual . append ( item)
40
+ collected . append ( item)
35
41
}
36
- XCTFail( )
42
+ XCTFail( " Chained sequence should throw when first sequence throws " )
37
43
} catch {
38
44
XCTAssertEqual ( Failure ( ) , error as? Failure )
39
45
}
40
- XCTAssertEqual ( [ 1 , 2 ] , actual)
46
+ XCTAssertEqual ( [ 1 , 2 ] , collected)
47
+
41
48
let pastEnd = try await iterator. next ( )
42
49
XCTAssertNil ( pastEnd)
43
50
}
44
51
45
- func test_throwing_second ( ) async throws {
52
+ func test_chain2_outputs_elements_from_sequences_and_throws_when_second_throws ( ) async throws {
46
53
let chained = chain ( [ 1 , 2 , 3 ] . async , [ 4 , 5 , 6 ] . async . map { try throwOn ( 5 , $0) } )
47
54
var iterator = chained. makeAsyncIterator ( )
48
- var actual = [ Int] ( )
55
+
56
+ var collected = [ Int] ( )
49
57
do {
50
58
while let item = try await iterator. next ( ) {
51
- actual . append ( item)
59
+ collected . append ( item)
52
60
}
53
- XCTFail( )
61
+ XCTFail( " Chained sequence should throw when second sequence throws " )
54
62
} catch {
55
63
XCTAssertEqual ( Failure ( ) , error as? Failure )
56
64
}
57
- XCTAssertEqual ( [ 1 , 2 , 3 , 4 ] , actual)
65
+ XCTAssertEqual ( collected, [ 1 , 2 , 3 , 4 ] )
66
+
58
67
let pastEnd = try await iterator. next ( )
59
68
XCTAssertNil ( pastEnd)
60
69
}
61
70
62
- func test_cancellation( ) async {
63
- let source = Indefinite ( value: " test " )
64
- let sequence = chain ( source. async , [ " past indefinite " ] . async )
71
+ func test_chain2_finishes_when_task_is_cancelled( ) async {
65
72
let finished = expectation ( description: " finished " )
66
73
let iterated = expectation ( description: " iterated " )
74
+
75
+ let source = Indefinite ( value: " test " )
76
+ let sequence = chain ( source. async , [ " past indefinite " ] . async )
77
+
67
78
let task = Task {
68
79
var firstIteration = false
69
80
for await _ in sequence {
@@ -74,84 +85,101 @@ final class TestChain2: XCTestCase {
74
85
}
75
86
finished. fulfill ( )
76
87
}
88
+
77
89
// ensure the other task actually starts
78
90
wait ( for: [ iterated] , timeout: 1.0 )
91
+
79
92
// cancellation should ensure the loop finishes
80
93
// without regards to the remaining underlying sequence
81
94
task. cancel ( )
95
+
82
96
wait ( for: [ finished] , timeout: 1.0 )
83
97
}
84
98
}
85
99
86
100
final class TestChain3: XCTestCase {
87
- func test_chain( ) async {
88
- let chained = chain ( [ 1 , 2 , 3 ] . async , [ 4 , 5 , 6 ] . async , [ 7 , 8 , 9 ] . async )
101
+ func test_chain3_concatenates_elements_from_sequences_and_returns_nil_when_source_is_pastEnd( ) async {
102
+ let expected1 = [ 1 , 2 , 3 ]
103
+ let expected2 = [ 4 , 5 , 6 ]
104
+ let expected3 = [ 7 , 8 , 9 ]
105
+ let expected = expected1 + expected2 + expected3
106
+ let chained = chain ( expected1. async , expected2. async , expected3. async )
89
107
var iterator = chained. makeAsyncIterator ( )
90
- var actual = [ Int] ( )
108
+
109
+ var collected = [ Int] ( )
91
110
while let item = await iterator. next ( ) {
92
- actual . append ( item)
111
+ collected . append ( item)
93
112
}
94
- XCTAssertEqual ( [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] , actual)
113
+ XCTAssertEqual ( expected, collected)
114
+
95
115
let pastEnd = await iterator. next ( )
96
116
XCTAssertNil ( pastEnd)
97
117
}
98
118
99
- func test_throwing_first ( ) async throws {
119
+ func test_chain3_outputs_elements_from_first_sequence_and_throws_when_first_throws ( ) async throws {
100
120
let chained = chain ( [ 1 , 2 , 3 ] . async . map { try throwOn ( 3 , $0) } , [ 4 , 5 , 6 ] . async , [ 7 , 8 , 9 ] . async )
101
121
var iterator = chained. makeAsyncIterator ( )
102
- var actual = [ Int] ( )
122
+
123
+ var collected = [ Int] ( )
103
124
do {
104
125
while let item = try await iterator. next ( ) {
105
- actual . append ( item)
126
+ collected . append ( item)
106
127
}
107
- XCTFail( )
128
+ XCTFail( " Chained sequence should throw when first sequence throws " )
108
129
} catch {
109
130
XCTAssertEqual ( Failure ( ) , error as? Failure )
110
131
}
111
- XCTAssertEqual ( [ 1 , 2 ] , actual)
132
+ XCTAssertEqual ( collected, [ 1 , 2 ] )
133
+
112
134
let pastEnd = try await iterator. next ( )
113
135
XCTAssertNil ( pastEnd)
114
136
}
115
137
116
- func test_throwing_second ( ) async throws {
138
+ func test_chain3_outputs_elements_from_sequences_and_throws_when_second_throws ( ) async throws {
117
139
let chained = chain ( [ 1 , 2 , 3 ] . async , [ 4 , 5 , 6 ] . async . map { try throwOn ( 5 , $0) } , [ 7 , 8 , 9 ] . async )
118
140
var iterator = chained. makeAsyncIterator ( )
119
- var actual = [ Int] ( )
141
+
142
+ var collected = [ Int] ( )
120
143
do {
121
144
while let item = try await iterator. next ( ) {
122
- actual . append ( item)
145
+ collected . append ( item)
123
146
}
124
- XCTFail( )
147
+ XCTFail( " Chained sequence should throw when second sequence throws " )
125
148
} catch {
126
149
XCTAssertEqual ( Failure ( ) , error as? Failure )
127
150
}
128
- XCTAssertEqual ( [ 1 , 2 , 3 , 4 ] , actual)
151
+ XCTAssertEqual ( collected, [ 1 , 2 , 3 , 4 ] )
152
+
129
153
let pastEnd = try await iterator. next ( )
130
154
XCTAssertNil ( pastEnd)
131
155
}
132
156
133
- func test_throwing_third ( ) async throws {
157
+ func test_chain3_outputs_elements_from_sequences_and_throws_when_third_throws ( ) async throws {
134
158
let chained = chain ( [ 1 , 2 , 3 ] . async , [ 4 , 5 , 6 ] . async , [ 7 , 8 , 9 ] . async . map { try throwOn ( 8 , $0) } )
135
159
var iterator = chained. makeAsyncIterator ( )
136
- var actual = [ Int] ( )
160
+
161
+ var collected = [ Int] ( )
137
162
do {
138
163
while let item = try await iterator. next ( ) {
139
- actual . append ( item)
164
+ collected . append ( item)
140
165
}
141
- XCTFail( )
166
+ XCTFail( " Chained sequence should throw when third sequence throws " )
142
167
} catch {
143
168
XCTAssertEqual ( Failure ( ) , error as? Failure )
144
169
}
145
- XCTAssertEqual ( [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ] , actual)
170
+ XCTAssertEqual ( collected, [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ] )
171
+
146
172
let pastEnd = try await iterator. next ( )
147
173
XCTAssertNil ( pastEnd)
148
174
}
149
175
150
- func test_cancellation( ) async {
151
- let source = Indefinite ( value: " test " )
152
- let sequence = chain ( source. async , [ " past indefinite " ] . async , [ " and even further " ] . async )
176
+ func test_chain3_finishes_when_task_is_cancelled( ) async {
153
177
let finished = expectation ( description: " finished " )
154
178
let iterated = expectation ( description: " iterated " )
179
+
180
+ let source = Indefinite ( value: " test " )
181
+ let sequence = chain ( source. async , [ " past indefinite " ] . async , [ " and even further " ] . async )
182
+
155
183
let task = Task {
156
184
var firstIteration = false
157
185
for await _ in sequence {
@@ -162,11 +190,14 @@ final class TestChain3: XCTestCase {
162
190
}
163
191
finished. fulfill ( )
164
192
}
193
+
165
194
// ensure the other task actually starts
166
195
wait ( for: [ iterated] , timeout: 1.0 )
196
+
167
197
// cancellation should ensure the loop finishes
168
198
// without regards to the remaining underlying sequence
169
199
task. cancel ( )
200
+
170
201
wait ( for: [ finished] , timeout: 1.0 )
171
202
}
172
203
}
0 commit comments