1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import XCTest
/// Same as `XCTAssertNoThrow` but executes the trailing closure.
public func assertNoThrow<T>(
_ expression: () throws -> T,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line
) {
XCTAssertNoThrow(try expression(), message(), file: file, line: line)
}
/// Same as `assertNoThrow` but allows the closure to be `async`.
public func assertNoThrow<T>(
_ expression: () async throws -> T,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line
) async {
do {
_ = try await expression()
} catch {
XCTFail("Expression was not expected to throw but threw \(error)", file: file, line: line)
}
}
/// Same as `XCTAssertThrows` but allows the expression to be async
public func assertThrowsError<T>(
_ expression: @autoclosure () async throws -> T,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line,
errorHandler: (_ error: Error) -> Void = { _ in }
) async {
let didThrow: Bool
do {
_ = try await expression()
didThrow = false
} catch {
errorHandler(error)
didThrow = true
}
if !didThrow {
XCTFail("Expression was expected to throw but did not throw", file: file, line: line)
}
}
/// Same as `XCTAssertEqual` but doesn't take autoclosures and thus `expression1`
/// and `expression2` can contain `await`.
public func assertEqual<T: Equatable>(
_ expression1: T,
_ expression2: T,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line
) {
XCTAssertEqual(expression1, expression2, message(), file: file, line: line)
}
/// Same as `XCTAssertTrue` but doesn't take autoclosures and thus `expression` can contain `await`.
public func assertTrue(
_ expression: Bool,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line
) {
XCTAssertTrue(expression, message(), file: file, line: line)
}
/// Same as `XCTAssertNil` but doesn't take autoclosures and thus `expression`
/// can contain `await`.
public func assertNil<T>(
_ expression: T?,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line
) {
XCTAssertNil(expression, message(), file: file, line: line)
}
/// Same as `XCTAssertNotNil` but doesn't take autoclosures and thus `expression`
/// can contain `await`.
public func assertNotNil<T>(
_ expression: T?,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line
) {
XCTAssertNotNil(expression, message(), file: file, line: line)
}
/// Same as `XCTUnwrap` but doesn't take autoclosures and thus `expression`
/// can contain `await`.
public func unwrap<T>(
_ expression: T?,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line
) throws -> T {
return try XCTUnwrap(expression, file: file, line: line)
}
extension XCTestCase {
private struct ExpectationNotFulfilledError: Error, CustomStringConvertible {
var expecatations: [XCTestExpectation]
var description: String {
return """
One of the expectation was not fulfilled within timeout: \
\(expecatations.map(\.description).joined(separator: ", "))
"""
}
}
/// Wait for the given expectations to be fulfilled. If the expectations aren't
/// fulfilled within `timeout`, throw an error, aborting the test execution.
public func fulfillmentOfOrThrow(
_ expectations: [XCTestExpectation],
timeout: TimeInterval = defaultTimeout,
enforceOrder enforceOrderOfFulfillment: Bool = false
) async throws {
// `XCTWaiter.fulfillment` was introduced in the macOS 13.3 SDK but marked as being available on macOS 10.15.
// At the same time that XCTWaiter.fulfillment was introduced `XCTWaiter.wait` was deprecated in async contexts.
// This means that we can't write code that compiles without warnings with both the macOS 13.3 and any previous SDK.
// Accepting the warning here when compiling with macOS 13.3 or later is the only thing that I know of that we can do here.
let started = await XCTWaiter.fulfillment(
of: expectations,
timeout: timeout,
enforceOrder: enforceOrderOfFulfillment
)
if started != .completed {
throw ExpectationNotFulfilledError(expecatations: expectations)
}
}
}
|