Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions Sources/SwiftMutationTesting/Execution/MutantExecutor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,31 @@ struct MutantExecutor: Sendable {
private func buildArtifact(sandbox: Sandbox, deps: ExecutionDeps) async throws -> BuildArtifact? {
await deps.reporter.report(.buildStarted)
let start = Date()

guard case .xcode(let scheme, let destination) = configuration.build.projectType else {
return nil
}

do {
let artifact = try await BuildStage(launcher: deps.launcher).build(
let stage = BuildStage(launcher: deps.launcher)

switch configuration.build.projectType {
case .xcode(let scheme, let destination):
do {
let artifact = try await stage.build(
sandbox: sandbox,
scheme: scheme,
destination: destination,
timeout: configuration.build.timeout
)
await deps.reporter.report(.buildFinished(duration: Date().timeIntervalSince(start)))
return artifact
} catch BuildError.compilationFailed {
return nil
}

case .spm:
let artifact = try await stage.buildSPM(
sandbox: sandbox,
scheme: scheme,
destination: destination,
testTarget: configuration.build.testTarget,
timeout: configuration.build.timeout
)
await deps.reporter.report(.buildFinished(duration: Date().timeIntervalSince(start)))
return artifact
} catch BuildError.compilationFailed {
return nil
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,48 @@ struct MutantExecutorTests {
#expect(incompatibleResult?.status == .unviable)
}

@Test("Given SPM project type and schematizable mutants, when execute called, then returns unviable")
func spmSchematizableMutantsAreUnviable() async throws {
let dir = try FileHelpers.makeTemporaryDirectory()
defer { FileHelpers.cleanup(dir) }

let sourceFile = dir.appendingPathComponent("Foo.swift")
try "let x = true".write(to: sourceFile, atomically: true, encoding: .utf8)

let executor = MutantExecutor(
configuration: makeConfigurationSPM(projectPath: dir.path),
launcher: MockProcessLauncher(exitCode: 0)
)
let mutant = makeMutant(id: "m0", filePath: sourceFile.path, isSchematizable: true)
let input = makeInputSPM(
projectPath: dir.path,
schematizedFiles: [SchematizedFile(originalPath: sourceFile.path, schematizedContent: "let x = false")],
mutants: [mutant]
)

let results = try await executor.execute(input)

#expect(results.count == 1)
#expect(results[0].status == .unviable)
}

@Test("Given SPM project type and build failure, when execute called, then throws compilationFailed")
func spmBuildFailureThrows() async throws {
let dir = try FileHelpers.makeTemporaryDirectory()
defer { FileHelpers.cleanup(dir) }

let executor = MutantExecutor(
configuration: makeConfigurationSPM(projectPath: dir.path),
launcher: MockProcessLauncher(exitCode: 1)
)
let mutant = makeMutant(id: "m0", filePath: "/tmp/Foo.swift", isSchematizable: true)
let input = makeInputSPM(projectPath: dir.path, mutants: [mutant])

await #expect(throws: BuildError.compilationFailed) {
try await executor.execute(input)
}
}

private func makeConfiguration(
projectPath: String,
noCache: Bool = false,
Expand All @@ -237,6 +279,15 @@ struct MutantExecutorTests {
)
}

private func makeConfigurationSPM(projectPath: String) -> RunnerConfiguration {
RunnerConfiguration(
projectPath: projectPath,
build: .init(projectType: .spm, timeout: 60, concurrency: 1, noCache: false),
reporting: .init(quiet: true),
filter: .init(excludePatterns: [], operators: [])
)
}

private func makeInput(
projectPath: String,
schematizedFiles: [SchematizedFile] = [],
Expand All @@ -254,6 +305,23 @@ struct MutantExecutorTests {
)
}

private func makeInputSPM(
projectPath: String,
schematizedFiles: [SchematizedFile] = [],
mutants: [MutantDescriptor] = []
) -> RunnerInput {
RunnerInput(
projectPath: projectPath,
projectType: .spm,
timeout: 60,
concurrency: 1,
noCache: false,
schematizedFiles: schematizedFiles,
supportFileContent: "",
mutants: mutants
)
}

private func makeMutant(
id: String,
filePath: String,
Expand Down