Skip to content

Commit ed88c55

Browse files
committed
Update Require DSL to be (mostly) Sendable. (#1130)
* Update Require DSL to largely be Sendable * Fix now-broken tests
1 parent c92afee commit ed88c55

6 files changed

Lines changed: 75 additions & 67 deletions

File tree

Sources/Nimble/DSL+Require.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public func requires(file: FileString = #file, line: UInt = #line, customError:
123123
/// `require` will return the result of the expression if the matcher passes, and throw an error if not.
124124
/// if a `customError` is given, then that will be thrown. Otherwise, a ``RequireError`` will be thrown.
125125
@discardableResult
126-
public func require<T>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @escaping () async throws -> T?) -> AsyncRequirement<T> {
126+
public func require<T: Sendable>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @escaping @Sendable () async throws -> T?) -> AsyncRequirement<T> {
127127
return AsyncRequirement(
128128
expression: AsyncExpression(
129129
expression: expression,
@@ -137,7 +137,7 @@ public func require<T>(file: FileString = #file, line: UInt = #line, customError
137137
/// `require` will return the result of the expression if the matcher passes, and throw an error if not.
138138
/// if a `customError` is given, then that will be thrown. Otherwise, a ``RequireError`` will be thrown.
139139
@discardableResult
140-
public func require<T>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: () -> (() async throws -> T)) -> AsyncRequirement<T> {
140+
public func require<T: Sendable>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: () -> (@Sendable () async throws -> T)) -> AsyncRequirement<T> {
141141
return AsyncRequirement(
142142
expression: AsyncExpression(
143143
expression: expression(),
@@ -151,7 +151,7 @@ public func require<T>(file: FileString = #file, line: UInt = #line, customError
151151
/// `require` will return the result of the expression if the matcher passes, and throw an error if not.
152152
/// if a `customError` is given, then that will be thrown. Otherwise, a ``RequireError`` will be thrown.
153153
@discardableResult
154-
public func require<T>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: () -> (() async throws -> T?)) -> AsyncRequirement<T> {
154+
public func require<T: Sendable>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: () -> (@Sendable () async throws -> T?)) -> AsyncRequirement<T> {
155155
return AsyncRequirement(
156156
expression: AsyncExpression(
157157
expression: expression(),
@@ -167,7 +167,7 @@ public func require<T>(file: FileString = #file, line: UInt = #line, customError
167167
///
168168
/// This is provided to avoid confusion between `require -> SyncRequirement` and `require -> AsyncRequirement`.
169169
@discardableResult
170-
public func requirea<T>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @autoclosure @escaping () async throws -> T?) async -> AsyncRequirement<T> {
170+
public func requirea<T: Sendable>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @autoclosure @escaping @Sendable () async throws -> T?) async -> AsyncRequirement<T> {
171171
return AsyncRequirement(
172172
expression: AsyncExpression(
173173
expression: expression,
@@ -183,7 +183,7 @@ public func requirea<T>(file: FileString = #file, line: UInt = #line, customErro
183183
///
184184
/// This is provided to avoid confusion between `require -> SyncRequirement` and `require -> AsyncRequirement`
185185
@discardableResult
186-
public func requirea<T>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @autoclosure () -> (() async throws -> T)) async -> AsyncRequirement<T> {
186+
public func requirea<T: Sendable>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @autoclosure () -> (@Sendable () async throws -> T)) async -> AsyncRequirement<T> {
187187
return AsyncRequirement(
188188
expression: AsyncExpression(
189189
expression: expression(),
@@ -199,7 +199,7 @@ public func requirea<T>(file: FileString = #file, line: UInt = #line, customErro
199199
///
200200
/// This is provided to avoid confusion between `require -> SyncRequirement` and `require -> AsyncRequirement`
201201
@discardableResult
202-
public func requirea<T>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @autoclosure () -> (() async throws -> T?)) async -> AsyncRequirement<T> {
202+
public func requirea<T: Sendable>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @autoclosure () -> (@Sendable () async throws -> T?)) async -> AsyncRequirement<T> {
203203
return AsyncRequirement(
204204
expression: AsyncExpression(
205205
expression: expression(),
@@ -256,7 +256,7 @@ public func unwraps<T>(file: FileString = #file, line: UInt = #line, customError
256256
/// `unwrap` will return the result of the expression if it is non-nil, and throw an error if the value is nil.
257257
/// if a `customError` is given, then that will be thrown. Otherwise, a ``RequireError`` will be thrown.
258258
@discardableResult
259-
public func unwrap<T>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @escaping () async throws -> T?) async throws -> T {
259+
public func unwrap<T: Sendable>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @escaping @Sendable () async throws -> T?) async throws -> T {
260260
try await requirea(file: file, line: line, customError: customError, try await expression()).toNot(beNil())
261261
}
262262

@@ -266,7 +266,7 @@ public func unwrap<T>(file: FileString = #file, line: UInt = #line, customError:
266266
/// `unwrap` will return the result of the expression if it is non-nil, and throw an error if the value is nil.
267267
/// if a `customError` is given, then that will be thrown. Otherwise, a ``RequireError`` will be thrown.
268268
@discardableResult
269-
public func unwrap<T>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: () -> (() async throws -> T?)) async throws -> T {
269+
public func unwrap<T: Sendable>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: () -> (@Sendable () async throws -> T?)) async throws -> T {
270270
try await requirea(file: file, line: line, customError: customError, expression()).toNot(beNil())
271271
}
272272

@@ -276,7 +276,7 @@ public func unwrap<T>(file: FileString = #file, line: UInt = #line, customError:
276276
/// `unwrapa` will return the result of the expression if it is non-nil, and throw an error if the value is nil.
277277
/// if a `customError` is given, then that will be thrown. Otherwise, a ``RequireError`` will be thrown.
278278
@discardableResult
279-
public func unwrapa<T>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @autoclosure @escaping () async throws -> T?) async throws -> T {
279+
public func unwrapa<T: Sendable>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @autoclosure @escaping @Sendable () async throws -> T?) async throws -> T {
280280
try await requirea(file: file, line: line, customError: customError, try await expression()).toNot(beNil())
281281
}
282282

@@ -286,6 +286,6 @@ public func unwrapa<T>(file: FileString = #file, line: UInt = #line, customError
286286
/// `unwrapa` will return the result of the expression if it is non-nil, and throw an error if the value is nil.
287287
/// if a `customError` is given, then that will be thrown. Otherwise, a ``RequireError`` will be thrown.
288288
@discardableResult
289-
public func unwrapa<T>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @autoclosure () -> (() async throws -> T?)) async throws -> T {
289+
public func unwrapa<T: Sendable>(file: FileString = #file, line: UInt = #line, customError: Error? = nil, _ expression: @autoclosure () -> (@Sendable () async throws -> T?)) async throws -> T {
290290
try await requirea(file: file, line: line, customError: customError, expression()).toNot(beNil())
291291
}

Sources/Nimble/Matchers/PostNotification.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ private func _postNotifications<Out>(
8080
let message = ExpectationMessage
8181
.expectedTo("post notifications - but was called off the main thread.")
8282
.appended(details: "postNotifications and postDistributedNotifications attempted to run their predicate off the main thread. This is a bug in Nimble.")
83-
return PredicateResult(status: .fail, message: message)
83+
return MatcherResult(status: .fail, message: message)
8484
}
8585

8686
let collectorNotificationsExpression = Expression(

Sources/Nimble/Polling+Require.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@ extension SyncRequirement {
189189
public func alwaysTo(_ matcher: Matcher<Value>, until: NimbleTimeInterval = PollingDefaults.timeout, pollInterval: NimbleTimeInterval = PollingDefaults.pollInterval, description: String? = nil) throws -> Value {
190190
return try toAlways(matcher, until: until, pollInterval: pollInterval, description: description)
191191
}
192+
}
192193

194+
extension SyncRequirement where Value: Sendable {
193195
// MARK: - Async Polling with Synchronous Matchers
194196
/// Tests the actual value using a matcher to match by checking continuously
195197
/// at each pollInterval until the timeout is reached.
@@ -734,28 +736,28 @@ public func pollUnwraps<T>(file: FileString = #file, line: UInt = #line, _ expre
734736
/// Makes sure that the async expression evaluates to a non-nil value, otherwise throw an error.
735737
/// As you can tell, this is a much less verbose equivalent to `requirea(expression).toEventuallyNot(beNil())`
736738
@discardableResult
737-
public func pollUnwrap<T>(file: FileString = #file, line: UInt = #line, _ expression: @escaping () async throws -> T?) async throws -> T {
739+
public func pollUnwrap<T: Sendable>(file: FileString = #file, line: UInt = #line, _ expression: @escaping @Sendable () async throws -> T?) async throws -> T {
738740
try await requirea(file: file, line: line, try await expression()).toEventuallyNot(beNil())
739741
}
740742

741743
/// Makes sure that the async expression evaluates to a non-nil value, otherwise throw an error.
742744
/// As you can tell, this is a much less verbose equivalent to `requirea(expression).toEventuallyNot(beNil())`
743745
@discardableResult
744-
public func pollUnwrap<T>(file: FileString = #file, line: UInt = #line, _ expression: () -> (() async throws -> T?)) async throws -> T {
746+
public func pollUnwrap<T: Sendable>(file: FileString = #file, line: UInt = #line, _ expression: () -> (@Sendable () async throws -> T?)) async throws -> T {
745747
try await requirea(file: file, line: line, expression()).toEventuallyNot(beNil())
746748
}
747749

748750
/// Makes sure that the async expression evaluates to a non-nil value, otherwise throw an error.
749751
/// As you can tell, this is a much less verbose equivalent to `requirea(expression).toEventuallyNot(beNil())`
750752
@discardableResult
751-
public func pollUnwrapa<T>(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure @escaping () async throws -> T?) async throws -> T {
753+
public func pollUnwrapa<T: Sendable>(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure @escaping @Sendable () async throws -> T?) async throws -> T {
752754
try await requirea(file: file, line: line, try await expression()).toEventuallyNot(beNil())
753755
}
754756

755757
/// Makes sure that the async expression evaluates to a non-nil value, otherwise throw an error.
756758
/// As you can tell, this is a much less verbose equivalent to `requirea(expression).toEventuallyNot(beNil())`
757759
@discardableResult
758-
public func pollUnwrapa<T>(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure () -> (() async throws -> T?)) async throws -> T {
760+
public func pollUnwrapa<T: Sendable>(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure () -> (@Sendable () async throws -> T?)) async throws -> T {
759761
try await requirea(file: file, line: line, expression()).toEventuallyNot(beNil())
760762
}
761763

Sources/Nimble/Requirement.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Foundation
22

3-
public struct RequireError: Error, CustomNSError {
3+
public struct RequireError: Error, CustomNSError, Sendable {
44
let message: String
55
let location: SourceLocation
66

@@ -115,7 +115,9 @@ public struct SyncRequirement<Value> {
115115
public func notTo(_ matcher: Matcher<Value>, description: String? = nil) throws -> Value {
116116
try toNot(matcher, description: description)
117117
}
118+
}
118119

120+
extension SyncRequirement where Value: Sendable {
119121
// MARK: - AsyncMatchers
120122
/// Tests the actual value using a matcher to match.
121123
@discardableResult
@@ -140,7 +142,7 @@ public struct SyncRequirement<Value> {
140142
}
141143
}
142144

143-
public struct AsyncRequirement<Value> {
145+
public struct AsyncRequirement<Value: Sendable>: Sendable {
144146
public let expression: AsyncExpression<Value>
145147

146148
/// A custom error to throw.

0 commit comments

Comments
 (0)