File: Assertions.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (147 lines) | stat: -rw-r--r-- 4,933 bytes parent folder | download
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)
    }
  }
}