Template support for input parameters (#4)
This PR contains the work done to support input parameters for the `create` command of the executable target, and to render content dynamically for the newly-generated project. Reviewed-on: #4 Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
This commit was merged in pull request #4.
This commit is contained in:
@@ -64,6 +64,19 @@ extension FileServiceMock: FileServicing {
|
||||
}
|
||||
}
|
||||
|
||||
func createFile(at location: URL, with data: Data) async throws (FileServiceError) {
|
||||
guard let nextAction else { return }
|
||||
|
||||
switch nextAction {
|
||||
case .error(let error):
|
||||
throw error
|
||||
case let .createFile(location, data):
|
||||
try await spy?.createFile(at: location, with: data)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func createFolder(at location: URL) async throws (FileServiceError) {
|
||||
guard let nextAction else { return }
|
||||
|
||||
@@ -127,6 +140,7 @@ private extension FileServiceMock {
|
||||
extension FileServiceMock {
|
||||
enum Action {
|
||||
case copyFile(URL, URL)
|
||||
case createFile(URL, Data)
|
||||
case createFolder(URL)
|
||||
case deleteItem(URL)
|
||||
case error(FileServiceError)
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import ColibriLibrary
|
||||
import Foundation
|
||||
|
||||
final class TemplateServiceMock {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
private var actions: [Action] = []
|
||||
|
||||
private weak var spy: TemplateServiceSpy?
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
init(
|
||||
action: Action,
|
||||
spy: TemplateServiceSpy? = nil
|
||||
) {
|
||||
self.actions.append(action)
|
||||
self.spy = spy
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - TemplateServicing
|
||||
|
||||
extension TemplateServiceMock: TemplateServicing {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
@discardableResult
|
||||
func render(_ object: Any, on template: String) async throws(TemplateServiceError) -> String {
|
||||
guard let nextAction else { return .empty }
|
||||
|
||||
switch nextAction {
|
||||
case .error(let error):
|
||||
throw error
|
||||
case .render(let content):
|
||||
try await spy?.render(object, on: template)
|
||||
return content
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private extension TemplateServiceMock {
|
||||
|
||||
// MARK: Computed
|
||||
|
||||
var nextAction: Action? {
|
||||
guard !actions.isEmpty else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return actions.removeFirst()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
extension TemplateServiceMock {
|
||||
enum Action {
|
||||
case error(TemplateServiceError)
|
||||
case render(String)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - String+Constants
|
||||
|
||||
private extension String {
|
||||
static let empty = ""
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import ColibriLibrary
|
||||
import Foundation
|
||||
|
||||
final class TerminalServiceMock {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
private var actions: [Action] = []
|
||||
|
||||
private weak var spy: TerminalServiceSpy?
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
init(
|
||||
action: Action,
|
||||
spy: TerminalServiceSpy? = nil
|
||||
) {
|
||||
self.actions.append(action)
|
||||
self.spy = spy
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - TerminalServicing
|
||||
|
||||
extension TerminalServiceMock: TerminalServicing {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
func run(_ executableURL: URL, arguments: [String]) async throws (TerminalServiceError) -> String {
|
||||
guard let nextAction else { return .empty }
|
||||
|
||||
switch nextAction {
|
||||
case .error(let error):
|
||||
throw error
|
||||
case let .run(executableURL, arguments):
|
||||
try await spy?.run(executableURL, arguments: arguments)
|
||||
return .empty
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private extension TerminalServiceMock {
|
||||
|
||||
// MARK: Computed
|
||||
|
||||
var nextAction: Action? {
|
||||
guard !actions.isEmpty else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return actions.removeFirst()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
extension TerminalServiceMock {
|
||||
enum Action {
|
||||
case error(TerminalServiceError)
|
||||
case run(URL, [String])
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - String+Constants
|
||||
|
||||
private extension String {
|
||||
static let empty = ""
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import ColibriLibrary
|
||||
import Foundation
|
||||
|
||||
@testable import ColibriLibrary
|
||||
|
||||
final class FileServiceSpy {
|
||||
|
||||
// MARK: Properties
|
||||
@@ -22,6 +21,10 @@ extension FileServiceSpy: FileServicing {
|
||||
actions.append(.fileCopied(source, destination))
|
||||
}
|
||||
|
||||
func createFile(at location: URL, with data: Data) async throws (FileServiceError) {
|
||||
actions.append(.fileCreated(location, data))
|
||||
}
|
||||
|
||||
func createFolder(at location: URL) async throws (FileServiceError) {
|
||||
actions.append(.folderCreated(location))
|
||||
}
|
||||
@@ -43,6 +46,7 @@ extension FileServiceSpy: FileServicing {
|
||||
|
||||
extension FileServiceSpy {
|
||||
enum Action: Equatable {
|
||||
case fileCreated(_ location: URL, _ data: Data)
|
||||
case fileCopied(_ source: URL, _ destination: URL)
|
||||
case folderCreated(_ location: URL)
|
||||
case itemDeleted(_ location: URL)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import ColibriLibrary
|
||||
|
||||
final class TemplateServiceSpy {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
private(set) var actions: [Action] = []
|
||||
|
||||
}
|
||||
|
||||
// MARK: - TemplateServicing
|
||||
|
||||
extension TemplateServiceSpy: TemplateServicing {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
@discardableResult
|
||||
func render(_ object: Any, on template: String) async throws (TemplateServiceError) -> String {
|
||||
actions.append(.rendered(object, template))
|
||||
|
||||
return .content
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
extension TemplateServiceSpy {
|
||||
enum Action {
|
||||
case rendered(_ object: Any, _ template: String)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - String+Constants
|
||||
|
||||
private extension String {
|
||||
static let content = ""
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import ColibriLibrary
|
||||
import Foundation
|
||||
|
||||
final class TerminalServiceSpy {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
private(set) var actions: [Action] = []
|
||||
|
||||
}
|
||||
|
||||
// MARK: - TerminalServicing
|
||||
|
||||
extension TerminalServiceSpy: TerminalServicing {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
@discardableResult
|
||||
func run(_ executableURL: URL, arguments: [String]) async throws(TerminalServiceError) -> String {
|
||||
actions.append(.ran(executableURL, arguments))
|
||||
|
||||
return .content
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
extension TerminalServiceSpy {
|
||||
enum Action: Equatable {
|
||||
case ran(_ executableURL: URL, _ arguments: [String])
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - String+Constants
|
||||
|
||||
private extension String {
|
||||
static let content = ""
|
||||
}
|
||||
Reference in New Issue
Block a user