Brightify / Cuckoo

Boilerplate-free mocking framework for Swift!
MIT License
1.67k stars 172 forks source link

Protocol with primary associated type cannot be mocked #491

Closed aaronbarsky closed 4 months ago

aaronbarsky commented 4 months ago

Using 2.0.1 I am trying to mock the following file.

import Combine
import Foundation
protocol SubscriptionServiceType<Output> {
    associatedtype Output: Equatable
    func connect() -> AnyPublisher<Output, Error>
}

1.10 produces the valid mock

class MockSubscriptionServiceType<Output: Equatable>: SubscriptionServiceType, Cuckoo.ProtocolMock {
     typealias MocksType = DefaultImplCaller<Output>
     typealias Stubbing = __StubbingProxy_SubscriptionServiceType
     typealias Verification = __VerificationProxy_SubscriptionServiceType

     let cuckoo_manager = Cuckoo.MockManager.preconfiguredManager ?? Cuckoo.MockManager(hasParent: false)

     class DefaultImplCaller<Output: Equatable>: SubscriptionServiceType {
        private let reference: Any

2.0.1 produces invalid code

class MockSubscriptionServiceType<Output, Output: Equatable>: SubscriptionServiceType, Cuckoo.ProtocolMock {
    typealias MocksType = DefaultImplCaller<Output, Output>
    typealias Stubbing = __StubbingProxy_SubscriptionServiceType
    typealias Verification = __VerificationProxy_SubscriptionServiceType

    let cuckoo_manager = Cuckoo.MockManager.preconfiguredManager ?? Cuckoo.MockManager(hasParent: false)

    class DefaultImplCaller<Output, Output: Equatable>: SubscriptionServiceType {
        private let reference: Any

Note the 1.10.0 code has a Swift 6 warning

Generic parameter 'Output' shadows generic parameter from outer scope with the same name; this is an error in Swift 6

but for now it is functional.

The 2.0.1 code with Output, Output:Equatable does not compile

MatyasKriz commented 4 months ago

Thanks for reporting this and providing the source as well as generated code for both versions. The fix itself shouldn't be difficult, but I'll see what I can do about the Swift 6 warning as well.

MatyasKriz commented 4 months ago

I've added your test sample to the unit tests, so this error shouldn't occur again. 🙂 Please try out 2.0.2 to see if it's fixed your issue completely.

Furthermore this issue made me prod the DefaultImplCaller altogether and find out it actually (probably, according to the unit tests) doesn't require the generic parameters as it's already got them available through the class it resides in.

aaronbarsky commented 4 months ago

Brilliant. Compiles without warnings and my unit tests pass. Thanks for the quick turnaround.

MatyasKriz commented 4 months ago

Glad to hear that. 🙂 Closing issue then.