@@ -195,23 +195,23 @@ open class XCTestCase: XCTest {
195
195
/// class.
196
196
open class func tearDown( ) { }
197
197
198
- private let teardownBlocksState = TeardownBlocksState ( )
198
+ private var teardownBlocks : [ ( ) -> Void ] = [ ]
199
+ private var teardownBlocksDequeued : Bool = false
200
+ private let teardownBlocksQueue : DispatchQueue = DispatchQueue ( label: " org.swift.XCTest.XCTestCase.teardownBlocks " )
199
201
200
202
/// Registers a block of teardown code to be run after the current test
201
203
/// method ends.
202
204
open func addTeardownBlock( _ block: @escaping ( ) -> Void ) {
203
- teardownBlocksState. append ( block)
204
- }
205
-
206
- /// Registers a block of teardown code to be run after the current test
207
- /// method ends.
208
- @available ( macOS 12 . 0 , * )
209
- public func addTeardownBlock( _ block: @Sendable @escaping ( ) async throws -> Void ) {
210
- teardownBlocksState. appendAsync ( block)
205
+ teardownBlocksQueue. sync {
206
+ precondition ( !self . teardownBlocksDequeued, " API violation -- attempting to add a teardown block after teardown blocks have been dequeued " )
207
+ self . teardownBlocks. append ( block)
208
+ }
211
209
}
212
210
213
211
private func performSetUpSequence( ) {
214
- func handleErrorDuringSetUp( _ error: Error ) {
212
+ do {
213
+ try setUpWithError ( )
214
+ } catch {
215
215
if error. xct_shouldRecordAsTestFailure {
216
216
recordFailure ( for: error)
217
217
}
@@ -225,60 +225,33 @@ open class XCTestCase: XCTest {
225
225
}
226
226
}
227
227
228
- do {
229
- if #available( macOS 12 . 0 , * ) {
230
- try awaitUsingExpectation {
231
- try await self . setUp ( )
232
- }
233
- }
234
- } catch {
235
- handleErrorDuringSetUp ( error)
236
- }
237
-
238
- do {
239
- try setUpWithError ( )
240
- } catch {
241
- handleErrorDuringSetUp ( error)
242
- }
243
-
244
228
setUp ( )
245
229
}
246
230
247
231
private func performTearDownSequence( ) {
248
- func handleErrorDuringTearDown( _ error: Error ) {
249
- if error. xct_shouldRecordAsTestFailure {
250
- recordFailure ( for: error)
251
- }
252
- }
253
-
254
- func runTeardownBlocks( ) {
255
- for block in self . teardownBlocksState. finalize ( ) . reversed ( ) {
256
- do {
257
- try block ( )
258
- } catch {
259
- handleErrorDuringTearDown ( error)
260
- }
261
- }
262
- }
263
-
264
232
runTeardownBlocks ( )
265
233
266
234
tearDown ( )
267
235
268
236
do {
269
237
try tearDownWithError ( )
270
238
} catch {
271
- handleErrorDuringTearDown ( error)
239
+ if error. xct_shouldRecordAsTestFailure {
240
+ recordFailure ( for: error)
241
+ }
242
+ }
243
+ }
244
+
245
+ private func runTeardownBlocks( ) {
246
+ let blocks = teardownBlocksQueue. sync { ( ) -> [ ( ) -> Void ] in
247
+ self . teardownBlocksDequeued = true
248
+ let blocks = self . teardownBlocks
249
+ self . teardownBlocks = [ ]
250
+ return blocks
272
251
}
273
252
274
- do {
275
- if #available( macOS 12 . 0 , * ) {
276
- try awaitUsingExpectation {
277
- try await self . tearDown ( )
278
- }
279
- }
280
- } catch {
281
- handleErrorDuringTearDown ( error)
253
+ for block in blocks. reversed ( ) {
254
+ block ( )
282
255
}
283
256
}
284
257
@@ -319,59 +292,3 @@ private func test<T: XCTestCase>(_ testFunc: @escaping (T) -> () throws -> Void)
319
292
try testFunc ( testCase) ( )
320
293
}
321
294
}
322
-
323
- @available ( macOS 12 . 0 , * )
324
- public func asyncTest< T: XCTestCase > (
325
- _ testClosureGenerator: @escaping ( T ) -> ( ) async throws -> Void
326
- ) -> ( T ) -> ( ) throws -> Void {
327
- return { ( testType: T ) in
328
- let testClosure = testClosureGenerator ( testType)
329
- return {
330
- try awaitUsingExpectation ( testClosure)
331
- }
332
- }
333
- }
334
-
335
- @available ( macOS 12 . 0 , * )
336
- func awaitUsingExpectation(
337
- _ closure: @escaping ( ) async throws -> Void
338
- ) throws -> Void {
339
- let expectation = XCTestExpectation ( description: " async test completion " )
340
- let thrownErrorWrapper = ThrownErrorWrapper ( )
341
-
342
- Task {
343
- defer { expectation. fulfill ( ) }
344
-
345
- do {
346
- try await closure ( )
347
- } catch {
348
- thrownErrorWrapper. error = error
349
- }
350
- }
351
-
352
- _ = XCTWaiter . wait ( for: [ expectation] , timeout: asyncTestTimeout)
353
-
354
- if let error = thrownErrorWrapper. error {
355
- throw error
356
- }
357
- }
358
-
359
- private final class ThrownErrorWrapper : @unchecked Sendable {
360
-
361
- private var _error : Error ?
362
-
363
- var error : Error ? {
364
- get {
365
- XCTWaiter . subsystemQueue. sync { _error }
366
- }
367
- set {
368
- XCTWaiter . subsystemQueue. sync { _error = newValue }
369
- }
370
- }
371
- }
372
-
373
-
374
- // This time interval is set to a very large value due to their being no real native timeout functionality within corelibs-xctest.
375
- // With the introduction of async/await support, the framework now relies on XCTestExpectations internally to coordinate the addition async portions of setup and tear down.
376
- // This time interval is the timeout corelibs-xctest uses with XCTestExpectations.
377
- private let asyncTestTimeout : TimeInterval = 60 * 60 * 24 * 30
0 commit comments