Skip to content

[Feature] Add support for non-escaping closures #129

@bfahey

Description

@bfahey

Use Case

Add support for non-escaping closures

Feature Proposal

I would like @Mocked to support non-escaping closures out of the box.

@Mocked
final class ExampleProtocol {
    func perform(action: @Sendable () -> Void)
}

@MockedMembers
final class ExampleProtocolMock {
    func perform(action: @Sendable () -> Void)
}

/// An implementation for `ExampleProtocol._perform`.
enum PerformImplementation<
	Arguments
>: @unchecked Sendable, MockVoidParameterizedMethodImplementation {

    /// The implementation's closure type.
    typealias Closure = (@Sendable () -> Void) -> Void

    /// Does nothing when invoked.
    case unimplemented

    /// Invokes the provided closure when invoked.
    ///
    /// - Parameter closure: The closure to invoke.
    case uncheckedInvokes(_ closure: Closure)

    /// Invokes the provided closure when invoked.
    ///
    /// - Parameter closure: The closure to invoke.
    static func invokes(
    	_ closure: @Sendable @escaping (@Sendable () -> Void) -> Void // <-- here's where the @escaping keyword gets added
    ) -> Self where Arguments: Sendable {
        .uncheckedInvokes(closure)
    }

    /// The implementation as a closure, or `nil` if unimplemented.
    var _closure: Closure? {
        switch self {
        case .unimplemented:
            nil
        case let .uncheckedInvokes(closure):
            closure
        }
    }
}

private let __perform = MockVoidParameterizedMethod<
	PerformImplementation<
		(() -> Void)
	>
>.makeMethod()

var _perform: MockVoidParameterizedMethod<
	PerformImplementation<
		(() -> Void)
	>
> {
    self.__perform.method
}

Alternatives Considered

Manually building mocks with @MockedMembers and excluding the function with the non-escaping closure.

Additional Context

I believe this could be accomplished with withoutActuallyEscaping(_:do:).

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions