Sourcery
Sourcery copied to clipboard
[Bug][AutoMockable] Compilation errors for methods having closure parameters with more than a single parameter.
Hello 👋
The current AutoMockable.stencil
does not properly handle methods methods having closure parameters with more than a single parameter.
Example:
// sourcery: AutoMockable
protocol MyProtocol {
func foo(closureA: @escaping (String, Int) -> Void)
}
The generated mock looks like this:
class MyProtocolMock: MyProtocol {
//MARK: - foo
var fooClosureAEscapingStringIntVoidVoidCallsCount = 0
var fooClosureAEscapingStringIntVoidVoidCalled: Bool {
return fooClosureAEscapingStringIntVoidVoidCallsCount > 0
}
var fooClosureAEscapingStringIntVoidVoidReceivedClosureA: (((String, Int) -> Void))?
var fooClosureAEscapingStringIntVoidVoidReceivedInvocations: [(((String, Int) -> Void))] = []
var fooClosureAEscapingStringIntVoidVoidClosure: ((@escaping (String, Int) -> Void) -> Void)?
func foo(closureA: (@escaping (String, Int) -> Void) // <-- there is a missing closing parenthese {
fooClosureAEscapingStringIntVoidVoidCallsCount += 1
fooClosureAEscapingStringIntVoidVoidReceivedClosureA = closureA
fooClosureAEscapingStringIntVoidVoidReceivedInvocations.append(closureA)
fooClosureAEscapingStringIntVoidVoidClosure?(closureA)
}
}
The solution would be to replace this line with this:
{% macro methodName method %}func {{ method.shortName}}({%- for param in method.parameters %}{% if param.argumentLabel == nil %}_ {% if not param.name == "" %}{{ param.name }}{% else %}arg{{ param.index }}{% endif %}{%elif param.argumentLabel == param.name%}{{ param.name }}{%else%}{{ param.argumentLabel }} {{ param.name }}{% endif %}: {% if param.typeName.isClosure and param.typeName.closure.parameters.count > 1 %}({% endif %}{% call existentialParameterTypeName param.typeName param.isVariadic %}{% if param.typeName.isClosure and param.typeName.closure.parameters.count > 1 %}){% endif %}{% if not forloop.last %}, {% endif %}{% endfor -%}){% endmacro %}