From ccfba68ee1e8e65095026d13aa2ee515e5beeb16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kry=C5=A1tof=20Mat=C4=9Bj?= Date: Fri, 10 May 2024 13:52:56 +0200 Subject: [PATCH] Add option to generate init with optional variables --- Sources/Rubicon/Domain/AccessLevel.swift | 12 ---- .../Rubicon/Generator/DummyGenerator.swift | 2 +- Sources/Rubicon/Generator/InitGenerator.swift | 30 ++++----- Sources/Rubicon/Generator/SpyGenerator.swift | 11 +++- Sources/Rubicon/Generator/StubGenerator.swift | 11 +++- Sources/Rubicon/Integration/Rubicon.swift | 64 +++++++++++++++++-- .../Generator/InitGeneratorTests.swift | 34 ++++++++-- .../Generator/SpyGeneratorTests.swift | 40 +++++++++--- .../Generator/StubGeneratorTests.swift | 45 +++++++++---- .../Integration/SpyIntegrationTests.swift | 21 +++++- .../Integration/StubIntegrationTests.swift | 19 +++++- 11 files changed, 218 insertions(+), 71 deletions(-) diff --git a/Sources/Rubicon/Domain/AccessLevel.swift b/Sources/Rubicon/Domain/AccessLevel.swift index 3f355b1..7d129f7 100644 --- a/Sources/Rubicon/Domain/AccessLevel.swift +++ b/Sources/Rubicon/Domain/AccessLevel.swift @@ -11,18 +11,6 @@ public enum AccessLevel { case `internal` case `private` - // TODO: DELETE ME LATER! - func makeClassString() -> String { - switch self { - case .public: - return "public " - case .internal: - return "" - case .private: - return "private " - } - } - func makeContentString() -> String { switch self { case .public: diff --git a/Sources/Rubicon/Generator/DummyGenerator.swift b/Sources/Rubicon/Generator/DummyGenerator.swift index ee315e3..62fc963 100644 --- a/Sources/Rubicon/Generator/DummyGenerator.swift +++ b/Sources/Rubicon/Generator/DummyGenerator.swift @@ -35,7 +35,7 @@ final class DummyGenerator { setContent: ["fatalError()"] ) }) - content.append(initGenerator.makeCode(with: [])) + content.append(initGenerator.makeCode(with: [], isAddingDefaultValueToOptionalsEnabled: false)) content += protocolType.functions.map { return functionGenerator.makeCode(from: $0, content: ["fatalError()"]) diff --git a/Sources/Rubicon/Generator/InitGenerator.swift b/Sources/Rubicon/Generator/InitGenerator.swift index 367ecc8..1018e7e 100644 --- a/Sources/Rubicon/Generator/InitGenerator.swift +++ b/Sources/Rubicon/Generator/InitGenerator.swift @@ -1,5 +1,5 @@ protocol InitGenerator { - func makeCode(with variables: [VarDeclaration]) -> [String] + func makeCode(with variables: [VarDeclaration], isAddingDefaultValueToOptionalsEnabled: Bool) -> [String] } final class InitGeneratorImpl: InitGenerator { @@ -20,14 +20,17 @@ final class InitGeneratorImpl: InitGenerator { self.argumentGenerator = argumentGenerator } - func makeCode(with variables: [VarDeclaration]) -> [String] { - let assignments = variables.compactMap(makeAssigment(of:)) + func makeCode(with variables: [VarDeclaration], isAddingDefaultValueToOptionalsEnabled: Bool) -> [String] { + let assignments = variables.map(makeAssigment(of:)) guard !assignments.isEmpty || accessLevel == .public else { return [] } - let initArguments = variables.compactMap(makeInitArgument(from:)).joined(separator: ", ") + let initArguments = variables.map { makeInitArgument( + from: $0, + isAddingDefaultValueToOptionalsEnabled: isAddingDefaultValueToOptionalsEnabled + ) } .joined(separator: ", ") return [ "\(accessLevelGenerator.makeContentAccessLevel())init(\(initArguments)) {" @@ -36,20 +39,13 @@ final class InitGeneratorImpl: InitGenerator { ] } - private func makeAssigment(of variable: VarDeclaration) -> String? { - if variable.type.isOptional { - return nil - } else { - return "self.\(variable.identifier) = \(variable.identifier)" - } + private func makeAssigment(of variable: VarDeclaration) -> String { + return "self.\(variable.identifier) = \(variable.identifier)" } - private func makeInitArgument(from variable: VarDeclaration) -> String? { - if variable.type.isOptional { - return nil - } else { - let declaration = ArgumentDeclaration(name: variable.identifier, type: variable.type) - return argumentGenerator.makeCode(from: declaration) - } + private func makeInitArgument(from variable: VarDeclaration, isAddingDefaultValueToOptionalsEnabled: Bool) -> String { + let defaultValue = isAddingDefaultValueToOptionalsEnabled && variable.type.isOptional ? " = nil" : "" + let declaration = ArgumentDeclaration(name: variable.identifier, type: variable.type) + return argumentGenerator.makeCode(from: declaration) + defaultValue } } diff --git a/Sources/Rubicon/Generator/SpyGenerator.swift b/Sources/Rubicon/Generator/SpyGenerator.swift index ba8d61f..620c932 100644 --- a/Sources/Rubicon/Generator/SpyGenerator.swift +++ b/Sources/Rubicon/Generator/SpyGenerator.swift @@ -6,6 +6,7 @@ final class SpyGenerator { private let initGenerator: InitGenerator private let structGenerator: StructGenerator private let accessLevelGenerator: AccessLevelGenerator + private var isInitWithOptionalsEnabled: Bool = false init( protocolGenerator: ProtocolGenerator, @@ -25,7 +26,8 @@ final class SpyGenerator { self.accessLevelGenerator = accessLevelGenerator } - func generate(from protocolType: ProtocolDeclaration) -> String { + func generate(from protocolType: ProtocolDeclaration, isInitWithOptionalsEnabled: Bool) -> String { + self.isInitWithOptionalsEnabled = isInitWithOptionalsEnabled let content = generateBody(from: protocolType) return protocolGenerator.makeProtocol( from: protocolType, @@ -43,7 +45,12 @@ final class SpyGenerator { content.append(makeVariables(from: protocolType).map(variableGenerator.makeCode)) content.append(makeSpyVariables(from: protocolType)) - content.append(initGenerator.makeCode(with: makeVariables(from: protocolType) + makeReturnVariables(from: protocolType))) + let initVariables = makeVariables(from: protocolType) + makeReturnVariables(from: protocolType) + let nonOptionalInitVariables = initVariables.filter { !$0.type.isOptional } + content.append(initGenerator.makeCode( + with: isInitWithOptionalsEnabled ? initVariables : nonOptionalInitVariables, + isAddingDefaultValueToOptionalsEnabled: isInitWithOptionalsEnabled + )) content += protocolType.functions.map { makeFunction(from: $0, protocolDeclaration: protocolType) diff --git a/Sources/Rubicon/Generator/StubGenerator.swift b/Sources/Rubicon/Generator/StubGenerator.swift index ec01973..8b5c281 100644 --- a/Sources/Rubicon/Generator/StubGenerator.swift +++ b/Sources/Rubicon/Generator/StubGenerator.swift @@ -4,6 +4,7 @@ final class StubGenerator { private let functionGenerator: FunctionGenerator private let functionNameGenerator: FunctionNameGenerator private let initGenerator: InitGenerator + private var isInitWithOptionalsEnabled: Bool = false init( protocolGenerator: ProtocolGenerator, @@ -19,7 +20,8 @@ final class StubGenerator { self.initGenerator = initGenerator } - func generate(from protocolType: ProtocolDeclaration, nameSuffix: String) -> String { + func generate(from protocolType: ProtocolDeclaration, nameSuffix: String, isInitWithOptionalsEnabled: Bool) -> String { + self.isInitWithOptionalsEnabled = isInitWithOptionalsEnabled let content = generateBody(from: protocolType) return protocolGenerator.makeProtocol( from: protocolType, @@ -32,7 +34,12 @@ final class StubGenerator { var content = [[String]]() content.append(makeVariables(from: protocolType).map(variableGenerator.makeCode)) - content.append(initGenerator.makeCode(with: makeVariables(from: protocolType))) + let initVariables = makeVariables(from: protocolType) + let nonOptionalInitVariables = initVariables.filter { !$0.type.isOptional } + content.append(initGenerator.makeCode( + with: isInitWithOptionalsEnabled ? initVariables : nonOptionalInitVariables, + isAddingDefaultValueToOptionalsEnabled: isInitWithOptionalsEnabled + )) content += protocolType.functions.map { makeFunction(from: $0, protocolDeclaration: protocolType) diff --git a/Sources/Rubicon/Integration/Rubicon.swift b/Sources/Rubicon/Integration/Rubicon.swift index 272baff..58129aa 100644 --- a/Sources/Rubicon/Integration/Rubicon.swift +++ b/Sources/Rubicon/Integration/Rubicon.swift @@ -1,3 +1,38 @@ +public struct SpyConfiguration { + public let accessLevel: AccessLevel + public let indentStep: String + public let isInitWithOptionalsEnabled: Bool + + public init( + accessLevel: AccessLevel, + indentStep: String, + isInitWithOptionalsEnabled: Bool + ) { + self.accessLevel = accessLevel + self.indentStep = indentStep + self.isInitWithOptionalsEnabled = isInitWithOptionalsEnabled + } +} + +public struct StubConfiguration { + public let accessLevel: AccessLevel + public let indentStep: String + public let nameSuffix: String + public let isInitWithOptionalsEnabled: Bool + + public init( + accessLevel: AccessLevel, + indentStep: String, + nameSuffix: String = "Stub", + isInitWithOptionalsEnabled: Bool + ) { + self.accessLevel = accessLevel + self.indentStep = indentStep + self.nameSuffix = nameSuffix + self.isInitWithOptionalsEnabled = isInitWithOptionalsEnabled + } +} + public final class Rubicon { public init() {} @@ -35,12 +70,21 @@ public final class Rubicon { ) } - public func makeStub(code: String, accessLevel: AccessLevel, indentStep: String, nameSuffix: String = "Stub") -> [String] { + public func makeStub(code: String, configuration: StubConfiguration) -> [String] { let parser = makeParser() - let generator = makeStubGenerator(accessLevel: accessLevel, indentStep: indentStep) + let generator = makeStubGenerator( + accessLevel: configuration.accessLevel, + indentStep: configuration.indentStep + ) do { let protocols = try parser.parse(text: code) - return protocols.map { generator.generate(from: $0, nameSuffix: nameSuffix) } + return protocols.map { + generator.generate( + from: $0, + nameSuffix: configuration.nameSuffix, + isInitWithOptionalsEnabled: configuration.isInitWithOptionalsEnabled + ) + } } catch { return [] } @@ -57,12 +101,20 @@ public final class Rubicon { ) } - public func makeSpy(code: String, accessLevel: AccessLevel, indentStep: String) -> [String] { + public func makeSpy(code: String, configuration: SpyConfiguration) -> [String] { let parser = makeParser() - let generator = makeSpyGenerator(accessLevel: accessLevel, indentStep: indentStep) + let generator = makeSpyGenerator( + accessLevel: configuration.accessLevel, + indentStep: configuration.indentStep + ) do { let protocols = try parser.parse(text: code) - return protocols.map(generator.generate(from:)) + return protocols.map{ + generator.generate( + from: $0, + isInitWithOptionalsEnabled: configuration.isInitWithOptionalsEnabled + ) + } } catch { return [] } diff --git a/Tests/RubiconTests/Generator/InitGeneratorTests.swift b/Tests/RubiconTests/Generator/InitGeneratorTests.swift index c9e6865..a0b8f58 100644 --- a/Tests/RubiconTests/Generator/InitGeneratorTests.swift +++ b/Tests/RubiconTests/Generator/InitGeneratorTests.swift @@ -26,7 +26,7 @@ final class InitGeneratorTests: XCTestCase { } func test_givenNoVariable_whenMakeCode_thenDoNotMakeInit() { - let result = sut.makeCode(with: []) + let result = sut.makeCode(with: [], isAddingDefaultValueToOptionalsEnabled: false) XCTAssertEqual(result, []) } @@ -34,7 +34,7 @@ final class InitGeneratorTests: XCTestCase { func test_givenPublicAccessLevelAndNoVariable_whenMakeCode_thenMakeInit() { initialize(accessLevel: .public) - let result = sut.makeCode(with: []) + let result = sut.makeCode(with: [], isAddingDefaultValueToOptionalsEnabled: false) equal(result, rows: [ "accessLevel init() {", @@ -45,7 +45,7 @@ final class InitGeneratorTests: XCTestCase { func test_givenSomeVariables_whenMakeCode_thenMakeInit() { initialize(accessLevel: .public) - let result = sut.makeCode(with: [.makeStub(), .makeStub()]) + let result = sut.makeCode(with: [.makeStub(), .makeStub()], isAddingDefaultValueToOptionalsEnabled: false) equal(result, rows: [ "accessLevel init(argument, argument) {", @@ -60,14 +60,36 @@ final class InitGeneratorTests: XCTestCase { func test_givenOptionalVariable_whenMakeCode_thenMakeInit() { initialize(accessLevel: .public) - let result = sut.makeCode(with: [.makeStub(), .makeStub(type: .makeStub(isOptional: true))]) + let result = sut.makeCode( + with: [.makeStub(), .makeStub(type: .makeStub(isOptional: true))], + isAddingDefaultValueToOptionalsEnabled: false + ) equal(result, rows: [ - "accessLevel init(argument) {", + "accessLevel init(argument, argument) {", + "-self.identifier = identifier", "-self.identifier = identifier", "}", ]) - XCTAssertEqual(argumentGeneratorSpy.makeCode.count, 1) + XCTAssertEqual(argumentGeneratorSpy.makeCode.count, 2) + XCTAssertEqual(argumentGeneratorSpy.makeCode.first?.declaration, .makeStub(label: nil, name: "identifier", type: .makeStub())) + } + + func test_givenOptionalVariableAndIsAddingDefaultValueToOptionalsEnabled_whenMakeCode_thenMakeInit() { + initialize(accessLevel: .public) + + let result = sut.makeCode( + with: [.makeStub(), .makeStub(type: .makeStub(isOptional: true))], + isAddingDefaultValueToOptionalsEnabled: true + ) + + equal(result, rows: [ + "accessLevel init(argument, argument = nil) {", + "-self.identifier = identifier", + "-self.identifier = identifier", + "}", + ]) + XCTAssertEqual(argumentGeneratorSpy.makeCode.count, 2) XCTAssertEqual(argumentGeneratorSpy.makeCode.first?.declaration, .makeStub(label: nil, name: "identifier", type: .makeStub())) } } diff --git a/Tests/RubiconTests/Generator/SpyGeneratorTests.swift b/Tests/RubiconTests/Generator/SpyGeneratorTests.swift index 1eb664f..c932ff0 100644 --- a/Tests/RubiconTests/Generator/SpyGeneratorTests.swift +++ b/Tests/RubiconTests/Generator/SpyGeneratorTests.swift @@ -33,7 +33,7 @@ final class SpyGeneratorTests: XCTestCase { } func test_givenEmptyProtocol_whenGenerate_thenGenerateCode() { - let result = sut.generate(from: .makeStub()) + let result = sut.generate(from: .makeStub(), isInitWithOptionalsEnabled: false) XCTAssertEqual(protocolGeneratorSpy.makeProtocol.count, 1) XCTAssertEqual(protocolGeneratorSpy.makeProtocol.first?.declaration, .makeStub()) @@ -47,7 +47,7 @@ final class SpyGeneratorTests: XCTestCase { func test_givenProtocolWithVariable_whenGenerate_thenGenerateSpy() { let protocolDeclaration = ProtocolDeclaration.makeStub(variables: [.makeStub()]) - _ = sut.generate(from: protocolDeclaration) + _ = sut.generate(from: protocolDeclaration, isInitWithOptionalsEnabled: false) XCTAssertEqual(variableGeneratorSpy.makeCode.count, 1) XCTAssertEqual(variableGeneratorSpy.makeCode.first?.declaration, .makeStub()) @@ -58,12 +58,13 @@ final class SpyGeneratorTests: XCTestCase { ]) XCTAssertEqual(initGeneratorSpy.makeCode.count, 1) XCTAssertEqual(initGeneratorSpy.makeCode.first?.variables, [.makeStub()]) + XCTAssertEqual(initGeneratorSpy.makeCode.first?.isAddingDefaultValueToOptionalsEnabled, false) } func test_givenProtocolWithConstant_whenGenerate_thenGenerateSpy() { let protocolDeclaration = ProtocolDeclaration.makeStub(variables: [.makeStub(isConstant: true)]) - _ = sut.generate(from: protocolDeclaration) + _ = sut.generate(from: protocolDeclaration, isInitWithOptionalsEnabled: false) XCTAssertEqual(initGeneratorSpy.makeCode.first?.variables.first?.isConstant, false) } @@ -71,7 +72,7 @@ final class SpyGeneratorTests: XCTestCase { func test_givenProtocolWithVariables_whenGenerate_thenGenerateSpy() { let protocolDeclaration = ProtocolDeclaration.makeStub(variables: [.makeStub(), .makeStub()]) - _ = sut.generate(from: protocolDeclaration) + _ = sut.generate(from: protocolDeclaration, isInitWithOptionalsEnabled: false) XCTAssertEqual(variableGeneratorSpy.makeCode.count, 2) equal(protocolGeneratorSpy.makeProtocol.first?.content, rows: [ @@ -85,7 +86,7 @@ final class SpyGeneratorTests: XCTestCase { func test_givenProtocolWithFunctionWithoutReturn_whenGenerate_thenGenerateSpy() { let protocolDeclaration = ProtocolDeclaration.makeStub(functions: [.makeStub()]) - _ = sut.generate(from: protocolDeclaration) + _ = sut.generate(from: protocolDeclaration, isInitWithOptionalsEnabled: false) equal(protocolGeneratorSpy.makeProtocol.first?.content, rows: [ "accessLevel var functionNameCount = 0", @@ -103,7 +104,7 @@ final class SpyGeneratorTests: XCTestCase { func test_givenProtocolWithFunctionWithtReturn_whenGenerate_thenGenerateSpy() { let protocolDeclaration = ProtocolDeclaration.makeStub(functions: [.makeStub(returnType: .makeStub())]) - _ = sut.generate(from: protocolDeclaration) + _ = sut.generate(from: protocolDeclaration, isInitWithOptionalsEnabled: false) XCTAssertEqual(variableGeneratorSpy.makeCode.count, 1) XCTAssertEqual(variableGeneratorSpy.makeCode.first?.declaration.identifier, "functionNameReturn") @@ -129,7 +130,7 @@ final class SpyGeneratorTests: XCTestCase { let returnType = TypeDeclaration.makeStub(isOptional: true) let protocolDeclaration = ProtocolDeclaration.makeStub(functions: [.makeStub(returnType: returnType)]) - _ = sut.generate(from: protocolDeclaration) + _ = sut.generate(from: protocolDeclaration, isInitWithOptionalsEnabled: false) XCTAssertEqual(variableGeneratorSpy.makeCode.count, 1) XCTAssertEqual(variableGeneratorSpy.makeCode.first?.declaration.identifier, "functionNameReturn") @@ -156,7 +157,7 @@ final class SpyGeneratorTests: XCTestCase { let functionDeclaration = FunctionDeclaration.makeStub(isThrowing: true, returnType: returnType) let protocolDeclaration = ProtocolDeclaration.makeStub(functions: [functionDeclaration]) - _ = sut.generate(from: protocolDeclaration) + _ = sut.generate(from: protocolDeclaration, isInitWithOptionalsEnabled: false) XCTAssertEqual(variableGeneratorSpy.makeCode.count, 2) XCTAssertEqual(variableGeneratorSpy.makeCode.first?.declaration.identifier, "functionNameThrowBlock") @@ -187,7 +188,7 @@ final class SpyGeneratorTests: XCTestCase { let functionDeclaration = FunctionDeclaration.makeStub(arguments: [.makeStub()]) let protocolDeclaration = ProtocolDeclaration.makeStub(functions: [functionDeclaration]) - _ = sut.generate(from: protocolDeclaration) + _ = sut.generate(from: protocolDeclaration, isInitWithOptionalsEnabled: false) equal(protocolGeneratorSpy.makeProtocol.first?.content, rows: [ "struct", @@ -213,6 +214,27 @@ final class SpyGeneratorTests: XCTestCase { XCTAssertEqual(structGeneratorSpy.makeCode.first?.declaration.variables.first?.identifier, "name") XCTAssertEqual(structGeneratorSpy.makeCode.first?.declaration.variables.first?.type, .makeStub()) } + + func test_givenProtocolWithOptionalVariablesAndIsInitWithOptionalsEnabled_whenGenerate_thenGenerateSpyWithMultipleInits() { + let protocolDeclaration = ProtocolDeclaration.makeStub( + variables: [ + .makeStub(), + .makeStub(type: .makeStub(isOptional: true)) + ] + ) + + _ = sut.generate(from: protocolDeclaration, isInitWithOptionalsEnabled: true) + + XCTAssertEqual(variableGeneratorSpy.makeCode.count, 2) + equal(protocolGeneratorSpy.makeProtocol.first?.content, rows: [ + "variable", + "variable", + "", + "init", + ]) + XCTAssertEqual(initGeneratorSpy.makeCode.count, 1) + XCTAssertEqual(initGeneratorSpy.makeCode.first?.isAddingDefaultValueToOptionalsEnabled, true) + } } final class StructGeneratorSpy: StructGenerator { diff --git a/Tests/RubiconTests/Generator/StubGeneratorTests.swift b/Tests/RubiconTests/Generator/StubGeneratorTests.swift index 2983220..bfdbf4d 100644 --- a/Tests/RubiconTests/Generator/StubGeneratorTests.swift +++ b/Tests/RubiconTests/Generator/StubGeneratorTests.swift @@ -27,7 +27,7 @@ final class StubGeneratorTests: XCTestCase { } func test_givenEmptyProtocol_whenGenerate_thenGenerateCode() { - let result = sut.generate(from: .makeStub(), nameSuffix: "Suffix") + let result = sut.generate(from: .makeStub(), nameSuffix: "Suffix", isInitWithOptionalsEnabled: false) XCTAssertEqual(protocolGeneratorSpy.makeProtocol.count, 1) XCTAssertEqual(protocolGeneratorSpy.makeProtocol.first?.declaration, .makeStub()) @@ -41,7 +41,7 @@ final class StubGeneratorTests: XCTestCase { func test_givenProtocolWithVariable_whenGenerate_thenGenerateStub() { let protocolDeclaration = ProtocolDeclaration.makeStub(variables: [.makeStub()]) - _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub") + _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub", isInitWithOptionalsEnabled: false) XCTAssertEqual(variableGeneratorSpy.makeCode.count, 1) XCTAssertEqual(variableGeneratorSpy.makeCode.first?.declaration, .makeStub()) @@ -52,12 +52,13 @@ final class StubGeneratorTests: XCTestCase { ]) XCTAssertEqual(initGeneratorSpy.makeCode.count, 1) XCTAssertEqual(initGeneratorSpy.makeCode.first?.variables, [.makeStub()]) + XCTAssertEqual(initGeneratorSpy.makeCode.first?.isAddingDefaultValueToOptionalsEnabled, false) } func test_givenProtocolWithConstant_whenGenerate_thenGenerateStub() { let protocolDeclaration = ProtocolDeclaration.makeStub(variables: [.makeStub(isConstant: true)]) - _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub") + _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub", isInitWithOptionalsEnabled: false) XCTAssertEqual(initGeneratorSpy.makeCode.first?.variables.first?.isConstant, false) } @@ -65,7 +66,7 @@ final class StubGeneratorTests: XCTestCase { func test_givenProtocolWithVariables_whenGenerate_thenGenerateStub() { let protocolDeclaration = ProtocolDeclaration.makeStub(variables: [.makeStub(), .makeStub()]) - _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub") + _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub", isInitWithOptionalsEnabled: false) XCTAssertEqual(variableGeneratorSpy.makeCode.count, 2) equal(protocolGeneratorSpy.makeProtocol.first?.content, rows: [ @@ -79,7 +80,7 @@ final class StubGeneratorTests: XCTestCase { func test_givenProtocolWithFunctionWithoutReturn_whenGenerate_thenGenerateStub() { let protocolDeclaration = ProtocolDeclaration.makeStub(functions: [.makeStub()]) - _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub") + _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub", isInitWithOptionalsEnabled: false) equal(protocolGeneratorSpy.makeProtocol.first?.content, rows: [ "init", @@ -94,7 +95,7 @@ final class StubGeneratorTests: XCTestCase { func test_givenProtocolWithFunctionWithtReturn_whenGenerate_thenGenerateStub() { let protocolDeclaration = ProtocolDeclaration.makeStub(functions: [.makeStub(returnType: .makeStub())]) - _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub") + _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub", isInitWithOptionalsEnabled: false) XCTAssertEqual(variableGeneratorSpy.makeCode.count, 1) XCTAssertEqual(variableGeneratorSpy.makeCode.first?.declaration.identifier, "functionNameReturn") @@ -118,7 +119,7 @@ final class StubGeneratorTests: XCTestCase { let returnType = TypeDeclaration.makeStub(isOptional: true) let protocolDeclaration = ProtocolDeclaration.makeStub(functions: [.makeStub(returnType: returnType)]) - _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub") + _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub", isInitWithOptionalsEnabled: false) XCTAssertEqual(variableGeneratorSpy.makeCode.count, 1) XCTAssertEqual(variableGeneratorSpy.makeCode.first?.declaration.identifier, "functionNameReturn") @@ -141,7 +142,7 @@ final class StubGeneratorTests: XCTestCase { let functionDeclaration = FunctionDeclaration.makeStub(isThrowing: true, returnType: returnType) let protocolDeclaration = ProtocolDeclaration.makeStub(functions: [functionDeclaration]) - _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub") + _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub", isInitWithOptionalsEnabled: false) XCTAssertEqual(variableGeneratorSpy.makeCode.count, 2) XCTAssertEqual(variableGeneratorSpy.makeCode.first?.declaration.identifier, "functionNameThrowBlock") @@ -165,6 +166,27 @@ final class StubGeneratorTests: XCTestCase { "function", ]) } + + func test_givenProtocolWithOptionalVariablesAndIsInitWithOptionalsEnabled_whenGenerate_thenGenerateSpyWithMultipleInits() { + let protocolDeclaration = ProtocolDeclaration.makeStub( + variables: [ + .makeStub(), + .makeStub(type: .makeStub(isOptional: true)) + ] + ) + + _ = sut.generate(from: protocolDeclaration, nameSuffix: "Stub", isInitWithOptionalsEnabled: true) + + XCTAssertEqual(variableGeneratorSpy.makeCode.count, 2) + equal(protocolGeneratorSpy.makeProtocol.first?.content, rows: [ + "variable", + "variable", + "", + "init", + ]) + XCTAssertEqual(initGeneratorSpy.makeCode.count, 1) + XCTAssertEqual(initGeneratorSpy.makeCode[0].variables.count, 2) + } } final class FunctionNameGeneratorSpy: FunctionNameGenerator { @@ -204,17 +226,18 @@ final class FunctionNameGeneratorSpy: FunctionNameGenerator { final class InitGeneratorSpy: InitGenerator { struct MakeCode { let variables: [VarDeclaration] + let isAddingDefaultValueToOptionalsEnabled: Bool } - var makeCode = [MakeCode]() var makeCodeReturn: [String] + var makeCode = [MakeCode]() init(makeCodeReturn: [String]) { self.makeCodeReturn = makeCodeReturn } - func makeCode(with variables: [VarDeclaration]) -> [String] { - let item = MakeCode(variables: variables) + func makeCode(with variables: [VarDeclaration], isAddingDefaultValueToOptionalsEnabled: Bool) -> [String] { + let item = MakeCode(variables: variables, isAddingDefaultValueToOptionalsEnabled: isAddingDefaultValueToOptionalsEnabled) makeCode.append(item) return makeCodeReturn } diff --git a/Tests/RubiconTests/Integration/SpyIntegrationTests.swift b/Tests/RubiconTests/Integration/SpyIntegrationTests.swift index f06d639..13cb6ea 100644 --- a/Tests/RubiconTests/Integration/SpyIntegrationTests.swift +++ b/Tests/RubiconTests/Integration/SpyIntegrationTests.swift @@ -19,7 +19,7 @@ final class SpyIntegrationTests: XCTestCase { """ let sut = Rubicon() - let result = sut.makeSpy(code: code, accessLevel: .internal, indentStep: "-") + let result = sut.makeSpy(code: code, configuration: .makeStub(isInitWithOptionalsEnabled: true)) equal(string: result.first ?? "", rows: [ "final class CarSpy: VehicleSpy, Car {", @@ -55,10 +55,13 @@ final class SpyIntegrationTests: XCTestCase { "-var continueFromScreenId = [ContinueFromScreenId]()", "-var continueFromId = [ContinueFromId]()", "", - "-init(color: Int, loadReturn: Int, isFullReturn: Bool, downloadReturn: [String]) {", + "-init(name: String? = nil, color: Int, loadThrowBlock: @escaping (() throws -> Void)? = nil, loadReturn: Int, isFullReturn: Bool, downloadThrowBlock: @escaping (() throws -> Void)? = nil, downloadReturn: [String]) {", + "--self.name = name", "--self.color = color", + "--self.loadThrowBlock = loadThrowBlock", "--self.loadReturn = loadReturn", "--self.isFullReturn = isFullReturn", + "--self.downloadThrowBlock = downloadThrowBlock", "--self.downloadReturn = downloadReturn", "-}", "", @@ -107,7 +110,7 @@ final class SpyIntegrationTests: XCTestCase { """ let sut = Rubicon() - let result = sut.makeSpy(code: code, accessLevel: .internal, indentStep: "-") + let result = sut.makeSpy(code: code, configuration: .makeStub()) equal(string: result.first ?? "", rows: [ "final class CarSpy: VehicleSpy, Car {", @@ -126,3 +129,15 @@ final class SpyIntegrationTests: XCTestCase { ]) } } + +extension SpyConfiguration { + static func makeStub( + isInitWithOptionalsEnabled: Bool = false + ) -> SpyConfiguration { + SpyConfiguration( + accessLevel: .internal, + indentStep: "-", + isInitWithOptionalsEnabled: isInitWithOptionalsEnabled + ) + } +} diff --git a/Tests/RubiconTests/Integration/StubIntegrationTests.swift b/Tests/RubiconTests/Integration/StubIntegrationTests.swift index c46c9af..4e5e940 100644 --- a/Tests/RubiconTests/Integration/StubIntegrationTests.swift +++ b/Tests/RubiconTests/Integration/StubIntegrationTests.swift @@ -17,7 +17,7 @@ final class StubIntegrationTests: XCTestCase { """ let sut = Rubicon() - let result = sut.makeStub(code: code, accessLevel: .internal, indentStep: "-") + let result = sut.makeStub(code: code, configuration: .makeStub(isInitWithOptionalsEnabled: true)) equal(string: result.first ?? "", rows: [ "final class CarStub: Car {", @@ -29,10 +29,13 @@ final class StubIntegrationTests: XCTestCase { "-var downloadThrowBlock: (() throws -> Void)?", "-var downloadReturn: [String]", "", - "-init(color: Int, loadReturn: Int, isFullReturn: Bool, downloadReturn: [String]) {", + "-init(name: String? = nil, color: Int, loadThrowBlock: @escaping (() throws -> Void)? = nil, loadReturn: Int, isFullReturn: Bool, downloadThrowBlock: @escaping (() throws -> Void)? = nil, downloadReturn: [String]) {", + "--self.name = name", "--self.color = color", + "--self.loadThrowBlock = loadThrowBlock", "--self.loadReturn = loadReturn", "--self.isFullReturn = isFullReturn", + "--self.downloadThrowBlock = downloadThrowBlock", "--self.downloadReturn = downloadReturn", "-}", "", @@ -60,3 +63,15 @@ final class StubIntegrationTests: XCTestCase { ]) } } + + +extension StubConfiguration { + static func makeStub(isInitWithOptionalsEnabled: Bool = false) -> StubConfiguration { + StubConfiguration( + accessLevel: .internal, + indentStep: "-", + nameSuffix: "Stub", + isInitWithOptionalsEnabled: isInitWithOptionalsEnabled + ) + } +}