Skip to content

Commit

Permalink
Some bugfixes and improvements regarding newlining
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmya committed Aug 1, 2023
1 parent ab57bb5 commit c55a6b6
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 29 deletions.
10 changes: 10 additions & 0 deletions Sources/MockDeclarations/MockModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ struct MockModelWithInitMethodDeclaration {
}
}

// sourcery: AutoStubbable
struct MockModelWithInitMethodAndImplicitlyUnwrappedOptionalDeclaration {
let property: Int
var implicitlyUnwrappedProperty: Int!

init(property: Int) {
self.property = property
}
}

// sourcery: AutoStubbable
struct MockModelDeclaration {
let property: Int
Expand Down
5 changes: 5 additions & 0 deletions Sources/MockDeclarations/MockProtocols.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ protocol MockProtocolWithPropertyAndMethod {
func method()
}

// sourcery: AutoMockable
protocol MockProtocolWithReturnSelf {
func method() -> Self
}

class SomeType { }

// sourcery: AutoMockable
Expand Down
15 changes: 10 additions & 5 deletions Sources/Templates/AutoStubbable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ enum AutoStubbable {
lines.append("")

let sortedTypes = (types.structs + types.classes).sorted(by: { $0.name < $1.name }).filter(\.isAutoStubbable)
lines.append(contentsOf: sortedTypes.flatMap { type in
let types = sortedTypes.map { type in
type.generateStub()
})

}.joined(separator: [.emptyLine])
lines.append(contentsOf: types)

return lines.joined(separator: .newLine)
}
}
Expand All @@ -20,8 +21,9 @@ extension Type {
func generateStub() -> [String] {
var lines: [String] = []
lines.append("\(accessLevel) extension \(name) {")
let implicitlyUnwrappedVariables = storedVariables.filter(\.isImplicitlyUnwrappedOptional)
initMethods.enumerated().forEach { index, method in

let initMethodLines = initMethods.enumerated().map { index, method in
var lines: [String] = []
lines.append("static func \(stubMethodName(index: index, count: initMethods.count))(".addingIndent())
let methodParameterLines = method.parameters.map { parameter in
"\(parameter.argumentLabel ?? parameter.name): \(parameter.typeName.generateStubbableName(type: parameter.type)) = \(parameter.typeName.generateDefaultValue(type: parameter.type, includeComplexType: true))".addingIndent(count: 2)
Expand All @@ -37,7 +39,10 @@ extension Type {
lines.append(joinedMethodAssignmentLines)
lines.append(")".addingIndent(count: 2))
lines.append("}".addingIndent())
return lines
}
lines.append(contentsOf: initMethodLines.joined(separator: [.emptyLine]))

if initMethods.isEmpty {
lines.append("static func \(stubMethodName(index: 0, count: 1))(".addingIndent())
let availableVariables = storedVariables.filter { !$0.hasDefaultValue }
Expand Down
4 changes: 0 additions & 4 deletions Sources/Templates/Extensions/Annotated+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,4 @@ extension Annotated {
var isAutoMockable: Bool {
annotations["AutoMockable"] as? Int == 1
}

var isFinal: Bool {
annotations["final"] as? Int == 1
}
}
3 changes: 2 additions & 1 deletion Sources/Templates/Extensions/Method+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ private extension Method {
fatalError("Something terrible happened")
}


/// Generates parameters that are captured or returned
/// - Parameters:
/// - name: Unique name of the method to generate stub parameters for
Expand Down Expand Up @@ -107,6 +106,7 @@ private extension Method {
}
}
if !returnTypeName.isVoid && !isInitializer {
// Stored property cannot have covariant `Self` type
let returnTypeNameString = returnTypeName.name == "Self" ? "Default\(type.name)Mock" : returnTypeName.name
let defaultValue = returnTypeName.generateDefaultValue(type: returnType, includeComplexType: false)
let nonOptionalSignature = defaultValue.isEmpty ? "!" : "! = \(defaultValue)"
Expand Down Expand Up @@ -221,6 +221,7 @@ private extension Method {

func mockReturnType(type: Type) -> String? {
guard !returnTypeName.isVoid else { return nil }
// We have to return a concrete type instead of `Self`
if returnTypeName.name == "Self" {
return "-> Default\(type.name)Mock"
}
Expand Down
4 changes: 3 additions & 1 deletion Sources/Templates/Extensions/Protocol+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ private extension Protocol {
if based.contains(where: { $0.key == "AnyActor"}) {
return "actor"
}
return isFinal ? "final class" : "class"
// If we have a method that returns `Self` we must declare the class final
let shouldBeFinal = methods.contains(where: { $0.returnTypeName.name == "Self"} )
return shouldBeFinal ? "final class" : "class"
}
}

Expand Down
29 changes: 14 additions & 15 deletions Sources/Templates/Extensions/TypeName+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,21 @@ extension TypeName {
return "{ \(closure.returnTypeName.generateDefaultValue(type: closure.returnType, includeComplexType: includeComplexType)) } "
}

switch unwrappedTypeName {
case "String", "Character": return "\"\""
case "Int", "Double", "TimeInterval", "CGFloat", "Float": return "0"
case "Bool": return "false"
case "URL": return "URL(fileURLWithPath: \"\")"
case "UIApplication": return ".shared" // UIApplication is special
default:
if includeComplexType {
if type?.isAutoStubbable == true {
return "\(generateStubbableName(type: type)).stub()"
} else if type?.isAutoMockable == true {
return "Default\(unwrappedTypeName)Mock()"
}

return ".init()"
switch (unwrappedTypeName, includeComplexType) {
case ("String", _), ("Character", _): return "\"\""
case ("Int", _), ("Double", _), ("TimeInterval", _), ("CGFloat", _), ("Float", _): return "0"
case ("Bool", _): return "false"
case ("URL", true): return "URL(fileURLWithPath: \"\")"
case ("UIApplication", true): return ".shared" // UIApplication is special
case (_, true):
if type?.isAutoStubbable == true {
return "\(generateStubbableName(type: type)).stub()"
} else if type?.isAutoMockable == true {
return "Default\(unwrappedTypeName)Mock()"
}

return ".init()"
default:
return ""
}
}
Expand Down
6 changes: 3 additions & 3 deletions Sources/Templates/Extensions/Variable+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import SourceryRuntime

extension Variable {
func generateMock() -> String {
isMutable ? mockMutable : mockComputed
isMutable ? generateMutableMock() : generateComputedMock()
}
}

private extension Variable {
var mockMutable: String {
func generateMutableMock() -> String {
let capitalizedName = name.capitalizingFirstLetter()
let defaultValue = typeName.generateDefaultValue(type: type, includeComplexType: false)
let nonOptionalSignature = defaultValue.isEmpty ? "!" : "! = \(defaultValue)"
Expand Down Expand Up @@ -38,7 +38,7 @@ private extension Variable {
"""
}

var mockComputed: String {
func generateComputedMock() -> String {
let capitalizedName = name.capitalizingFirstLetter()
let defaultValue = typeName.generateDefaultValue(type: type, includeComplexType: false)
let nonOptionalSignature = defaultValue.isEmpty ? "!" : "! = \(defaultValue)"
Expand Down
15 changes: 15 additions & 0 deletions Tests/TemplateTests/AutoMockable.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,19 @@ class DefaultMockProtocolWithPropertyAndMethodMock: MockProtocolWithPropertyAndM
invokedMethod = true
invokedMethodCount += 1
}
}

final class DefaultMockProtocolWithReturnSelfMock: MockProtocolWithReturnSelf {

var invokedMethod = false
var invokedMethodCount = 0
var stubbedMethodResult: DefaultMockProtocolWithReturnSelfMock!
var invokedMethodExpectation = XCTestExpectation(description: "\(#function) expectation")

func method() -> DefaultMockProtocolWithReturnSelfMock {
defer { invokedMethodExpectation.fulfill() }
invokedMethod = true
invokedMethodCount += 1
return stubbedMethodResult
}
}
13 changes: 13 additions & 0 deletions Tests/TemplateTests/AutoStubbable.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ internal extension MockModelDeclaration {
)
}
}

internal extension MockModelWithInitMethodAndImplicitlyUnwrappedOptionalDeclaration {
static func stub(
property: Int = 0
) -> MockModelWithInitMethodAndImplicitlyUnwrappedOptionalDeclaration {
MockModelWithInitMethodAndImplicitlyUnwrappedOptionalDeclaration(
property: property
)
}
}

internal extension MockModelWithInitMethodDeclaration {
static func stub0(
property: Int = 0,
Expand All @@ -25,6 +36,7 @@ internal extension MockModelWithInitMethodDeclaration {
somesome: somesome
)
}

static func stub1(
property: Int = 0,
optionalProperty: String? = nil
Expand All @@ -34,6 +46,7 @@ internal extension MockModelWithInitMethodDeclaration {
optionalProperty: optionalProperty
)
}

static func stub2(
property: Int = 0,
failableOptionalProperty: String? = nil
Expand Down

0 comments on commit c55a6b6

Please sign in to comment.