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

Mocks with protocols restricted to a explicit class #376

Open
geraldeersteling opened this issue Jan 5, 2021 · 3 comments
Open

Mocks with protocols restricted to a explicit class #376

geraldeersteling opened this issue Jan 5, 2021 · 3 comments
Labels
help wanted This issue is asking for a way to solve a problem.

Comments

@geraldeersteling
Copy link

Hello,

I'm fairly new with Cuckoo and got everything up and running. I do encounter an issue and I'm unable to find a solution in the issues here on GitHub (or I'm not searching for it the right way...).

Take this protocol for example:

protocol Slide: UIVIew {
    var delegate: SlideDelegate? { get set }
}

Now when I run Cuckoo this gave me the following generated code:

Generated code
 class MockSlideDelegate: SlideDelegate, Cuckoo.ProtocolMock {
    
     typealias MocksType = SlideDelegate
    
     typealias Stubbing = __StubbingProxy_SlideDelegate
     typealias Verification = __VerificationProxy_SlideDelegate

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

    
    private var __defaultImplStub: SlideDelegate?

     func enableDefaultImplementation(_ stub: SlideDelegate) {
        __defaultImplStub = stub
        cuckoo_manager.enableDefaultStubImplementation()
    }
    

    

    

    
    
    
     func nextPressed(forSlide: Slide)  {
        
    return cuckoo_manager.call("nextPressed(forSlide: Slide)",
            parameters: (forSlide),
            escapingParameters: (forSlide),
            superclassCall:
                
                Cuckoo.MockManager.crashOnProtocolSuperclassCall()
                ,
            defaultCall: __defaultImplStub!.nextPressed(forSlide: forSlide))
        
    }
    
    
    
     func previousPressed(forSlide: Slide)  {
        
    return cuckoo_manager.call("previousPressed(forSlide: Slide)",
            parameters: (forSlide),
            escapingParameters: (forSlide),
            superclassCall:
                
                Cuckoo.MockManager.crashOnProtocolSuperclassCall()
                ,
            defaultCall: __defaultImplStub!.previousPressed(forSlide: forSlide))
        
    }
    

	 struct __StubbingProxy_SlideDelegate: Cuckoo.StubbingProxy {
	    private let cuckoo_manager: Cuckoo.MockManager
	
	     init(manager: Cuckoo.MockManager) {
	        self.cuckoo_manager = manager
	    }
	    
	    
	    func nextPressed<M1: Cuckoo.Matchable>(forSlide: M1) -> Cuckoo.ProtocolStubNoReturnFunction<(Slide)> where M1.MatchedType == Slide {
	        let matchers: [Cuckoo.ParameterMatcher<(Slide)>] = [wrap(matchable: forSlide) { $0 }]
	        return .init(stub: cuckoo_manager.createStub(for: MockSlideDelegate.self, method: "nextPressed(forSlide: Slide)", parameterMatchers: matchers))
	    }
	    
	    func previousPressed<M1: Cuckoo.Matchable>(forSlide: M1) -> Cuckoo.ProtocolStubNoReturnFunction<(Slide)> where M1.MatchedType == Slide {
	        let matchers: [Cuckoo.ParameterMatcher<(Slide)>] = [wrap(matchable: forSlide) { $0 }]
	        return .init(stub: cuckoo_manager.createStub(for: MockSlideDelegate.self, method: "previousPressed(forSlide: Slide)", parameterMatchers: matchers))
	    }
	    
	}

	 struct __VerificationProxy_SlideDelegate: Cuckoo.VerificationProxy {
	    private let cuckoo_manager: Cuckoo.MockManager
	    private let callMatcher: Cuckoo.CallMatcher
	    private let sourceLocation: Cuckoo.SourceLocation
	
	     init(manager: Cuckoo.MockManager, callMatcher: Cuckoo.CallMatcher, sourceLocation: Cuckoo.SourceLocation) {
	        self.cuckoo_manager = manager
	        self.callMatcher = callMatcher
	        self.sourceLocation = sourceLocation
	    }
	
	    
	
	    
	    @discardableResult
	    func nextPressed<M1: Cuckoo.Matchable>(forSlide: M1) -> Cuckoo.__DoNotUse<(Slide), Void> where M1.MatchedType == Slide {
	        let matchers: [Cuckoo.ParameterMatcher<(Slide)>] = [wrap(matchable: forSlide) { $0 }]
	        return cuckoo_manager.verify("nextPressed(forSlide: Slide)", callMatcher: callMatcher, parameterMatchers: matchers, sourceLocation: sourceLocation)
	    }
	    
	    @discardableResult
	    func previousPressed<M1: Cuckoo.Matchable>(forSlide: M1) -> Cuckoo.__DoNotUse<(Slide), Void> where M1.MatchedType == Slide {
	        let matchers: [Cuckoo.ParameterMatcher<(Slide)>] = [wrap(matchable: forSlide) { $0 }]
	        return cuckoo_manager.verify("previousPressed(forSlide: Slide)", callMatcher: callMatcher, parameterMatchers: matchers, sourceLocation: sourceLocation)
	    }
	    
	}
}

 class SlideDelegateStub: SlideDelegate {
    

    

    
     func nextPressed(forSlide: Slide)   {
        return DefaultValueRegistry.defaultValue(for: (Void).self)
    }
    
     func previousPressed(forSlide: Slide)   {
        return DefaultValueRegistry.defaultValue(for: (Void).self)
    }
    
}



 class MockSlide: Slide, Cuckoo.ProtocolMock {
    
     typealias MocksType = Slide
    
     typealias Stubbing = __StubbingProxy_Slide
     typealias Verification = __VerificationProxy_Slide

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

    
    private var __defaultImplStub: Slide?

     func enableDefaultImplementation(_ stub: Slide) {
        __defaultImplStub = stub
        cuckoo_manager.enableDefaultStubImplementation()
    }
    

    
    
    
     var delegate: SlideDelegate? {
        get {
            return cuckoo_manager.getter("delegate",
                superclassCall:
                    
                    Cuckoo.MockManager.crashOnProtocolSuperclassCall()
                    ,
                defaultCall: __defaultImplStub!.delegate)
        }
        
        set {
            cuckoo_manager.setter("delegate",
                value: newValue,
                superclassCall:
                    
                    Cuckoo.MockManager.crashOnProtocolSuperclassCall()
                    ,
                defaultCall: __defaultImplStub!.delegate = newValue)
        }
        
    }
    

    

    

	 struct __StubbingProxy_Slide: Cuckoo.StubbingProxy {
	    private let cuckoo_manager: Cuckoo.MockManager
	
	     init(manager: Cuckoo.MockManager) {
	        self.cuckoo_manager = manager
	    }
	    
	    
	    var delegate: Cuckoo.ProtocolToBeStubbedOptionalProperty<MockSlide, SlideDelegate> {
	        return .init(manager: cuckoo_manager, name: "delegate")
	    }
	    
	    
	}

	 struct __VerificationProxy_Slide: Cuckoo.VerificationProxy {
	    private let cuckoo_manager: Cuckoo.MockManager
	    private let callMatcher: Cuckoo.CallMatcher
	    private let sourceLocation: Cuckoo.SourceLocation
	
	     init(manager: Cuckoo.MockManager, callMatcher: Cuckoo.CallMatcher, sourceLocation: Cuckoo.SourceLocation) {
	        self.cuckoo_manager = manager
	        self.callMatcher = callMatcher
	        self.sourceLocation = sourceLocation
	    }
	
	    
	    
	    var delegate: Cuckoo.VerifyOptionalProperty<SlideDelegate> {
	        return .init(manager: cuckoo_manager, name: "delegate", callMatcher: callMatcher, sourceLocation: sourceLocation)
	    }
	    
	
	    
	}
}

 class SlideStub: Slide {
    
    
     var delegate: SlideDelegate? {
        get {
            return DefaultValueRegistry.defaultValue(for: (SlideDelegate?).self)
        }
        
        set { }
        
    }
    

    

    
}

However the generated mocks are no UIView's rather just classes which conform to the Slide protocol. Subsequently giving me the following errors while compiling:

  • Slide requires that MockSlide inherit from `UIView
  • Slide requires that SlideStub inherit from `UIView

How can I fix this, or is this 'just how things work'?

@MatyasKriz MatyasKriz added the help wanted This issue is asking for a way to solve a problem. label Jan 11, 2021
@MatyasKriz
Copy link
Collaborator

Hi, @geraldeersteling. Cuckoo needs the source code to parse it and find out which methods are declared, which it can't do from just the type unfortunately. The OCMock integration in Cuckoo might help with this, take a look at the tests and try it out.

@bspinner
Copy link

bspinner commented Jul 7, 2021

This is as well a problem with opensource classes/protocols:

public class ClassExample {
    @Published private(set) public var greetings: String = "Hello, World!"
}

public protocol ProtocolExample: ClassExample {
}

public class Example: ClassExample, ProtocolExample {

}

will generate

//
// ERROR: 'ProtocolExample' requires that 'MockProtocolExample' inherit from 'ClassExample'
//
public class MockProtocolExample: ProtocolExample, Cuckoo.ProtocolMock { 
// ...
    public var greetings: String {
        get {
            return cuckoo_manager.getter("greetings",
                superclassCall:
                    
                    Cuckoo.MockManager.crashOnProtocolSuperclassCall()
                    ,
                defaultCall: __defaultImplStub!.greetings)
        }
        
    }

// ...

	public struct __StubbingProxy_ProtocolExample: Cuckoo.StubbingProxy {
	    private let cuckoo_manager: Cuckoo.MockManager
	
	    public init(manager: Cuckoo.MockManager) {
	        self.cuckoo_manager = manager
	    }
	    
	    //
	    // ERROR: Type 'MockProtocolExample' does not conform to protocol 'ClassMock'
	    //
	    var greetings: Cuckoo.ClassToBeStubbedReadOnlyProperty<MockProtocolExample, String> {
	        return .init(manager: cuckoo_manager, name: "greetings")
	    }
	    
	    
	}
}

(see two errors in code comments)

@MatyasKriz
Copy link
Collaborator

@bspinner does the example work without the @Published?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted This issue is asking for a way to solve a problem.
Projects
None yet
Development

No branches or pull requests

3 participants