diff --git a/Binaries/PrefireBinary.artifactbundle/prefire-3.0.3-macos/bin/prefire b/Binaries/PrefireBinary.artifactbundle/prefire-3.0.3-macos/bin/prefire index e3cce35..e246c93 100755 Binary files a/Binaries/PrefireBinary.artifactbundle/prefire-3.0.3-macos/bin/prefire and b/Binaries/PrefireBinary.artifactbundle/prefire-3.0.3-macos/bin/prefire differ diff --git a/PrefireExecutable/Sources/prefire/Commands/Playbook/GeneratePlaybookCommand.swift b/PrefireExecutable/Sources/prefire/Commands/Playbook/GeneratePlaybookCommand.swift index 36010fd..51b3eab 100644 --- a/PrefireExecutable/Sources/prefire/Commands/Playbook/GeneratePlaybookCommand.swift +++ b/PrefireExecutable/Sources/prefire/Commands/Playbook/GeneratePlaybookCommand.swift @@ -49,11 +49,11 @@ enum GeneratePlaybookCommand { static let macroPreviewBodies = "macroPreviewBodies" } - static func run(_ options: GeneratedPlaybookOptions) throws { + static func run(_ options: GeneratedPlaybookOptions) async throws { let task = Process() task.executableURL = URL(filePath: options.sourcery) - let rawArguments = makeArguments(for: options) + let rawArguments = await makeArguments(for: options) let yamlContent = YAMLParser().string(from: rawArguments) let filePath = (options.cacheBasePath?.appending("/") ?? FileManager.default.temporaryDirectory.path()) .appending(Constants.configFileName) @@ -66,10 +66,10 @@ enum GeneratePlaybookCommand { task.waitUntilExit() } - static func makeArguments(for options: GeneratedPlaybookOptions) -> [String: Any?] { + static func makeArguments(for options: GeneratedPlaybookOptions) async -> [String: Any?] { // Works with `#Preview` macro #if swift(>=5.9) - let previewBodies = PreviewLoader.loadMacroPreviewBodies(for: options.sources, defaultEnabled: options.previewDefaultEnabled) + let previewBodies = await PreviewLoader.loadMacroPreviewBodies(for: options.sources, defaultEnabled: options.previewDefaultEnabled) #else let previewBodies: String? = nil #endif diff --git a/PrefireExecutable/Sources/prefire/Commands/Playbook/Playbook.swift b/PrefireExecutable/Sources/prefire/Commands/Playbook/Playbook.swift index 67e120d..a36f45c 100644 --- a/PrefireExecutable/Sources/prefire/Commands/Playbook/Playbook.swift +++ b/PrefireExecutable/Sources/prefire/Commands/Playbook/Playbook.swift @@ -2,7 +2,7 @@ import ArgumentParser import Foundation extension Prefire { - struct Playbook: ParsableCommand { + struct Playbook: AsyncParsableCommand { static let configuration = CommandConfiguration(abstract: "Generate Playbook") @Argument(help: "Paths to a source swift files or directories.") @@ -25,10 +25,10 @@ extension Prefire { @Flag(help: "Display full info") var verbose = false - func run() throws { + func run() async throws { Logger.verbose = verbose - try GeneratePlaybookCommand.run( + try await GeneratePlaybookCommand.run( GeneratedPlaybookOptions( sourcery: sourcery, targetPath: targetPath, diff --git a/PrefireExecutable/Sources/prefire/Commands/Tests/GenerateTestsCommand.swift b/PrefireExecutable/Sources/prefire/Commands/Tests/GenerateTestsCommand.swift index 2ebb9be..354af0d 100644 --- a/PrefireExecutable/Sources/prefire/Commands/Tests/GenerateTestsCommand.swift +++ b/PrefireExecutable/Sources/prefire/Commands/Tests/GenerateTestsCommand.swift @@ -77,11 +77,11 @@ enum GenerateTestsCommand { static let previewsMacros = "previewsMacros" } - static func run(_ options: GeneratedTestsOptions) throws { + static func run(_ options: GeneratedTestsOptions) async throws { let task = Process() task.executableURL = URL(filePath: options.sourcery) - let rawArguments = makeArguments(for: options) + let rawArguments = await makeArguments(for: options) let yamlContent = YAMLParser().string(from: rawArguments) let filePath = (options.cacheBasePath?.appending("/") ?? FileManager.default.temporaryDirectory.path()) .appending(Constants.configFileName) @@ -94,7 +94,7 @@ enum GenerateTestsCommand { task.waitUntilExit() } - static func makeArguments(for options: GeneratedTestsOptions) -> [String: Any?] { + static func makeArguments(for options: GeneratedTestsOptions) async -> [String: Any?] { let sources = options.sources let output = options.output ?? FileManager.default.currentDirectoryPath.appending("/\(Constants.snapshotFileName).generated.swift") let snapshotOutput = options.testTargetPath?.appending("/\(Constants.snapshotFileName).swift") @@ -114,7 +114,7 @@ enum GenerateTestsCommand { // Works with `#Preview` macro #if swift(>=5.9) - let previewBodies = PreviewLoader.loadPreviewBodies(for: sources, defaultEnabled: options.prefireEnabledMarker) + let previewBodies = await PreviewLoader.loadPreviewBodies(for: sources, defaultEnabled: options.prefireEnabledMarker) #else let previewBodies: String? = nil #endif diff --git a/PrefireExecutable/Sources/prefire/Commands/Tests/Tests.swift b/PrefireExecutable/Sources/prefire/Commands/Tests/Tests.swift index a1875a5..feab4b1 100644 --- a/PrefireExecutable/Sources/prefire/Commands/Tests/Tests.swift +++ b/PrefireExecutable/Sources/prefire/Commands/Tests/Tests.swift @@ -2,7 +2,7 @@ import ArgumentParser import Foundation extension Prefire { - struct Tests: ParsableCommand { + struct Tests: AsyncParsableCommand { static let configuration = CommandConfiguration(abstract: "Generate Snapshot/Accessibility Tests") @Argument(help: "Paths to a source swift files or directories.") @@ -34,10 +34,10 @@ extension Prefire { @Flag(help: "Display full info") var verbose = false - func run() throws { + func run() async throws { Logger.verbose = verbose - try GenerateTestsCommand.run( + try await GenerateTestsCommand.run( GeneratedTestsOptions( sourcery: sourcery, target: target, diff --git a/PrefireExecutable/Sources/prefire/Config/Config.swift b/PrefireExecutable/Sources/prefire/Config/Config.swift index 27a557c..66ef2d7 100644 --- a/PrefireExecutable/Sources/prefire/Config/Config.swift +++ b/PrefireExecutable/Sources/prefire/Config/Config.swift @@ -1,136 +1,58 @@ import Foundation -private enum Constants { - static let separtor = ":" -} - struct Config { - struct TestsConfig { - var target: String? - var sources: [String]? - var testFilePath: String? - var template: String? - var device: String? - var osVersion: String? - var snapshotDevices: [String]? - var previewDefaultEnabled: Bool? - var imports: [String]? - var testableImports: [String]? - } - - struct PlaybookConfig { - var targetPath: String? - var template: String? - var previewDefaultEnabled: Bool? - var imports: [String]? - var testableImports: [String]? - } - var tests = TestsConfig() var playbook = PlaybookConfig() - init?(from configDataString: String, env: [String : String]) { - var isTestConfig = false - var isPlaybookConfig = false - - let lines = configDataString.components(separatedBy: .newlines) - - for index in 0.. Config? { let possibleConfigPaths = ConfigPathBuilder.possibleConfigPaths(for: configPath, testTargetPath: testTargetPath) @@ -141,66 +63,11 @@ extension Config { Logger.print("🟢 The '.prefire' file is used on the path: \(configUrl.path)") - if let configuration = Config(from: configDataString, env: env) { - return configuration - } + return ConfigDecoder().decode(from: configDataString, env: env) } - Logger.print("🟡 The '.prefire' file was not found by paths:" + possibleConfigPaths.map({ "\n - " + $0 }).reduce("", +)) + Logger.print("🟡 The '.prefire' file was not found by paths:" + possibleConfigPaths.map({ "\n - " + $0 }).joined()) return nil } - - // MARK: - Private - - private static func getValues(from components: [String], lines: [String], key: Keys, env: [String : String]) -> [String]? { - guard (components.first?.hasSuffix("- \(key.rawValue)") ?? false) == true, components.last?.isEmpty == true else { return nil } - - var values = [String]() - - for line in lines[1.. String? { - guard components.first?.hasSuffix("- \(key.rawValue)") == true else { return nil } - - var value = components.last? - .trimmingCharacters(in: CharacterSet.whitespaces) - .replacingOccurrences(of: "\"", with: "") - - // Check and replace if the value contains a key formatted as "${key}" - if let key = value?.findKey(), let envValue = env[key] { - value = value?.replacingOccurrences(of: "${\(key)}", with: envValue) - } - - return value - } -} - -private extension String { - /// Extract the key enclosed within "${}" from a string - /// - Returns: Key - func findKey() -> String? { - guard contains("${") else { return nil } - - return components(separatedBy: "${").last?.components(separatedBy: "}").first - } } diff --git a/PrefireExecutable/Sources/prefire/Config/ConfigDecoder.swift b/PrefireExecutable/Sources/prefire/Config/ConfigDecoder.swift new file mode 100644 index 0000000..8106d9f --- /dev/null +++ b/PrefireExecutable/Sources/prefire/Config/ConfigDecoder.swift @@ -0,0 +1,132 @@ +import Foundation + +private enum Constants { + static let separtor = ":" +} + +final class ConfigDecoder { + func decode(from configDataString: String, env: [String : String]) -> Config { + var config: Config = Config() + + var currentSection: Config.CodingKeys? = nil + + let lines = configDataString.components(separatedBy: .newlines) + + for index in 0.., env: [String : String]) { + var components = components + let keyString = components.removeFirst().replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "-", with: "") + + guard let key = TestsConfig.CodingKeys(rawValue: keyString) else { return } + + switch key { + case .target: + config.tests.target = getValue(from: components.last, env: env) + case .sources: + config.tests.sources = getValues(from: components, lines: lines, env: env) + case .testFilePath: + config.tests.testFilePath = getValue(from: components.last, env: env) + case .template: + config.tests.template = getValue(from: components.last, env: env) + case .device: + config.tests.device = getValue(from: components.last, env: env) + case .osVersion: + config.tests.osVersion = getValue(from: components.last, env: env) + case .snapshotDevices: + config.tests.snapshotDevices = getValues(from: components, lines: lines, env: env) + case .previewDefaultEnabled: + config.tests.previewDefaultEnabled = getValue(from: components.last, env: env) == "true" + case .imports: + config.tests.imports = getValues(from: components, lines: lines, env: env) + case .testableImports: + config.tests.testableImports = getValues(from: components, lines: lines, env: env) + } + } + + private func handlePlaybookConfig(config: inout Config, components: [String], lines: ArraySlice, env: [String : String]) { + var components = components + let keyString = components.removeFirst().replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "-", with: "") + + guard let key = PlaybookConfig.CodingKeys(rawValue: keyString) else { return } + + switch key { + case .targetPath: + config.playbook.targetPath = getValue(from: components.last, env: env) + case .template: + config.playbook.template = getValue(from: components.last, env: env) + case .previewDefaultEnabled: + config.playbook.previewDefaultEnabled = getValue(from: components.last, env: env) == "true" + case .imports: + config.playbook.imports = getValues(from: components, lines: lines, env: env) + case .testableImports: + config.playbook.testableImports = getValues(from: components, lines: lines, env: env) + } + } + + private func getValues(from components: [String], lines: ArraySlice, env: [String : String]) -> [String]? { + guard components.last?.isEmpty == true else { return nil } + + var values = [String]() + + for line in lines[lines.startIndex + 1.. String? { + var value = component?.trimmingCharacters(in: .whitespaces).replacingOccurrences(of: "\"", with: "") + + // Check and replace if the value contains a key formatted as "${key}" + if let key = value?.findKey(), let envValue = env[key] { + value = value?.replacingOccurrences(of: "${\(key)}", with: envValue) + } + + return value + } +} + +private extension String { + /// Extract the key enclosed within "${}" from a string + /// - Returns: Key + func findKey() -> String? { + guard contains("${") else { return nil } + + return components(separatedBy: "${").last?.components(separatedBy: "}").first + } +} diff --git a/PrefireExecutable/Sources/prefire/Extensions/FileManager+FileList.swift b/PrefireExecutable/Sources/prefire/Extensions/FileManager+FileList.swift index 07c79ba..7aee24c 100644 --- a/PrefireExecutable/Sources/prefire/Extensions/FileManager+FileList.swift +++ b/PrefireExecutable/Sources/prefire/Extensions/FileManager+FileList.swift @@ -3,27 +3,18 @@ import Foundation extension FileManager { /// This function recursively lists all files with a ".swift" extension within the specified directory path. /// - Parameter path: The directory path to list files from. - /// - Returns: An array of file paths with the extension ".swift" within the specified directory path. - func listFiles(atPath path: String) -> [String] { - do { - let contents = try contentsOfDirectory(atPath: path) - var paths: [String] = [] + /// - Parameter extension: File extension + /// - Returns: An array of file paths with the extension within the specified directory path. + func listFiles(atPath path: String, withExtension extension: String) -> [String] { + var files = [String]() - for item in contents { - let itemPath = "\(path)/\(item)" - if item.hasSuffix(".swift") { - paths.append(itemPath) - } - - if (try? contentsOfDirectory(atPath: itemPath)) != nil { - paths += listFiles(atPath: itemPath) + if let enumerator = enumerator(atPath: path) { + for case let file as String in enumerator { + if file.hasSuffix(`extension`) { + files.append(file) } } - - return paths - } catch { - Logger.print("Error: \(error)") - return [] } + return files } } diff --git a/PrefireExecutable/Sources/prefire/Previews/PreviewLoader+Playbook.swift b/PrefireExecutable/Sources/prefire/Previews/PreviewLoader+Playbook.swift index 56995db..bd0d79d 100644 --- a/PrefireExecutable/Sources/prefire/Previews/PreviewLoader+Playbook.swift +++ b/PrefireExecutable/Sources/prefire/Previews/PreviewLoader+Playbook.swift @@ -9,8 +9,8 @@ extension PreviewLoader { /// - sources: Paths to the processed files with #Preview /// - defaultEnabled: Automatic view addition is enabled /// - Returns: Ready-made code with a PreviewModel array for embedding in a template file - static func loadMacroPreviewBodies(for sources: [String], defaultEnabled: Bool) -> String? { - guard let findedBodies = loadRawPreviewBodies(for: sources, defaultEnabled: defaultEnabled) else { return nil } + static func loadMacroPreviewBodies(for sources: [String], defaultEnabled: Bool) async -> String? { + guard let findedBodies = await loadRawPreviewBodies(for: sources, defaultEnabled: defaultEnabled) else { return nil } let previewModels = findedBodies .map { RawPreviewModel(from: $0.value, filename: $0.key, lineSymbol: previewSpaces).previewModel } diff --git a/PrefireExecutable/Sources/prefire/Previews/PreviewLoader+Tests.swift b/PrefireExecutable/Sources/prefire/Previews/PreviewLoader+Tests.swift index 081380b..d5096b6 100644 --- a/PrefireExecutable/Sources/prefire/Previews/PreviewLoader+Tests.swift +++ b/PrefireExecutable/Sources/prefire/Previews/PreviewLoader+Tests.swift @@ -5,8 +5,8 @@ extension PreviewLoader { private static let yamlSettings = "|-4\n\n" private static let previewSpaces = " " - static func loadPreviewBodies(for sources: [String], defaultEnabled: Bool) -> String? { - guard let findedBodies = loadRawPreviewBodies(for: sources, defaultEnabled: defaultEnabled) else { return nil } + static func loadPreviewBodies(for sources: [String], defaultEnabled: Bool) async -> String? { + guard let findedBodies = await loadRawPreviewBodies(for: sources, defaultEnabled: defaultEnabled) else { return nil } let result = findedBodies .sorted(by: { $0.key > $1.key }) diff --git a/PrefireExecutable/Sources/prefire/Previews/PreviewLoader.swift b/PrefireExecutable/Sources/prefire/Previews/PreviewLoader.swift index 87e7532..bdeee7e 100644 --- a/PrefireExecutable/Sources/prefire/Previews/PreviewLoader.swift +++ b/PrefireExecutable/Sources/prefire/Previews/PreviewLoader.swift @@ -15,29 +15,40 @@ enum PreviewLoader { /// - sources: Paths to a source swift files or directories. /// - defaultEnabled: Whether automatic view inclusion should be allowed. Default value is true. /// - Returns: A dictionary containing the preview bodies for the sources, with file names as keys and preview bodies as values - static func loadRawPreviewBodies(for sources: [String], defaultEnabled: Bool) -> [String: String]? { + static func loadRawPreviewBodies(for sources: [String], defaultEnabled: Bool) async -> [String: String]? { var previewBodyDictionary = [String: String]() - - for url in sources.compactMap(URL.init(string:)) { - do { - guard !url.isDirectory else { - let urls = FileManager.default.listFiles(atPath: url.path()) - let bodies = loadRawPreviewBodies(for: urls, defaultEnabled: defaultEnabled) ?? [:] - previewBodyDictionary.merge(bodies) { _, new in new } - continue - } - - let content = try String(contentsOfFile: url.path) - guard !content.isEmpty, content.contains(Constants.previewMarker) else { continue } - - if let previewBodies = previewBodies(from: content, defaultEnabled: defaultEnabled) { - let fileName = url.fileName - previewBodies.enumerated().forEach { index, previewBody in - previewBodyDictionary["\(fileName)_\(index)"] = previewBody + let fileManager = FileManager.default + + await withTaskGroup(of: [String: String]?.self) { group in + for url in sources.compactMap(URL.init(string:)) { + group.addTask { + do { + if url.isDirectory { + let files = fileManager.listFiles(atPath: url.path(), withExtension: ".swift") + return await loadRawPreviewBodies(for: files, defaultEnabled: defaultEnabled) + } + + let content = try await readFile(atPath: url.path) + guard content.range(of: Constants.previewMarker) != nil else { return nil } + + var localPreviewBodyDictionary = [String: String]() + if let previewBodies = previewBodies(from: content, defaultEnabled: defaultEnabled) { + let fileName = url.fileName + previewBodies.enumerated().forEach { index, previewBody in + localPreviewBodyDictionary["\(fileName)_\(index)"] = previewBody + } + } + return localPreviewBodyDictionary + } catch { + Logger.print("⚠️ Cannot load file with Preview macro at path: \(url.path)") + return nil } } - } catch { - Logger.print("⚠️ Cannot load file with Preview macro at path: \(url.path)") + } + + for await result in group { + guard let bodies = result else { continue } + previewBodyDictionary.merge(bodies) { _, new in new } } } @@ -51,26 +62,31 @@ enum PreviewLoader { /// - defaultEnabled: Whether automatic view inclusion should be allowed. Default value is true. /// - Returns: An array representing the results of the macro preview without the initial `#Preview` and final `}`. static func previewBodies(from content: String, defaultEnabled: Bool) -> [String]? { + let lines = content.split(separator: "\n", omittingEmptySubsequences: false) var previewBodies: [String] = [] - let lines = content.components(separatedBy: .newlines) - - var result = "" + var currentBody: String = "" var previewWasFound = false var viewMustBeLoaded = defaultEnabled - - var openingBraceCount = 0 - var closingBraceCount = 0 + var braceBalance = 0 for line in lines { if line.hasPrefix(Constants.previewMarker) { previewWasFound = true + currentBody = "" + braceBalance = 0 } guard previewWasFound else { continue } - openingBraceCount += line.filter { $0 == Constants.openingBrace }.count - closingBraceCount += line.filter { $0 == Constants.closingBrace }.count + braceBalance += line.reduce(0) { (count, char) in + if char == Constants.openingBrace { + return count + 1 + } else if char == Constants.closingBrace { + return count - 1 + } + return count + } if defaultEnabled { if line.hasSuffix(Constants.prefireDisableMarker) { @@ -80,21 +96,22 @@ enum PreviewLoader { viewMustBeLoaded = line.hasSuffix(Constants.prefireEnabledMarker) } - result += (line + "\n") + currentBody.append(String(line) + "\n") - if openingBraceCount == closingBraceCount { - if !result.isEmpty, viewMustBeLoaded { - previewBodies.append(result) + if braceBalance == 0 { + if !currentBody.isEmpty, viewMustBeLoaded { + previewBodies.append(currentBody) } - result = "" previewWasFound = false viewMustBeLoaded = defaultEnabled - openingBraceCount = .zero - closingBraceCount = .zero } } return previewBodies.isEmpty ? nil : previewBodies } + + static private func readFile(atPath path: String) async throws -> String { + return try String(contentsOfFile: path) + } } diff --git a/PrefireExecutable/Tests/PrefireTests/ConfigDecoderTests.swift b/PrefireExecutable/Tests/PrefireTests/ConfigDecoderTests.swift new file mode 100644 index 0000000..7290d3a --- /dev/null +++ b/PrefireExecutable/Tests/PrefireTests/ConfigDecoderTests.swift @@ -0,0 +1,51 @@ +import Foundation +@testable import prefire +import XCTest + +class ConfigDecoderTests: XCTestCase { + private let prefireConfigString = """ + test_configuration: + - target: PrefireExample + - test_file_path: ${TARGET_DIR}/PrefireExampleTests/PreviewTests.generated.swift + - template_file_path: CustomPreviewTests.stencil + - simulator_device: "iPhone15,2" + - required_os: 17 + - snapshot_devices: + - iPhone 15 + - iPad + - preview_default_enabled: true + - imports: + - UIKit + - SwiftUI + - testable_imports: + - Prefire + playbook_configuration: + - template_file_path: CustomModels.stencil + - imports: + - UIKit + - Foundation + - testable_imports: + - SwiftUI + - preview_default_enabled: false + """ + + private let env = ["TARGET_DIR":"/User/Tests"] + + func test_successDecodeConfig() { + let config = ConfigDecoder().decode(from: prefireConfigString, env: env) + + XCTAssertEqual(config.tests.target, "PrefireExample") + XCTAssertEqual(config.tests.testFilePath, "/User/Tests/PrefireExampleTests/PreviewTests.generated.swift") + XCTAssertEqual(config.tests.template, "CustomPreviewTests.stencil") + XCTAssertEqual(config.tests.device, "iPhone15,2") + XCTAssertEqual(config.tests.osVersion, "17") + XCTAssertEqual(config.tests.snapshotDevices, ["iPhone 15", "iPad"]) + XCTAssertEqual(config.tests.previewDefaultEnabled, true) + XCTAssertEqual(config.tests.imports, ["UIKit", "SwiftUI"]) + XCTAssertEqual(config.tests.testableImports, ["Prefire"]) + XCTAssertEqual(config.playbook.imports, ["UIKit", "Foundation"]) + XCTAssertEqual(config.playbook.testableImports, ["SwiftUI"]) + XCTAssertEqual(config.playbook.template, "CustomModels.stencil") + XCTAssertEqual(config.playbook.previewDefaultEnabled, false) + } +} diff --git a/PrefireExecutable/Tests/PrefireTests/ConfigTests.swift b/PrefireExecutable/Tests/PrefireTests/ConfigTests.swift deleted file mode 100644 index c5adc18..0000000 --- a/PrefireExecutable/Tests/PrefireTests/ConfigTests.swift +++ /dev/null @@ -1,49 +0,0 @@ -import Foundation -@testable import prefire -import XCTest - -class ConfigTests: XCTestCase { - private let prefireConfigString = """ - test_configuration: - - target: PrefireExample - - test_file_path: ${TARGET_DIR}/PrefireExampleTests/PreviewTests.generated.swift - - template_file_path: CustomPreviewTests.stencil - - simulator_device: "iPhone15,2" - - required_os: 17 - - snapshot_devices: - - iPhone 15 - - iPad - - preview_default_enabled: true - - imports: - - UIKit - - SwiftUI - - testable_imports: - - Prefire - playbook_configuration: - - template_file_path: CustomModels.stencil - - imports: - - UIKit - - Foundation - - testable_imports: - - SwiftUI - - preview_default_enabled: false - """ - - func test_successCreateConfig() { - let config = Config(from: prefireConfigString, env: ["TARGET_DIR":"/User/Tests"]) - - XCTAssertEqual(config?.tests.target, "PrefireExample") - XCTAssertEqual(config?.tests.testFilePath, "/User/Tests/PrefireExampleTests/PreviewTests.generated.swift") - XCTAssertEqual(config?.tests.template, "CustomPreviewTests.stencil") - XCTAssertEqual(config?.tests.device, "iPhone15,2") - XCTAssertEqual(config?.tests.osVersion, "17") - XCTAssertEqual(config?.tests.snapshotDevices, ["iPhone 15", "iPad"]) - XCTAssertEqual(config?.tests.previewDefaultEnabled, true) - XCTAssertEqual(config?.tests.imports, ["UIKit", "SwiftUI"]) - XCTAssertEqual(config?.tests.testableImports, ["Prefire"]) - XCTAssertEqual(config?.playbook.imports, ["UIKit", "Foundation"]) - XCTAssertEqual(config?.playbook.testableImports, ["SwiftUI"]) - XCTAssertEqual(config?.playbook.template, "CustomModels.stencil") - XCTAssertEqual(config?.playbook.previewDefaultEnabled, false) - } -} diff --git a/PrefireExecutable/Tests/PrefireTests/FileManagerListFilesTest.swift b/PrefireExecutable/Tests/PrefireTests/FileManagerListFilesTest.swift new file mode 100644 index 0000000..83a5ae7 --- /dev/null +++ b/PrefireExecutable/Tests/PrefireTests/FileManagerListFilesTest.swift @@ -0,0 +1,17 @@ +import Foundation +@testable import prefire +import XCTest + +class FileManagerListFilesTest: XCTestCase { + let sourceDirectoryURL = URL(fileURLWithPath: #file) + .deletingLastPathComponent() + .deletingLastPathComponent() + .deletingLastPathComponent() + .appendingPathComponent("Binaries") + + func testListFiles() { + let files = FileManager.default.listFiles(atPath: sourceDirectoryURL.path(), withExtension: "") + + XCTAssertEqual(files.count, 7) + } +} diff --git a/PrefireExecutable/Tests/PrefireTests/GenerateTestsCommandTest.swift b/PrefireExecutable/Tests/PrefireTests/GenerateTestsCommandTest.swift index 29a209b..5f6edc7 100644 --- a/PrefireExecutable/Tests/PrefireTests/GenerateTestsCommandTest.swift +++ b/PrefireExecutable/Tests/PrefireTests/GenerateTestsCommandTest.swift @@ -22,7 +22,7 @@ class GenerateTestsCommandTests: XCTestCase { ) } - func test_makeArguments_sources() { + func test_makeArguments_sources() async { options.sources = ["some/sources"] let expectedArguments = [ "output": options.output, @@ -41,12 +41,12 @@ class GenerateTestsCommandTests: XCTestCase { ], ] as [String: Any?] - let arguments = GenerateTestsCommand.makeArguments(for: options) + let arguments = await GenerateTestsCommand.makeArguments(for: options) XCTAssertEqual(YAMLParser().string(from: arguments), YAMLParser().string(from: expectedArguments)) } - func test_makeArguments_snapshot_devices() { + func test_makeArguments_snapshot_devices() async { options.snapshotDevices = ["iPhone 15", "iPad"] options.sources = ["some/sources", "some/other/sources"] @@ -61,7 +61,7 @@ class GenerateTestsCommandTests: XCTestCase { ] ] as [String: Any?] - let arguments = GenerateTestsCommand.makeArguments(for: options) + let arguments = await GenerateTestsCommand.makeArguments(for: options) XCTAssertEqual(YAMLParser().string(from: arguments), YAMLParser().string(from: expectedArguments)) } diff --git a/PrefireExecutable/Tests/PrefireTests/PreviewLoaderTests.swift b/PrefireExecutable/Tests/PrefireTests/PreviewLoaderTests.swift index f12e758..538e976 100644 --- a/PrefireExecutable/Tests/PrefireTests/PreviewLoaderTests.swift +++ b/PrefireExecutable/Tests/PrefireTests/PreviewLoaderTests.swift @@ -10,9 +10,9 @@ class PreviewLoaderTests: XCTestCase { let source = #file - func test_loadRawPreviewBodiesDefaultEnable() { + func test_loadRawPreviewBodiesDefaultEnable() async { #if swift(>=5.9) - let bodies = PreviewLoader.loadRawPreviewBodies(for: [source], defaultEnabled: true) + let bodies = await PreviewLoader.loadRawPreviewBodies(for: [source], defaultEnabled: true) XCTAssertEqual(bodies?.count, 2) XCTAssertEqual(bodies?["PreviewLoaderTests_0"], previewRepresentations[0]) @@ -20,9 +20,9 @@ class PreviewLoaderTests: XCTestCase { #endif } - func test_loadRawPreviewBodiesDefaultDisabled() { + func test_loadRawPreviewBodiesDefaultDisabled() async { #if swift(>=5.9) - let bodies = PreviewLoader.loadRawPreviewBodies(for: [source], defaultEnabled: false) + let bodies = await PreviewLoader.loadRawPreviewBodies(for: [source], defaultEnabled: false) XCTAssertEqual(bodies?.count, 1) XCTAssertEqual(bodies?["PreviewLoaderTests_0"], previewRepresentations[1])