From ee07c6b452cdd9d97e627a959b9012246b1da898 Mon Sep 17 00:00:00 2001 From: Josh Wright Date: Fri, 1 Sep 2023 17:07:09 -0700 Subject: [PATCH] Add missing Linux APIs --- Tests/Alchemy/_Utilities/Linux+Testing.swift | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Tests/Alchemy/_Utilities/Linux+Testing.swift diff --git a/Tests/Alchemy/_Utilities/Linux+Testing.swift b/Tests/Alchemy/_Utilities/Linux+Testing.swift new file mode 100644 index 00000000..0d4e0c4e --- /dev/null +++ b/Tests/Alchemy/_Utilities/Linux+Testing.swift @@ -0,0 +1,33 @@ +#if os(Linux) +extension XCTestCase { + /// Wait on an array of expectations for up to the specified timeout, and optionally specify whether they + /// must be fulfilled in the given order. May return early based on fulfillment of the waited on expectations. + /// + /// - Parameter expectations: The expectations to wait on. + /// - Parameter timeout: The maximum total time duration to wait on all expectations. + /// - Parameter enforceOrder: Specifies whether the expectations must be fulfilled in the order + /// they are specified in the `expectations` Array. Default is false. + /// - Parameter file: The file name to use in the error message if + /// expectations are not fulfilled before the given timeout. Default is the file + /// containing the call to this method. It is rare to provide this + /// parameter when calling this method. + /// - Parameter line: The line number to use in the error message if the + /// expectations are not fulfilled before the given timeout. Default is the line + /// number of the call to this method in the calling file. It is rare to + /// provide this parameter when calling this method. + /// + /// - SeeAlso: XCTWaiter + @available(macOS 12.0, *) + func fulfillment(of expectations: [XCTestExpectation], timeout: TimeInterval, enforceOrder: Bool = false, file: StaticString = #file, line: Int = #line) async { + return await withCheckedContinuation { continuation in + // This function operates by blocking a background thread instead of one owned by libdispatch or by the + // Swift runtime (as used by Swift concurrency.) To ensure we use a thread owned by neither subsystem, use + // Foundation's Thread.detachNewThread(_:). + Thread.detachNewThread { [self] in + wait(for: expectations, timeout: timeout, enforceOrder: enforceOrder) + continuation.resume() + } + } + } +} +#endif