Skip to content

Commit ad8f592

Browse files
authored
Merge pull request #330 from apple/revert-326-chefski/add-async-support
Revert "[REVIEW] Add Async Support to XCTest"
2 parents 38f9fa1 + 6569394 commit ad8f592

File tree

9 files changed

+26
-372
lines changed

9 files changed

+26
-372
lines changed

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,3 @@ xcuserdata
44
*.xcscmblueprint
55
.build/
66
Output/
7-
Tests/Functional/.lit_test_times.txt

CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ add_library(XCTest
2929
Sources/XCTest/Private/SourceLocation.swift
3030
Sources/XCTest/Private/WaiterManager.swift
3131
Sources/XCTest/Private/IgnoredErrors.swift
32-
Sources/XCTest/Private/XCTestCase.TearDownBlocksState.swift
3332
Sources/XCTest/Public/XCTestRun.swift
3433
Sources/XCTest/Public/XCTestMain.swift
3534
Sources/XCTest/Public/XCTestCase.swift

Sources/XCTest/Private/XCTestCase.TearDownBlocksState.swift

-44
This file was deleted.

Sources/XCTest/Public/XCAbstractTest.swift

-9
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@ open class XCTest {
5252
perform(testRun!)
5353
}
5454

55-
/// Async setup method called before the invocation of `setUpWithError` for each test method in the class.
56-
@available(macOS 12.0, *)
57-
open func setUp() async throws {}
58-
5955
/// Setup method called before the invocation of `setUp` and the test method
6056
/// for each test method in the class.
6157
open func setUpWithError() throws {}
@@ -72,11 +68,6 @@ open class XCTest {
7268
/// for each test method in the class.
7369
open func tearDownWithError() throws {}
7470

75-
/// Async teardown method which is called after the invocation of `tearDownWithError`
76-
/// for each test method in the class.
77-
@available(macOS 12.0, *)
78-
open func tearDown() async throws {}
79-
8071
// FIXME: This initializer is required due to a Swift compiler bug on Linux.
8172
// It should be removed once the bug is fixed.
8273
public init() {}

Sources/XCTest/Public/XCTestCase.swift

+24-107
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)