From c16a20955ea7dcdf3f617c961997c1d4d8aa8075 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 10 Aug 2023 11:18:55 +0200 Subject: [PATCH] Add support to any keyword for function return type to AutoMockable.stencil (#1186) * Add support to any keyword for function return type to AutoMockable.stencil * Update changelog * Fix tests --- CHANGELOG.md | 2 + Templates/Templates/AutoMockable.stencil | 8 +- Templates/Tests/Context/AutoMockable.swift | 10 + .../Tests/Expected/AutoMockable.expected | 182 +++++++++++++++++- .../Generated/AutoMockable.generated.swift | 182 +++++++++++++++++- 5 files changed, 378 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eef07fa86..5af7a72e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## 2.1.0 ## Changes - Added support for Swift Package Manager config ([#1184](https://github.com/krzysztofzablocki/Sourcery/pull/1184)) +- Add support to any keyword for function parameter type to AutoMockable.stencil ([#1169](https://github.com/krzysztofzablocki/Sourcery/pull/1169)) +- Add support to any keyword for function return type to AutoMockable.stencil([#1186](https://github.com/krzysztofzablocki/Sourcery/pull/1186)) ## 2.0.3 ## Internal Changes diff --git a/Templates/Templates/AutoMockable.stencil b/Templates/Templates/AutoMockable.stencil index 6b250b4e1..b795c4b15 100755 --- a/Templates/Templates/AutoMockable.stencil +++ b/Templates/Templates/AutoMockable.stencil @@ -54,7 +54,7 @@ import {{ import }} {% macro closureReturnTypeName method %}{% if method.isOptionalReturnType %}{{ method.unwrappedReturnTypeName }}?{% else %}{{ method.returnTypeName }}{% endif %}{% endmacro %} {% macro methodClosureDeclaration method %} - {% call accessLevel method.accessLevel %}{% call staticSpecifier method %}var {% call methodClosureName method %}: (({% for param in method.parameters %}{% call existentialClosureVariableTypeName param.typeName %}{% if not forloop.last %}, {% endif %}{% endfor %}) {% if method.isAsync %}async {% endif %}{% if method.throws %}throws {% endif %}-> {% if method.isInitializer %}Void{% else %}{% call closureReturnTypeName method %}{% endif %})? + {% call accessLevel method.accessLevel %}{% call staticSpecifier method %}var {% call methodClosureName method %}: (({% for param in method.parameters %}{% call existentialClosureVariableTypeName param.typeName %}{% if not forloop.last %}, {% endif %}{% endfor %}) {% if method.isAsync %}async {% endif %}{% if method.throws %}throws {% endif %}-> {% if method.isInitializer %}Void{% else %}{% call existentialVariableTypeName method.returnTypeName %}{% endif %})? {% endmacro %} {% macro methodClosureCallParameters method %}{% for param in method.parameters %}{{ param.name }}{% if not forloop.last %}, {% endif %}{% endfor %}{% endmacro %} @@ -84,7 +84,7 @@ import {{ import }} {% call accessLevel method.accessLevel %}{% call staticSpecifier method %}var {% call swiftifyMethodName method.selectorName %}ReceivedInvocations: [({% for param in method.parameters %}{{ param.name }}: {% if param.typeAttributes.escaping %}{% call existentialClosureVariableTypeName param.typeName.unwrappedTypeName %}{% else %}{% call existentialClosureVariableTypeName param.typeName %}{% endif %}{{ ', ' if not forloop.last }}{% endfor %})] = [] {% endif %} {% if not method.returnTypeName.isVoid and not method.isInitializer %} - {% call accessLevel method.accessLevel %}{% call staticSpecifier method %}var {% call swiftifyMethodName method.selectorName %}ReturnValue: {{ '(' if method.returnTypeName.isClosure and not method.isOptionalReturnType }}{{ method.returnTypeName }}{{ ')' if method.returnTypeName.isClosure and not method.isOptionalReturnType }}{{ '!' if not method.isOptionalReturnType }} + {% call accessLevel method.accessLevel %}{% call staticSpecifier method %}var {% call swiftifyMethodName method.selectorName %}ReturnValue: {{ '(' if method.returnTypeName.isClosure and not method.isOptionalReturnType or method.returnTypeName|contains:"any "}}{% call existentialVariableTypeName method.returnTypeName %}{{ ')' if method.returnTypeName.isClosure and not method.isOptionalReturnType or method.returnTypeName|contains:"any " }}{{ '!' if not method.isOptionalReturnType }} {% endif %} {% call methodClosureDeclaration method %} @@ -99,7 +99,7 @@ import {{ import }} {{ value }} {% endfor %} {% endfor %} - {% call accessLevel method.accessLevel %}{% call staticSpecifier method %}{% call methodName method %}{{ ' async' if method.isAsync }}{{ ' throws' if method.throws }}{% if not method.returnTypeName.isVoid %} -> {{ method.returnTypeName }}{% endif %} { + {% call accessLevel method.accessLevel %}{% call staticSpecifier method %}{% call methodName method %}{{ ' async' if method.isAsync }}{{ ' throws' if method.throws }}{% if not method.returnTypeName.isVoid %} -> {% call existentialVariableTypeName method.returnTypeName %}{% endif %} { {% if method.throws %} {% call methodThrowableErrorUsage method %} {% endif %} @@ -202,7 +202,7 @@ import {{ import }} {% macro underlyingMockedVariableName variable %}underlying{{ variable.name|upperFirstLetter }}{% endmacro %} {% macro mockedVariableName variable %}{{ variable.name }}{% endmacro %} -{% macro existentialVariableTypeName typeName %}{% if typeName|contains:"any" and typeName|contains:"!" %}{{ typeName | replace:"any","(any" | replace:"!",")!" }}{% elif typeName|contains:"any" and typeName.isOptional %}{{ typeName | replace:"any","(any" | replace:"?",")?" }}{% elif typeName|contains:"any" and typeName.isClosure %}({{ typeName | replace:"any","(any" | replace:"?",")?" }}){%else%}{{ typeName }}{%endif%}{% endmacro %} +{% macro existentialVariableTypeName typeName %}{% if typeName|contains:"any" and typeName|contains:"!" %}{{ typeName | replace:"any","(any" | replace:"!",")!" }}{% elif typeName|contains:"any" and typeName.isOptional %}{{ typeName | replace:"any","(any" | replace:"?",")?" }}{% elif typeName|contains:"any" and typeName.isClosure and typeName|contains:"?"%}({{ typeName | replace:"any","(any" | replace:"?",")?" }}){%else%}{{ typeName }}{%endif%}{% endmacro %} {% macro existentialClosureVariableTypeName typeName %}{% if typeName|contains:"any" and typeName|contains:"!" %}{{ typeName | replace:"any","(any" | replace:"!",")?" }}{% elif typeName|contains:"any" and typeName.isClosure and typeName|contains:"?" %}{{ typeName | replace:"any","(any" | replace:"?",")?" }}{% elif typeName|contains:"any" and typeName|contains:"?" %}{{ typeName | replace:"any","(any" | replace:"?",")?" }}{%else%}{{ typeName }}{%endif%}{% endmacro %} {% macro existentialParameterTypeName typeName %}{% if typeName|contains:"any" and typeName|contains:"!" %}{{ typeName | replace:"any","(any" | replace:"!",")!" }}{% elif typeName|contains:"any" and typeName.isClosure and typeName|contains:"?" %}{{ typeName | replace:"any","(any" | replace:"?",")?" }}{% elif typeName|contains:"any" and typeName.isOptional %}{{ typeName | replace:"any","(any" | replace:"?",")?" }}{%else%}{{ typeName }}{%endif%}{% endmacro %} {% macro methodName method %}func {{ method.shortName}}({%- for param in method.parameters %}{% if param.argumentLabel == nil %}_ {{ param.name }}{%elif param.argumentLabel == param.name%}{{ param.name }}{%else%}{{ param.argumentLabel }} {{ param.name }}{% endif %}: {% call existentialParameterTypeName param.typeName %}{% if not forloop.last %}, {% endif %}{% endfor -%}){% endmacro %} diff --git a/Templates/Tests/Context/AutoMockable.swift b/Templates/Tests/Context/AutoMockable.swift index e3b4ec9be..6e97c121d 100644 --- a/Templates/Tests/Context/AutoMockable.swift +++ b/Templates/Tests/Context/AutoMockable.swift @@ -171,4 +171,14 @@ protocol AnyProtocol: AutoMockable { func n(x: @escaping ((any StubProtocol)?) -> Void) var o: any StubWithAnyNameProtocol { get } func p(_ x: (any StubWithAnyNameProtocol)?) + func q() -> any StubProtocol + func r() -> (any StubProtocol)? + func s() -> () -> any StubProtocol + func t() -> () -> (any StubProtocol)? + func u() -> (Int, () -> (any StubProtocol)?) + func v() -> (Int, (() -> any StubProtocol)?) + func w() -> [(any StubProtocol)?] + func x() -> [String: (any StubProtocol)?] + func y() -> (any StubProtocol, (any StubProtocol)?) + func z() -> any StubProtocol & CustomStringConvertible } diff --git a/Templates/Tests/Expected/AutoMockable.expected b/Templates/Tests/Expected/AutoMockable.expected index 9f422adc5..e771308c2 100644 --- a/Templates/Tests/Expected/AutoMockable.expected +++ b/Templates/Tests/Expected/AutoMockable.expected @@ -215,6 +215,186 @@ class AnyProtocolMock: AnyProtocol { pClosure?(x) } + //MARK: - q + + var qCallsCount = 0 + var qCalled: Bool { + return qCallsCount > 0 + } + var qReturnValue: (any StubProtocol)! + var qClosure: (() -> any StubProtocol)? + + func q() -> any StubProtocol { + qCallsCount += 1 + if let qClosure = qClosure { + return qClosure() + } else { + return qReturnValue + } + } + + //MARK: - r + + var rCallsCount = 0 + var rCalled: Bool { + return rCallsCount > 0 + } + var rReturnValue: ((any StubProtocol)?) + var rClosure: (() -> (any StubProtocol)?)? + + func r() -> (any StubProtocol)? { + rCallsCount += 1 + if let rClosure = rClosure { + return rClosure() + } else { + return rReturnValue + } + } + + //MARK: - s + + var sCallsCount = 0 + var sCalled: Bool { + return sCallsCount > 0 + } + var sReturnValue: (() -> any StubProtocol)! + var sClosure: (() -> () -> any StubProtocol)? + + func s() -> () -> any StubProtocol { + sCallsCount += 1 + if let sClosure = sClosure { + return sClosure() + } else { + return sReturnValue + } + } + + //MARK: - t + + var tCallsCount = 0 + var tCalled: Bool { + return tCallsCount > 0 + } + var tReturnValue: ((() -> (any StubProtocol)?))! + var tClosure: (() -> (() -> (any StubProtocol)?))? + + func t() -> (() -> (any StubProtocol)?) { + tCallsCount += 1 + if let tClosure = tClosure { + return tClosure() + } else { + return tReturnValue + } + } + + //MARK: - u + + var uCallsCount = 0 + var uCalled: Bool { + return uCallsCount > 0 + } + var uReturnValue: ((Int, () -> (any StubProtocol)?))! + var uClosure: (() -> (Int, () -> (any StubProtocol)?))? + + func u() -> (Int, () -> (any StubProtocol)?) { + uCallsCount += 1 + if let uClosure = uClosure { + return uClosure() + } else { + return uReturnValue + } + } + + //MARK: - v + + var vCallsCount = 0 + var vCalled: Bool { + return vCallsCount > 0 + } + var vReturnValue: ((Int, (() -> any StubProtocol)?))! + var vClosure: (() -> (Int, (() -> any StubProtocol)?))? + + func v() -> (Int, (() -> any StubProtocol)?) { + vCallsCount += 1 + if let vClosure = vClosure { + return vClosure() + } else { + return vReturnValue + } + } + + //MARK: - w + + var wCallsCount = 0 + var wCalled: Bool { + return wCallsCount > 0 + } + var wReturnValue: ([(any StubProtocol)?])! + var wClosure: (() -> [(any StubProtocol)?])? + + func w() -> [(any StubProtocol)?] { + wCallsCount += 1 + if let wClosure = wClosure { + return wClosure() + } else { + return wReturnValue + } + } + + //MARK: - x + + var xCallsCount = 0 + var xCalled: Bool { + return xCallsCount > 0 + } + var xReturnValue: ([String: (any StubProtocol)?])! + var xClosure: (() -> [String: (any StubProtocol)?])? + + func x() -> [String: (any StubProtocol)?] { + xCallsCount += 1 + if let xClosure = xClosure { + return xClosure() + } else { + return xReturnValue + } + } + + //MARK: - y + + var yCallsCount = 0 + var yCalled: Bool { + return yCallsCount > 0 + } + var yReturnValue: ((any StubProtocol, (any StubProtocol)?))! + var yClosure: (() -> (any StubProtocol, (any StubProtocol)?))? + + func y() -> (any StubProtocol, (any StubProtocol)?) { + yCallsCount += 1 + if let yClosure = yClosure { + return yClosure() + } else { + return yReturnValue + } + } + + //MARK: - z + + var zCallsCount = 0 + var zCalled: Bool { + return zCallsCount > 0 + } + var zReturnValue: (any StubProtocol & CustomStringConvertible)! + var zClosure: (() -> any StubProtocol & CustomStringConvertible)? + + func z() -> any StubProtocol & CustomStringConvertible { + zCallsCount += 1 + if let zClosure = zClosure { + return zClosure() + } else { + return zReturnValue + } + } + } class AsyncProtocolMock: AsyncProtocol { @@ -655,7 +835,7 @@ class ImplicitlyUnwrappedOptionalReturnValueProtocolMock: ImplicitlyUnwrappedOpt return implicitReturnCallsCount > 0 } var implicitReturnReturnValue: String! - var implicitReturnClosure: (() -> String?)? + var implicitReturnClosure: (() -> String!)? func implicitReturn() -> String! { implicitReturnCallsCount += 1 diff --git a/Templates/Tests/Generated/AutoMockable.generated.swift b/Templates/Tests/Generated/AutoMockable.generated.swift index 7eaff0856..1b272044c 100644 --- a/Templates/Tests/Generated/AutoMockable.generated.swift +++ b/Templates/Tests/Generated/AutoMockable.generated.swift @@ -238,6 +238,186 @@ class AnyProtocolMock: AnyProtocol { pClosure?(x) } + //MARK: - q + + var qCallsCount = 0 + var qCalled: Bool { + return qCallsCount > 0 + } + var qReturnValue: (any StubProtocol)! + var qClosure: (() -> any StubProtocol)? + + func q() -> any StubProtocol { + qCallsCount += 1 + if let qClosure = qClosure { + return qClosure() + } else { + return qReturnValue + } + } + + //MARK: - r + + var rCallsCount = 0 + var rCalled: Bool { + return rCallsCount > 0 + } + var rReturnValue: ((any StubProtocol)?) + var rClosure: (() -> (any StubProtocol)?)? + + func r() -> (any StubProtocol)? { + rCallsCount += 1 + if let rClosure = rClosure { + return rClosure() + } else { + return rReturnValue + } + } + + //MARK: - s + + var sCallsCount = 0 + var sCalled: Bool { + return sCallsCount > 0 + } + var sReturnValue: (() -> any StubProtocol)! + var sClosure: (() -> () -> any StubProtocol)? + + func s() -> () -> any StubProtocol { + sCallsCount += 1 + if let sClosure = sClosure { + return sClosure() + } else { + return sReturnValue + } + } + + //MARK: - t + + var tCallsCount = 0 + var tCalled: Bool { + return tCallsCount > 0 + } + var tReturnValue: ((() -> (any StubProtocol)?))! + var tClosure: (() -> (() -> (any StubProtocol)?))? + + func t() -> (() -> (any StubProtocol)?) { + tCallsCount += 1 + if let tClosure = tClosure { + return tClosure() + } else { + return tReturnValue + } + } + + //MARK: - u + + var uCallsCount = 0 + var uCalled: Bool { + return uCallsCount > 0 + } + var uReturnValue: ((Int, () -> (any StubProtocol)?))! + var uClosure: (() -> (Int, () -> (any StubProtocol)?))? + + func u() -> (Int, () -> (any StubProtocol)?) { + uCallsCount += 1 + if let uClosure = uClosure { + return uClosure() + } else { + return uReturnValue + } + } + + //MARK: - v + + var vCallsCount = 0 + var vCalled: Bool { + return vCallsCount > 0 + } + var vReturnValue: ((Int, (() -> any StubProtocol)?))! + var vClosure: (() -> (Int, (() -> any StubProtocol)?))? + + func v() -> (Int, (() -> any StubProtocol)?) { + vCallsCount += 1 + if let vClosure = vClosure { + return vClosure() + } else { + return vReturnValue + } + } + + //MARK: - w + + var wCallsCount = 0 + var wCalled: Bool { + return wCallsCount > 0 + } + var wReturnValue: ([(any StubProtocol)?])! + var wClosure: (() -> [(any StubProtocol)?])? + + func w() -> [(any StubProtocol)?] { + wCallsCount += 1 + if let wClosure = wClosure { + return wClosure() + } else { + return wReturnValue + } + } + + //MARK: - x + + var xCallsCount = 0 + var xCalled: Bool { + return xCallsCount > 0 + } + var xReturnValue: ([String: (any StubProtocol)?])! + var xClosure: (() -> [String: (any StubProtocol)?])? + + func x() -> [String: (any StubProtocol)?] { + xCallsCount += 1 + if let xClosure = xClosure { + return xClosure() + } else { + return xReturnValue + } + } + + //MARK: - y + + var yCallsCount = 0 + var yCalled: Bool { + return yCallsCount > 0 + } + var yReturnValue: ((any StubProtocol, (any StubProtocol)?))! + var yClosure: (() -> (any StubProtocol, (any StubProtocol)?))? + + func y() -> (any StubProtocol, (any StubProtocol)?) { + yCallsCount += 1 + if let yClosure = yClosure { + return yClosure() + } else { + return yReturnValue + } + } + + //MARK: - z + + var zCallsCount = 0 + var zCalled: Bool { + return zCallsCount > 0 + } + var zReturnValue: (any StubProtocol & CustomStringConvertible)! + var zClosure: (() -> any StubProtocol & CustomStringConvertible)? + + func z() -> any StubProtocol & CustomStringConvertible { + zCallsCount += 1 + if let zClosure = zClosure { + return zClosure() + } else { + return zReturnValue + } + } + } class AsyncProtocolMock: AsyncProtocol { @@ -678,7 +858,7 @@ class ImplicitlyUnwrappedOptionalReturnValueProtocolMock: ImplicitlyUnwrappedOpt return implicitReturnCallsCount > 0 } var implicitReturnReturnValue: String! - var implicitReturnClosure: (() -> String?)? + var implicitReturnClosure: (() -> String!)? func implicitReturn() -> String! { implicitReturnCallsCount += 1