MakeAWishFoundation/SwiftyMocky

Incorrect mock generation with @MainActor in closure of async method

Opened this issue · 2 comments

Hi!

We use async functions for network operations and then pass the result with closure blocks up to our ViewControllers. It’s very convenient to declare @mainactor directly in closure to switch to the main queue:

func signUp(login: String, completion: @MainActor @escaping (Result<Void, Error>) -> Void) { 

}

Anyway, in our Mock.generated we got this:

fileprivate enum MethodType {
        case m_signUp__login_logincompletion_completion(Parameter<String>, Parameter<(Result<Void, Error>) -> Void>)
}

open func signUp(login: String, completion: @MainActor @escaping (Result<Void, Error>) -> Void) {

        addInvocation(.m_signUp__login_logincompletion_completion(Parameter<String>.value(`login`), 
        			  Parameter<(Result<Void, Error>) -> Void>.value(`completion`)))

	let perform = methodPerformValue(.m_signUp__login_logincompletion_completion(Parameter<String>.value(`login`), 
								     Parameter<(Result<Void, Error>) -> Void>.value(`completion`))) as? (String, @MainActor @escaping (Result<Void, Error>) -> Void) -> Void
		
	perform?(`login`, `completion`)
}

With 2 compiler errors when adding .value(completion):

`Converting function value of type '@MainActor (Result<Void, Error>) -> Void' to '(Result<Void, Error>) -> Void' loses global actor 'MainActor'`

I’ve been looking through issues (i.e. #290, #304) but mine looks new.

It seems to be an easy fix in some way. We either need to add @mainactor to MethodType or just ignore it while parsing (looks like it’s not that necessary to mock it at all).

seems like that was fixed in the latest release 4.2.0

@muratdi could you please check this according to the comment from @mltbnz?