Skip to content

Commit

Permalink
All parts of the dsl must take in sending
Browse files Browse the repository at this point in the history
  • Loading branch information
younata committed Oct 14, 2024
1 parent ff61b40 commit 7886e7d
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 57 deletions.
16 changes: 8 additions & 8 deletions Sources/Nimble/DSL+AsyncAwait.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Dispatch
#endif

/// Make an ``AsyncExpectation`` on a given actual value. The value given is lazily evaluated.
public func expect<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @escaping @Sendable () async throws -> T?) -> AsyncExpectation<T> {
public func expect<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @escaping @Sendable () async throws -> sending T?) -> AsyncExpectation<T> {
return AsyncExpectation(
expression: AsyncExpression(
expression: expression,
Expand All @@ -12,7 +12,7 @@ public func expect<T: Sendable>(fileID: String = #fileID, file: FileString = #fi
}

/// Make an ``AsyncExpectation`` on a given actual value. The closure is lazily invoked.
public func expect<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @Sendable () -> (@Sendable () async throws -> T)) -> AsyncExpectation<T> {
public func expect<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @Sendable () -> (@Sendable () async throws -> sending T)) -> AsyncExpectation<T> {
return AsyncExpectation(
expression: AsyncExpression(
expression: expression(),
Expand All @@ -21,7 +21,7 @@ public func expect<T: Sendable>(fileID: String = #fileID, file: FileString = #fi
}

/// Make an ``AsyncExpectation`` on a given actual value. The closure is lazily invoked.
public func expect<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @Sendable () -> (@Sendable () async throws -> T?)) -> AsyncExpectation<T> {
public func expect<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @Sendable () -> (@Sendable () async throws -> sending T?)) -> AsyncExpectation<T> {
return AsyncExpectation(
expression: AsyncExpression(
expression: expression(),
Expand All @@ -30,7 +30,7 @@ public func expect<T: Sendable>(fileID: String = #fileID, file: FileString = #fi
}

/// Make an ``AsyncExpectation`` on a given actual value. The closure is lazily invoked.
public func expect(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @Sendable () -> (@Sendable () async throws -> Void)) -> AsyncExpectation<Void> {
public func expect(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @Sendable () -> (@Sendable () async throws -> sending Void)) -> AsyncExpectation<Void> {
return AsyncExpectation(
expression: AsyncExpression(
expression: expression(),
Expand All @@ -40,7 +40,7 @@ public func expect(fileID: String = #fileID, file: FileString = #filePath, line:

/// Make an ``AsyncExpectation`` on a given actual value. The value given is lazily evaluated.
/// This is provided to avoid confusion between `expect -> SyncExpectation` and `expect -> AsyncExpectation`.
public func expecta<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @autoclosure @escaping @Sendable () async throws -> T?) async -> AsyncExpectation<T> {
public func expecta<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @autoclosure @escaping @Sendable () async throws -> sending T?) async -> AsyncExpectation<T> {
return AsyncExpectation(
expression: AsyncExpression(
expression: expression,
Expand All @@ -50,7 +50,7 @@ public func expecta<T: Sendable>(fileID: String = #fileID, file: FileString = #f

/// Make an ``AsyncExpectation`` on a given actual value. The closure is lazily invoked.
/// This is provided to avoid confusion between `expect -> SyncExpectation` and `expect -> AsyncExpectation`
public func expecta<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @autoclosure @Sendable () -> (@Sendable () async throws -> T)) async -> AsyncExpectation<T> {
public func expecta<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @autoclosure @Sendable () -> (@Sendable () async throws -> sending T)) async -> AsyncExpectation<T> {
return AsyncExpectation(
expression: AsyncExpression(
expression: expression(),
Expand All @@ -60,7 +60,7 @@ public func expecta<T: Sendable>(fileID: String = #fileID, file: FileString = #f

/// Make an ``AsyncExpectation`` on a given actual value. The closure is lazily invoked.
/// This is provided to avoid confusion between `expect -> SyncExpectation` and `expect -> AsyncExpectation`
public func expecta<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @autoclosure @Sendable () -> (@Sendable () async throws -> T?)) async -> AsyncExpectation<T> {
public func expecta<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @autoclosure @Sendable () -> (@Sendable () async throws -> sending T?)) async -> AsyncExpectation<T> {
return AsyncExpectation(
expression: AsyncExpression(
expression: expression(),
Expand All @@ -70,7 +70,7 @@ public func expecta<T: Sendable>(fileID: String = #fileID, file: FileString = #f

/// Make an ``AsyncExpectation`` on a given actual value. The closure is lazily invoked.
/// This is provided to avoid confusion between `expect -> SyncExpectation` and `expect -> AsyncExpectation`
public func expecta(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @autoclosure @Sendable () -> (@Sendable () async throws -> Void)) async -> AsyncExpectation<Void> {
public func expecta(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @autoclosure @Sendable () -> (@Sendable () async throws -> sending Void)) async -> AsyncExpectation<Void> {
return AsyncExpectation(
expression: AsyncExpression(
expression: expression(),
Expand Down
16 changes: 8 additions & 8 deletions Sources/Nimble/DSL+Require.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public func requires(fileID: String = #fileID, file: FileString = #filePath, lin
/// `require` will return the result of the expression if the matcher passes, and throw an error if not.
/// if a `customError` is given, then that will be thrown. Otherwise, a ``RequireError`` will be thrown.
@discardableResult
public func require<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, _ expression: @escaping () async throws -> T?) -> AsyncRequirement<T> {
public func require<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, _ expression: @escaping @Sendable () async throws -> sending T?) -> AsyncRequirement<T> {
return AsyncRequirement(
expression: AsyncExpression(
expression: expression,
Expand All @@ -137,7 +137,7 @@ public func require<T: Sendable>(fileID: String = #fileID, file: FileString = #f
/// `require` will return the result of the expression if the matcher passes, and throw an error if not.
/// if a `customError` is given, then that will be thrown. Otherwise, a ``RequireError`` will be thrown.
@discardableResult
public func require<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, _ expression: () -> (() async throws -> T)) -> AsyncRequirement<T> {
public func require<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, _ expression: () -> (@Sendable () async throws -> sending T)) -> AsyncRequirement<T> {
return AsyncRequirement(
expression: AsyncExpression(
expression: expression(),
Expand All @@ -151,7 +151,7 @@ public func require<T: Sendable>(fileID: String = #fileID, file: FileString = #f
/// `require` will return the result of the expression if the matcher passes, and throw an error if not.
/// if a `customError` is given, then that will be thrown. Otherwise, a ``RequireError`` will be thrown.
@discardableResult
public func require<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, _ expression: () -> (() async throws -> T?)) -> AsyncRequirement<T> {
public func require<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, _ expression: () -> (@Sendable () async throws -> sending T?)) -> AsyncRequirement<T> {
return AsyncRequirement(
expression: AsyncExpression(
expression: expression(),
Expand All @@ -167,7 +167,7 @@ public func require<T: Sendable>(fileID: String = #fileID, file: FileString = #f
///
/// This is provided to avoid confusion between `require -> SyncRequirement` and `require -> AsyncRequirement`.
@discardableResult
public func requirea<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, _ expression: @autoclosure @escaping () async throws -> T?) async -> AsyncRequirement<T> {
public func requirea<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, _ expression: @autoclosure @escaping @Sendable () async throws -> sending T?) async -> AsyncRequirement<T> {
return AsyncRequirement(
expression: AsyncExpression(
expression: expression,
Expand All @@ -183,7 +183,7 @@ public func requirea<T: Sendable>(fileID: String = #fileID, file: FileString = #
///
/// This is provided to avoid confusion between `require -> SyncRequirement` and `require -> AsyncRequirement`
@discardableResult
public func requirea<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, _ expression: @autoclosure () -> (() async throws -> T)) async -> AsyncRequirement<T> {
public func requirea<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, _ expression: @autoclosure () -> (@Sendable () async throws -> sending T)) async -> AsyncRequirement<T> {
return AsyncRequirement(
expression: AsyncExpression(
expression: expression(),
Expand All @@ -199,7 +199,7 @@ public func requirea<T: Sendable>(fileID: String = #fileID, file: FileString = #
///
/// This is provided to avoid confusion between `require -> SyncRequirement` and `require -> AsyncRequirement`
@discardableResult
public func requirea<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, _ expression: @autoclosure () -> (() async throws -> T?)) async -> AsyncRequirement<T> {
public func requirea<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, _ expression: @autoclosure () -> (@Sendable () async throws -> sending T?)) async -> AsyncRequirement<T> {
return AsyncRequirement(
expression: AsyncExpression(
expression: expression(),
Expand Down Expand Up @@ -266,7 +266,7 @@ public func unwrap<T: Sendable>(fileID: String = #fileID, file: FileString = #fi
/// `unwrap` will return the result of the expression if it is non-nil, and throw an error if the value is nil.
/// if a `customError` is given, then that will be thrown. Otherwise, a ``RequireError`` will be thrown.
@discardableResult
public func unwrap<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, description: String? = nil, _ expression: () -> (() async throws -> T?)) async throws -> T {
public func unwrap<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, description: String? = nil, _ expression: () -> (@Sendable () async throws -> sending T?)) async throws -> T {
try await requirea(fileID: fileID, file: file, line: line, column: column, customError: customError, expression()).toNot(beNil(), description: description)
}

Expand All @@ -286,7 +286,7 @@ public func unwrapa<T: Sendable>(fileID: String = #fileID, file: FileString = #f
/// `unwrapa` will return the result of the expression if it is non-nil, and throw an error if the value is nil.
/// if a `customError` is given, then that will be thrown. Otherwise, a ``RequireError`` will be thrown.
@discardableResult
public func unwrapa<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, description: String? = nil, _ expression: @autoclosure () -> (() async throws -> T?)) async throws -> T {
public func unwrapa<T: Sendable>(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, customError: Error? = nil, description: String? = nil, _ expression: @autoclosure () -> (@Sendable () async throws -> sending T?)) async throws -> T {
try await requirea(fileID: fileID, file: file, line: line, column: column, customError: customError, expression()).toNot(beNil(), description: description)
}

Expand Down
5 changes: 4 additions & 1 deletion Sources/Nimble/DSL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ public func expects<T>(fileID: String = #fileID, file: FileString = #filePath, l

/// Make a ``SyncExpectation`` on a given actual value. The closure is lazily invoked.
/// This is provided as an alternative to `expect` which avoids overloading with `expect -> AsyncExpectation`.
public func expects(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @autoclosure () -> (@Sendable () throws -> Void)) -> SyncExpectation<Void> {
public func expects(fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column, _ expression: @autoclosure () -> (@Sendable () throws -> sending Void)) -> SyncExpectation<Void> {
// It would seem like `sending` isn't necessary for the `expression` argument
// because the closure returns void. However, this gets rid of a type
// conversion warning/error.
return SyncExpectation(
expression: Expression(
expression: expression(),
Expand Down
4 changes: 2 additions & 2 deletions Sources/Nimble/Polling+Require.swift
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ public func pollUnwrap<T>(file: FileString = #file, line: UInt = #line, _ expres
/// Makes sure that the expression evaluates to a non-nil value, otherwise throw an error.
/// As you can tell, this is a much less verbose equivalent to `require(expression).toEventuallyNot(beNil())`
@discardableResult
public func pollUnwrap<T>(file: FileString = #file, line: UInt = #line, timeout: NimbleTimeInterval = PollingDefaults.timeout, pollInterval: NimbleTimeInterval = PollingDefaults.pollInterval, description: String? = nil, _ expression: @autoclosure () -> (@Sendable () throws -> T?)) throws -> T {
public func pollUnwrap<T>(file: FileString = #file, line: UInt = #line, timeout: NimbleTimeInterval = PollingDefaults.timeout, pollInterval: NimbleTimeInterval = PollingDefaults.pollInterval, description: String? = nil, _ expression: @autoclosure () -> (@Sendable () throws -> sending T?)) throws -> T {
try require(file: file, line: line, expression()).toEventuallyNot(beNil(), timeout: timeout, pollInterval: pollInterval, description: description)
}

Expand All @@ -729,7 +729,7 @@ public func pollUnwraps<T>(file: FileString = #file, line: UInt = #line, timeout
/// Makes sure that the expression evaluates to a non-nil value, otherwise throw an error.
/// As you can tell, this is a much less verbose equivalent to `require(expression).toEventuallyNot(beNil())`
@discardableResult
public func pollUnwraps<T>(file: FileString = #file, line: UInt = #line, timeout: NimbleTimeInterval = PollingDefaults.timeout, pollInterval: NimbleTimeInterval = PollingDefaults.pollInterval, description: String? = nil, _ expression: @autoclosure () -> (@Sendable () throws -> T?)) throws -> T {
public func pollUnwraps<T>(file: FileString = #file, line: UInt = #line, timeout: NimbleTimeInterval = PollingDefaults.timeout, pollInterval: NimbleTimeInterval = PollingDefaults.pollInterval, description: String? = nil, _ expression: @autoclosure () -> (@Sendable () throws -> sending T?)) throws -> T {
try require(file: file, line: line, expression()).toEventuallyNot(beNil(), timeout: timeout, pollInterval: pollInterval, description: description)
}

Expand Down
4 changes: 2 additions & 2 deletions Tests/NimbleTests/Matchers/BeIdenticalToTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ final class BeIdenticalToTest: XCTestCase {
}

func testBeIdenticalToNegativeMessage() {
let value1 = NSArray()
let value1 = 1 as NSNumber
let value2 = value1
let message = "expected to not be identical to \(identityAsString(value2)), got \(identityAsString(value1))"
failsWithErrorMessage(message) {
Expand All @@ -46,7 +46,7 @@ final class BeIdenticalToTest: XCTestCase {
expect(1 as NSNumber).toNot(be("turtles" as NSString))
expect([1 as NSNumber] as NSArray).toNot(be([1 as NSNumber] as NSArray))

let value1 = NSArray()
let value1 = 1 as NSNumber
let value2 = value1
let message = "expected to not be identical to \(identityAsString(value1)), got \(identityAsString(value2))"
failsWithErrorMessage(message) {
Expand Down
Loading

0 comments on commit 7886e7d

Please sign in to comment.