Skip to content

Commit eff0cbc

Browse files
Add test cases for target build testability with command plugin
1 parent b776667 commit eff0cbc

File tree

5 files changed

+94
-0
lines changed

5 files changed

+94
-0
lines changed

Fixtures/Miscellaneous/Plugins/CommandPluginTestStub/Package.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,27 @@ let package = Package(
2929
.target(name: "plugintool")
3030
]
3131
),
32+
.plugin(
33+
name: "check-testability",
34+
capability: .command(intent: .custom(
35+
verb: "check-testability",
36+
description: "Check testability of a target"
37+
))
38+
),
3239
.executableTarget(
3340
name: "placeholder"
3441
),
3542
.executableTarget(
3643
name: "plugintool"
3744
),
45+
.target(
46+
name: "InternalModule"
47+
),
48+
.testTarget(
49+
name: "InternalModuleTests",
50+
dependencies: [
51+
.target(name: "InternalModule")
52+
]
53+
),
3854
]
3955
)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import Foundation
2+
import PackagePlugin
3+
4+
@main
5+
struct CheckTestability: CommandPlugin {
6+
// This is a helper for testing target builds to ensure that they are testable.
7+
func performCommand(context: PluginContext, arguments: [String]) async throws {
8+
// Parse the arguments: <targetName> <config> <shouldTestable>
9+
guard arguments.count == 3 else {
10+
fatalError("Usage: <targetName> <config> <shouldTestable>")
11+
}
12+
let rawSubsetName = arguments[0]
13+
var subset: PackageManager.BuildSubset
14+
switch rawSubsetName {
15+
// Special subset names
16+
case "all-with-tests":
17+
subset = .all(includingTests: true)
18+
// By default, treat the subset as a target name
19+
default:
20+
subset = .target(rawSubsetName)
21+
}
22+
guard let config = PackageManager.BuildConfiguration(rawValue: arguments[1]) else {
23+
fatalError("Invalid configuration: \(arguments[1])")
24+
}
25+
let shouldTestable = arguments[2] == "true"
26+
27+
var parameters = PackageManager.BuildParameters()
28+
parameters.configuration = config
29+
parameters.logging = .verbose
30+
31+
// Perform the build
32+
let result = try packageManager.build(subset, parameters: parameters)
33+
34+
// Check if the build was successful
35+
guard result.succeeded else {
36+
fatalError("Build failed: \(result.logText)")
37+
}
38+
39+
// Check if the build log contains "-enable-testing" flag
40+
let isTestable = result.logText.contains("-enable-testing")
41+
if isTestable != shouldTestable {
42+
fatalError("Testability mismatch: expected \(shouldTestable), but got \(isTestable):\n\(result.logText)")
43+
}
44+
}
45+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
internal func internalFunction() {
2+
print("Internal function")
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@testable import InternalModule

Tests/CommandsTests/PackageCommandTests.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2448,6 +2448,35 @@ final class PackageCommandTests: CommandsTestCase {
24482448
}
24492449
}
24502450

2451+
func testCommandPluginBuildTestability() async throws {
2452+
// Plugin arguments: check-testability <targetName> <config> <shouldTestable>
2453+
2454+
// Overall configuration: debug, plugin build request: debug -> without testability
2455+
try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in
2456+
try await XCTAssertAsyncNoThrow(try await SwiftPM.Package.execute(["-c", "debug", "check-testability", "InternalModule", "debug", "true"], packagePath: fixturePath))
2457+
}
2458+
2459+
// Overall configuration: debug, plugin build request: release -> without testability
2460+
try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in
2461+
try await XCTAssertAsyncNoThrow(try await SwiftPM.Package.execute(["-c", "debug", "check-testability", "InternalModule", "release", "false"], packagePath: fixturePath))
2462+
}
2463+
2464+
// Overall configuration: release, plugin build request: debug -> with testability
2465+
try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in
2466+
try await XCTAssertAsyncNoThrow(try await SwiftPM.Package.execute(["-c", "release", "check-testability", "InternalModule", "debug", "true"], packagePath: fixturePath))
2467+
}
2468+
2469+
// Overall configuration: release, plugin build request: release -> with testability
2470+
try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in
2471+
try await XCTAssertAsyncNoThrow(try await SwiftPM.Package.execute(["-c", "release", "check-testability", "InternalModule", "release", "false"], packagePath: fixturePath))
2472+
}
2473+
2474+
// Overall configuration: release, plugin build request: release including tests -> with testability
2475+
try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in
2476+
try await XCTAssertAsyncNoThrow(try await SwiftPM.Package.execute(["-c", "release", "check-testability", "all-with-tests", "release", "true"], packagePath: fixturePath))
2477+
}
2478+
}
2479+
24512480
// Test logging of builds initiated by a command plugin
24522481
func testCommandPluginBuildLogs() async throws {
24532482
// Only run the test if the environment in which we're running actually supports Swift concurrency (which the plugin APIs require).

0 commit comments

Comments
 (0)