@@ -99,58 +99,128 @@ class FutureTests: XCTestCase {
99
99
let workQ = DispatchQueue ( label: " WorkQueue " )
100
100
let completionQ = DispatchQueue ( label: " CompletionQueue " )
101
101
102
- let expectIsAsyncA = self . expectation ( description: " Is Async " )
103
- var resA : Int = 2
102
+ let expectIsAsync = self . expectation ( description: " Is Async " )
103
+ var res : Int = 2
104
104
Future < Int > ( work: {
105
105
// is working on the correct queue
106
106
XCTAssertEqual ( DispatchQueue . currentLabel, workQ. label)
107
107
108
- return resA * 2
108
+ return res * 2
109
109
} )
110
110
. async ( delay: 1 , on: workQ, completesOn: completionQ)
111
111
. run {
112
112
let end = Date . timeIntervalSinceReferenceDate
113
- resA = $0
113
+ res = $0
114
114
115
115
// work has been done
116
- XCTAssertEqual ( resA , 4 )
116
+ XCTAssertEqual ( res , 4 )
117
117
// it was delayed
118
118
XCTAssert ( end - start > 1 )
119
119
// is completing on the correct queue
120
120
XCTAssertEqual ( DispatchQueue . currentLabel, completionQ. label)
121
121
122
- expectIsAsyncA . fulfill ( )
122
+ expectIsAsync . fulfill ( )
123
123
}
124
124
125
125
// it is async
126
- XCTAssertEqual ( resA, 2 )
127
-
128
- self . wait ( for: [ expectIsAsyncA] , timeout: 5 )
126
+ XCTAssertEqual ( res, 2 )
129
127
128
+ self . wait ( for: [ expectIsAsync] , timeout: 5 )
129
+ }
130
+
131
+ func testAsyncOnMain( ) {
130
132
131
- let expectIsAsyncB = self . expectation ( description: " Is Async " )
132
- var resB : Int = 2
133
+ let expectIsAsync = self . expectation ( description: " Is Async " )
134
+ var res : Int = 2
133
135
Future < Int > ( work: {
134
136
// is working on the correct queue
135
137
XCTAssertEqual ( DispatchQueue . currentLabel, DispatchQueue . main. label)
136
138
137
- return resB * 2
139
+ return res * 2
138
140
} )
139
141
. asyncOnMain ( )
140
142
. run {
141
- resB = $0
143
+ res = $0
142
144
143
- XCTAssertEqual ( resB , 4 )
145
+ XCTAssertEqual ( res , 4 )
144
146
145
147
// is completing on the correct queue
146
148
XCTAssertEqual ( DispatchQueue . currentLabel, DispatchQueue . main. label)
147
149
148
- expectIsAsyncB . fulfill ( )
150
+ expectIsAsync . fulfill ( )
149
151
}
150
152
151
153
// it is async
152
- XCTAssertEqual ( resB, 2 )
153
- self . wait ( for: [ expectIsAsyncB] , timeout: 5 )
154
+ XCTAssertEqual ( res, 2 )
155
+ self . wait ( for: [ expectIsAsync] , timeout: 5 )
156
+ }
157
+
158
+ func testAsyncBlockingQueue( ) {
159
+
160
+ let start = Date . timeIntervalSinceReferenceDate
161
+
162
+ let workQ = DispatchQueue ( label: " WorkQueue " )
163
+ let completionQ = DispatchQueue ( label: " CompletionQueue " )
164
+
165
+ let expectIsAsync = self . expectation ( description: " Is Async " )
166
+ var res : Int = 2
167
+ Future < Int > ( run: { cb in
168
+ // is working on the correct queue
169
+ XCTAssertEqual ( DispatchQueue . currentLabel, workQ. label)
170
+
171
+ // wait a second before completing the work
172
+ DispatchQueue . main. asyncAfter ( deadline: . now( ) + 1 ) {
173
+ XCTAssertEqual ( res, 2 )
174
+ res *= 2
175
+ cb ( res)
176
+ }
177
+ } )
178
+ . async ( delay: 0 , on: workQ, blocksQueue: true , completesOn: completionQ)
179
+ . run { returnedRes in
180
+ let end = Date . timeIntervalSinceReferenceDate
181
+
182
+ // Note: this callback occurs _after_ the queue is unblocked
183
+ // so returnedRes may not equal res (as the other work may have already occurred.
184
+
185
+ // work has been done
186
+ XCTAssertEqual ( returnedRes, 4 )
187
+ // it was delayed
188
+ XCTAssert ( end - start > 1 )
189
+ // is completing on the correct queue
190
+ XCTAssertEqual ( DispatchQueue . currentLabel, completionQ. label)
191
+ }
192
+
193
+ // start some other work on the same queue.
194
+ Future < Int > ( work: {
195
+ // is working on the correct queue
196
+ XCTAssertEqual ( DispatchQueue . currentLabel, workQ. label)
197
+
198
+ // the previously defined future has been run first
199
+ XCTAssertEqual ( res, 4 )
200
+
201
+ return res + 1
202
+ } )
203
+ . async ( delay: 0 , on: workQ, blocksQueue: true , completesOn: completionQ)
204
+ . run {
205
+ let end = Date . timeIntervalSinceReferenceDate
206
+ res = $0
207
+
208
+ // work has been done (after the previous work)
209
+ XCTAssertEqual ( res, 5 )
210
+ // it was delayed (waiting for prev work to finish)
211
+ XCTAssert ( end - start > 1 )
212
+ // is completing on the correct queue
213
+ XCTAssertEqual ( DispatchQueue . currentLabel, completionQ. label)
214
+
215
+ expectIsAsync. fulfill ( )
216
+ }
217
+
218
+ // it is async - the res hasnt been changed yet
219
+ XCTAssertEqual ( res, 2 )
220
+
221
+ self . wait ( for: [ expectIsAsync] , timeout: 5 )
222
+
223
+ XCTAssertEqual ( res, 5 )
154
224
}
155
225
156
226
func testParallel( ) {
0 commit comments