Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to point at correct @escaping @Sendable stub? #533

Open
chaseklingelzen opened this issue Jan 9, 2025 · 1 comment
Open

How to point at correct @escaping @Sendable stub? #533

chaseklingelzen opened this issue Jan 9, 2025 · 1 comment

Comments

@chaseklingelzen
Copy link

chaseklingelzen commented Jan 9, 2025

Hi,

We have the following protocol:

public protocol NetworkMonitorProvider {
    ...
    func observeNetworkStatus(_ handler: @escaping @Sendable (_ newPath: NetworkStatusProvider) -> Void)
    ...
}

extension NWPathMonitor: NetworkMonitorProvider {
    public func observeNetworkStatus(
        _ handler: @escaping @Sendable (_ newPath: NetworkStatusProvider) -> Void
    ) {
        pathUpdateHandler = { path in
            handler(path)
        }
    }
}

Our generated mock creates the following (note the difference where one actually creates @escaping @sendable and the other does not):

public class NetworkMonitorProviderStub:NetworkMonitorProvider, @unchecked Sendable {
    
    public var path: NetworkStatusProvider {
        get {
            return DefaultValueRegistry.defaultValue(for: (NetworkStatusProvider).self)
        }
    }


    
    public func observeNetworkStatus(_ p0: @escaping @Sendable (_ newPath: NetworkStatusProvider) -> Void) {
        return DefaultValueRegistry.defaultValue(for: (Void).self)
    }
    
    public func start(queue p0: DispatchQueue) {
        return DefaultValueRegistry.defaultValue(for: (Void).self)
    }
    
    public func cancel() {
        return DefaultValueRegistry.defaultValue(for: (Void).self)
    }
}

func observeNetworkStatus<M1: Cuckoo.Matchable>(_ p0: M1) -> Cuckoo.ProtocolStubNoReturnFunction<( (_ newPath: NetworkStatusProvider) -> Void)> where M1.MatchedType ==  (_ newPath: NetworkStatusProvider) -> Void {
            let matchers: [Cuckoo.ParameterMatcher<( (_ newPath: NetworkStatusProvider) -> Void)>] = [wrap(matchable: p0) { $0 }]
            return .init(stub: cuckoo_manager.createStub(for: MockNetworkMonitorProvider.self,
                method: "observeNetworkStatus(_ p0: @escaping @Sendable (_ newPath: NetworkStatusProvider) -> Void)",
                parameterMatchers: matchers
            ))
        }

Our unit test is set up like so:

stub(monitor) { stub in
      stub.observeNetworkStatus(any()).thenDoNothing()
}

The issue is the stub is not pointing at this func:

 public func observeNetworkStatus(_ p0: @escaping @Sendable (_ newPath: NetworkStatusProvider) -> Void) {
        return DefaultValueRegistry.defaultValue(for: (Void).self)
    }

It is pointing at this func:

func observeNetworkStatus<M1: Cuckoo.Matchable>(_ p0: M1) -> Cuckoo.ProtocolStubNoReturnFunction<( (_ newPath: NetworkStatusProvider) -> Void)> where M1.MatchedType ==  (_ newPath: NetworkStatusProvider) -> Void {
            let matchers: [Cuckoo.ParameterMatcher<( (_ newPath: NetworkStatusProvider) -> Void)>] = [wrap(matchable: p0) { $0 }]
            return .init(stub: cuckoo_manager.createStub(for: MockNetworkMonitorProvider.self,
                method: "observeNetworkStatus(_ p0: @escaping @Sendable (_ newPath: NetworkStatusProvider) -> Void)",
                parameterMatchers: matchers
            ))
        }

I'm aware we have anyClosure as option for argument (see below). This doesn't work.

stub(monitor) { stub in
      stub.observeNetworkStatus(anyClosure()).thenDoNothing()
}

My question is how do we make the stub point at the @escaping @sendable version of the stubbed func?

@MatyasKriz
Copy link
Collaborator

Hey, @chaseklingelzen, I'm actually not sure regarding these new @Sendable closures. I haven't found the time yet to implement all the new Swift 6 features, so we're missing some tests as well.

I wonder if you could define your own anySendableClosure matcher which would help Swift target the method you want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants