Skip to content

Commit 5077640

Browse files
committed
Refactor validation tests to avoid command invocation
1 parent 2e4e877 commit 5077640

File tree

1 file changed

+142
-129
lines changed

1 file changed

+142
-129
lines changed

Tests/CommandsTests/TestCommandTests.swift

Lines changed: 142 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,22 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import Foundation
13+
@testable import Commands
14+
@testable import CoreCommands
1415

16+
import Foundation
1517
import Basics
16-
import Commands
1718
import struct SPMBuildCore.BuildSystemProvider
1819
import enum PackageModel.BuildConfiguration
1920
import PackageModel
2021
import _InternalTestSupport
2122
import TSCTestSupport
2223
import Testing
2324

25+
import struct ArgumentParser.ExitCode
26+
import protocol ArgumentParser.AsyncParsableCommand
27+
import class TSCBasic.BufferedOutputByteStream
28+
2429
fileprivate func execute(
2530
_ args: [String],
2631
packagePath: AbsolutePath? = nil,
@@ -1179,165 +1184,117 @@ struct TestCommandTests {
11791184
struct LLDBTests {
11801185
@Test(arguments: SupportedBuildSystemOnAllPlatforms)
11811186
func lldbWithParallelThrowsError(buildSystem: BuildSystemProvider.Kind) async throws {
1182-
let configuration = BuildConfiguration.debug
1183-
try await fixture(name: "Miscellaneous/EchoExecutable") { fixturePath in
1184-
let error = await #expect(throws: SwiftPMError.self) {
1185-
try await execute(
1186-
["--debugger", "--parallel"],
1187-
packagePath: fixturePath,
1188-
configuration: configuration,
1189-
buildSystem: buildSystem
1190-
)
1191-
}
1187+
let args = args(["--debugger", "--parallel"], for: buildSystem)
1188+
let command = try #require(SwiftTestCommand.parseAsRoot(args) as? SwiftTestCommand)
1189+
let (state, outputStream) = try commandState()
11921190

1193-
guard case let SwiftPMError.executionFailure(_, stdout, stderr) = try #require(error) else {
1194-
Issue.record("Incorrect error was raised.")
1195-
return
1196-
}
1197-
1198-
#expect(
1199-
stderr.contains("error: --debugger cannot be used with --parallel (debugging requires sequential execution)"),
1200-
"got stdout: \(stdout), stderr: \(stderr)",
1201-
)
1191+
let error = await #expect(throws: ExitCode.self) {
1192+
try await command.run(state)
12021193
}
1194+
1195+
#expect(error == ExitCode.failure, "Expected ExitCode.failure, got \(String(describing: error))")
1196+
1197+
let errorDescription = outputStream.bytes.description
1198+
#expect(
1199+
errorDescription.contains("--debugger cannot be used with --parallel"),
1200+
"Expected error about incompatible flags, got: \(errorDescription)"
1201+
)
12031202
}
12041203

12051204
@Test(arguments: SupportedBuildSystemOnAllPlatforms)
12061205
func lldbWithNumWorkersThrowsError(buildSystem: BuildSystemProvider.Kind) async throws {
1207-
let configuration = BuildConfiguration.debug
1208-
try await fixture(name: "Miscellaneous/EchoExecutable") { fixturePath in
1209-
let error = await #expect(throws: SwiftPMError.self) {
1210-
try await execute(
1211-
["--debugger", "--parallel", "--num-workers", "2"],
1212-
packagePath: fixturePath,
1213-
configuration: configuration,
1214-
buildSystem: buildSystem,
1215-
)
1216-
}
1217-
guard case let SwiftPMError.executionFailure(_, stdout, stderr) = try #require(error) else {
1218-
Issue.record("Incorrect error was raised.")
1219-
return
1220-
}
1206+
let args = args(["--debugger", "--parallel", "--num-workers", "2"], for: buildSystem)
1207+
let command = try #require(SwiftTestCommand.parseAsRoot(args) as? SwiftTestCommand)
1208+
let (state, outputStream) = try commandState()
12211209

1222-
// Should hit the --parallel error first since validation is done in order
1223-
#expect(
1224-
stderr.contains("error: --debugger cannot be used with --parallel (debugging requires sequential execution)"),
1225-
"got stdout: \(stdout), stderr: \(stderr)",
1226-
)
1210+
let error = await #expect(throws: ExitCode.self) {
1211+
try await command.run(state)
12271212
}
1213+
1214+
#expect(error == ExitCode.failure, "Expected ExitCode.failure, got \(String(describing: error))")
1215+
1216+
let errorDescription = outputStream.bytes.description
1217+
// Should hit the --parallel error first since validation is done in order
1218+
#expect(
1219+
errorDescription.contains("--debugger cannot be used with --parallel"),
1220+
"Expected error about incompatible flags, got: \(errorDescription)"
1221+
)
12281222
}
12291223

12301224
@Test(arguments: SupportedBuildSystemOnAllPlatforms)
12311225
func lldbWithNumWorkersOnlyThrowsError(buildSystem: BuildSystemProvider.Kind) async throws {
1232-
let configuration = BuildConfiguration.debug
1233-
try await fixture(name: "Miscellaneous/EchoExecutable") { fixturePath in
1234-
let error = await #expect(throws: SwiftPMError.self) {
1235-
try await execute(
1236-
["--debugger", "--num-workers", "2"],
1237-
packagePath: fixturePath,
1238-
configuration: configuration,
1239-
buildSystem: buildSystem,
1240-
)
1241-
}
1242-
guard case let SwiftPMError.executionFailure(_, stdout, stderr) = try #require(error) else {
1243-
Issue.record("Incorrect error was raised.")
1244-
return
1245-
}
1226+
let args = args(["--debugger", "--num-workers", "2"], for: buildSystem)
1227+
let command = try #require(SwiftTestCommand.parseAsRoot(args) as? SwiftTestCommand)
1228+
let (state, outputStream) = try commandState()
12461229

1247-
#expect(
1248-
stderr.contains("error: --debugger cannot be used with --num-workers (debugging requires sequential execution)"),
1249-
"got stdout: \(stdout), stderr: \(stderr)",
1250-
)
1230+
let error = await #expect(throws: ExitCode.self) {
1231+
try await command.run(state)
12511232
}
1233+
1234+
#expect(error == ExitCode.failure, "Expected ExitCode.failure, got \(String(describing: error))")
1235+
1236+
let errorDescription = outputStream.bytes.description
1237+
#expect(
1238+
errorDescription.contains("--debugger cannot be used with --num-workers"),
1239+
"Expected error about incompatible flags, got: \(errorDescription)"
1240+
)
12521241
}
12531242

12541243
@Test(arguments: SupportedBuildSystemOnAllPlatforms)
12551244
func lldbWithListTestsThrowsError(buildSystem: BuildSystemProvider.Kind) async throws {
1256-
let configuration = BuildConfiguration.debug
1257-
try await fixture(name: "Miscellaneous/EchoExecutable") { fixturePath in
1258-
let error = await #expect(throws: SwiftPMError.self) {
1259-
try await execute(
1260-
["--debugger", "--list-tests"],
1261-
packagePath: fixturePath,
1262-
configuration: configuration,
1263-
buildSystem: buildSystem,
1264-
)
1265-
}
1266-
guard case let SwiftPMError.executionFailure(_, stdout, stderr) = try #require(error) else {
1267-
Issue.record("Incorrect error was raised.")
1268-
return
1269-
}
1245+
let args = args(["--debugger", "--list-tests"], for: buildSystem)
1246+
let command = try #require(SwiftTestCommand.parseAsRoot(args) as? SwiftTestCommand)
1247+
let (state, outputStream) = try commandState()
12701248

1271-
#expect(
1272-
stderr.contains("error: --debugger cannot be used with --list-tests (use 'swift test list' for listing tests)"),
1273-
"got stdout: \(stdout), stderr: \(stderr)",
1274-
)
1249+
let error = await #expect(throws: ExitCode.self) {
1250+
try await command.run(state)
12751251
}
1252+
1253+
#expect(error == ExitCode.failure, "Expected ExitCode.failure, got \(String(describing: error))")
1254+
1255+
let errorDescription = outputStream.bytes.description
1256+
#expect(
1257+
errorDescription.contains("--debugger cannot be used with --list-tests"),
1258+
"Expected error about incompatible flags, got: \(errorDescription)"
1259+
)
12761260
}
12771261

12781262
@Test(arguments: SupportedBuildSystemOnAllPlatforms)
12791263
func lldbWithShowCodecovPathThrowsError(buildSystem: BuildSystemProvider.Kind) async throws {
1280-
let configuration = BuildConfiguration.debug
1281-
try await fixture(name: "Miscellaneous/EchoExecutable") { fixturePath in
1282-
let error = await #expect(throws: SwiftPMError.self) {
1283-
try await execute(
1284-
["--debugger", "--show-codecov-path"],
1285-
packagePath: fixturePath,
1286-
configuration: configuration,
1287-
buildSystem: buildSystem,
1288-
)
1289-
}
1290-
guard case let SwiftPMError.executionFailure(_, stdout, stderr) = try #require(error) else {
1291-
Issue.record("Incorrect error was raised.")
1292-
return
1293-
}
1264+
let args = args(["--debugger", "--show-codecov-path"], for: buildSystem)
1265+
let command = try #require(SwiftTestCommand.parseAsRoot(args) as? SwiftTestCommand)
1266+
let (state, outputStream) = try commandState()
12941267

1295-
#expect(
1296-
stderr.contains("error: --debugger cannot be used with --show-codecov-path (debugging session cannot show paths)"),
1297-
"got stdout: \(stdout), stderr: \(stderr)",
1298-
)
1268+
let error = await #expect(throws: ExitCode.self) {
1269+
try await command.run(state)
12991270
}
1271+
1272+
#expect(error == ExitCode.failure, "Expected ExitCode.failure, got \(String(describing: error))")
1273+
1274+
let errorDescription = outputStream.bytes.description
1275+
#expect(
1276+
errorDescription.contains("--debugger cannot be used with --show-codecov-path"),
1277+
"Expected error about incompatible flags, got: \(errorDescription)"
1278+
)
13001279
}
13011280

13021281
@Test(arguments: SupportedBuildSystemOnAllPlatforms)
13031282
func lldbWithReleaseConfigurationThrowsError(buildSystem: BuildSystemProvider.Kind) async throws {
1304-
try await fixture(name: "Miscellaneous/EchoExecutable") { fixturePath in
1305-
let error = await #expect(throws: SwiftPMError.self) {
1306-
try await execute(
1307-
["--debugger", "-c", "release"],
1308-
packagePath: fixturePath,
1309-
configuration: .release,
1310-
buildSystem: buildSystem,
1311-
)
1312-
}
1313-
guard case let SwiftPMError.executionFailure(_, stdout, stderr) = try #require(error) else {
1314-
Issue.record("Incorrect error was raised.")
1315-
return
1316-
}
1283+
let args = args(["--debugger"], for: buildSystem, buildConfiguration: .release)
1284+
let command = try #require(SwiftTestCommand.parseAsRoot(args) as? SwiftTestCommand)
1285+
let (state, outputStream) = try commandState()
13171286

1318-
#expect(
1319-
stderr.contains("error: --debugger cannot be used with release configuration (debugging requires debug symbols)"),
1320-
"got stdout: \(stdout), stderr: \(stderr)",
1321-
)
1287+
let error = await #expect(throws: ExitCode.self) {
1288+
try await command.run(state)
13221289
}
1323-
}
13241290

1325-
@Test(arguments: SupportedBuildSystemOnAllPlatforms)
1326-
func lldbWithCompatibleFlagsDoesNotThrowValidationError(buildSystem: BuildSystemProvider.Kind) async throws {
1327-
let configuration = BuildConfiguration.debug
1328-
try await fixture(name: "Miscellaneous/EchoExecutable") { fixturePath in
1329-
let (stdout, stderr) = try await execute(
1330-
["--debugger", "--filter", ".*", "--skip", "sometest", "--enable-testable-imports"],
1331-
packagePath: fixturePath,
1332-
configuration: configuration,
1333-
buildSystem: buildSystem,
1334-
)
1291+
#expect(error == ExitCode.failure, "Expected ExitCode.failure, got \(String(describing: error))")
13351292

1336-
#expect(
1337-
!stderr.contains("error: --debugger cannot be used with"),
1338-
"got stdout: \(stdout), stderr: \(stderr)",
1339-
)
1340-
}
1293+
let errorDescription = outputStream.bytes.description
1294+
#expect(
1295+
errorDescription.contains("--debugger cannot be used with release configuration"),
1296+
"Expected error about incompatible flags, got: \(errorDescription)"
1297+
)
13411298
}
13421299

13431300
@Test(arguments: SupportedBuildSystemOnAllPlatforms)
@@ -1356,8 +1313,14 @@ struct TestCommandTests {
13561313
"got stdout: \(stdout), stderr: \(stderr)",
13571314
)
13581315

1316+
#if os(macOS)
1317+
let targetName = "xctest"
1318+
#else
1319+
let targetName = buildSystem == .swiftbuild ? "test-runner" : "xctest"
1320+
#endif
1321+
13591322
#expect(
1360-
stdout.contains("target create") && stdout.contains("xctest"),
1323+
stdout.contains("target create") && stdout.contains(targetName),
13611324
"Expected LLDB to target xctest binary, got stdout: \(stdout), stderr: \(stderr)",
13621325
)
13631326

@@ -1384,8 +1347,14 @@ struct TestCommandTests {
13841347
"got stdout: \(stdout), stderr: \(stderr)",
13851348
)
13861349

1350+
#if os(macOS)
1351+
let targetName = "swiftpm-testing-helper"
1352+
#else
1353+
let targetName = "TestDebuggingTests-test-runner"
1354+
#endif
1355+
13871356
#expect(
1388-
stdout.contains("target create") && stdout.contains("swiftpm-testing-helper"),
1357+
stdout.contains("target create") && stdout.contains(targetName),
13891358
"Expected LLDB to target swiftpm-testing-helper binary, got stdout: \(stdout), stderr: \(stderr)",
13901359
)
13911360

@@ -1428,5 +1397,49 @@ struct TestCommandTests {
14281397
)
14291398
}
14301399
}
1400+
1401+
func args(_ args: [String], for buildSystem: BuildSystemProvider.Kind, buildConfiguration: BuildConfiguration = .debug) -> [String] {
1402+
return args + buildConfiguration.args + getBuildSystemArgs(for: buildSystem)
1403+
}
1404+
1405+
func commandState() throws -> (SwiftCommandState, BufferedOutputByteStream) {
1406+
let outputStream = BufferedOutputByteStream()
1407+
1408+
let state = try SwiftCommandState(
1409+
outputStream: outputStream,
1410+
options: try GlobalOptions.parse([]),
1411+
toolWorkspaceConfiguration: .init(shouldInstallSignalHandlers: false),
1412+
workspaceDelegateProvider: {
1413+
CommandWorkspaceDelegate(
1414+
observabilityScope: $0,
1415+
outputHandler: $1,
1416+
progressHandler: $2,
1417+
inputHandler: $3
1418+
)
1419+
},
1420+
workspaceLoaderProvider: {
1421+
XcodeWorkspaceLoader(
1422+
fileSystem: $0,
1423+
observabilityScope: $1
1424+
)
1425+
},
1426+
createPackagePath: false
1427+
)
1428+
return (state, outputStream)
1429+
}
14311430
}
14321431
}
1432+
1433+
fileprivate extension BuildConfiguration {
1434+
var args: [String] {
1435+
var args = ["--configuration"]
1436+
switch self {
1437+
case .debug:
1438+
args.append("debug")
1439+
case .release:
1440+
args.append("release")
1441+
}
1442+
return args
1443+
}
1444+
}
1445+

0 commit comments

Comments
 (0)