Sourcery icon indicating copy to clipboard operation
Sourcery copied to clipboard

[Bug][AutoMockable] Compilation errors for methods having closure parameters with more than a single parameter.

Open rokridi opened this issue 6 months ago • 0 comments

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 %}

rokridi avatar Aug 08 '24 13:08 rokridi