@@ -195,23 +195,23 @@ open class XCTestCase: XCTest {
195195 /// class.
196196 open class func tearDown( ) { }
197197
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 " )
199201
200202 /// Registers a block of teardown code to be run after the current test
201203 /// method ends.
202204 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+ }
211209 }
212210
213211 private func performSetUpSequence( ) {
214- func handleErrorDuringSetUp( _ error: Error ) {
212+ do {
213+ try setUpWithError ( )
214+ } catch {
215215 if error. xct_shouldRecordAsTestFailure {
216216 recordFailure ( for: error)
217217 }
@@ -225,60 +225,33 @@ open class XCTestCase: XCTest {
225225 }
226226 }
227227
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-
244228 setUp ( )
245229 }
246230
247231 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-
264232 runTeardownBlocks ( )
265233
266234 tearDown ( )
267235
268236 do {
269237 try tearDownWithError ( )
270238 } 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
272251 }
273252
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 ( )
282255 }
283256 }
284257
@@ -319,59 +292,3 @@ private func test<T: XCTestCase>(_ testFunc: @escaping (T) -> () throws -> Void)
319292 try testFunc ( testCase) ( )
320293 }
321294}
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