Skip to content

Commit ce80f01

Browse files
committed
Refactor validation tests to avoid command invocation
1 parent 1c2a7ce commit ce80f01

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,
@@ -1175,165 +1180,117 @@ struct TestCommandTests {
11751180
struct LLDBTests {
11761181
@Test(arguments: SupportedBuildSystemOnAllPlatforms)
11771182
func lldbWithParallelThrowsError(buildSystem: BuildSystemProvider.Kind) async throws {
1178-
let configuration = BuildConfiguration.debug
1179-
try await fixture(name: "Miscellaneous/EchoExecutable") { fixturePath in
1180-
let error = await #expect(throws: SwiftPMError.self) {
1181-
try await execute(
1182-
["--debugger", "--parallel"],
1183-
packagePath: fixturePath,
1184-
configuration: configuration,
1185-
buildSystem: buildSystem
1186-
)
1187-
}
1183+
let args = args(["--debugger", "--parallel"], for: buildSystem)
1184+
let command = try #require(SwiftTestCommand.parseAsRoot(args) as? SwiftTestCommand)
1185+
let (state, outputStream) = try commandState()
11881186

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

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

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

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

1243-
#expect(
1244-
stderr.contains("error: --debugger cannot be used with --num-workers (debugging requires sequential execution)"),
1245-
"got stdout: \(stdout), stderr: \(stderr)",
1246-
)
1226+
let error = await #expect(throws: ExitCode.self) {
1227+
try await command.run(state)
12471228
}
1229+
1230+
#expect(error == ExitCode.failure, "Expected ExitCode.failure, got \(String(describing: error))")
1231+
1232+
let errorDescription = outputStream.bytes.description
1233+
#expect(
1234+
errorDescription.contains("--debugger cannot be used with --num-workers"),
1235+
"Expected error about incompatible flags, got: \(errorDescription)"
1236+
)
12481237
}
12491238

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

1267-
#expect(
1268-
stderr.contains("error: --debugger cannot be used with --list-tests (use 'swift test list' for listing tests)"),
1269-
"got stdout: \(stdout), stderr: \(stderr)",
1270-
)
1245+
let error = await #expect(throws: ExitCode.self) {
1246+
try await command.run(state)
12711247
}
1248+
1249+
#expect(error == ExitCode.failure, "Expected ExitCode.failure, got \(String(describing: error))")
1250+
1251+
let errorDescription = outputStream.bytes.description
1252+
#expect(
1253+
errorDescription.contains("--debugger cannot be used with --list-tests"),
1254+
"Expected error about incompatible flags, got: \(errorDescription)"
1255+
)
12721256
}
12731257

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

1291-
#expect(
1292-
stderr.contains("error: --debugger cannot be used with --show-codecov-path (debugging session cannot show paths)"),
1293-
"got stdout: \(stdout), stderr: \(stderr)",
1294-
)
1264+
let error = await #expect(throws: ExitCode.self) {
1265+
try await command.run(state)
12951266
}
1267+
1268+
#expect(error == ExitCode.failure, "Expected ExitCode.failure, got \(String(describing: error))")
1269+
1270+
let errorDescription = outputStream.bytes.description
1271+
#expect(
1272+
errorDescription.contains("--debugger cannot be used with --show-codecov-path"),
1273+
"Expected error about incompatible flags, got: \(errorDescription)"
1274+
)
12961275
}
12971276

12981277
@Test(arguments: SupportedBuildSystemOnAllPlatforms)
12991278
func lldbWithReleaseConfigurationThrowsError(buildSystem: BuildSystemProvider.Kind) async throws {
1300-
try await fixture(name: "Miscellaneous/EchoExecutable") { fixturePath in
1301-
let error = await #expect(throws: SwiftPMError.self) {
1302-
try await execute(
1303-
["--debugger", "-c", "release"],
1304-
packagePath: fixturePath,
1305-
configuration: .release,
1306-
buildSystem: buildSystem,
1307-
)
1308-
}
1309-
guard case let SwiftPMError.executionFailure(_, stdout, stderr) = try #require(error) else {
1310-
Issue.record("Incorrect error was raised.")
1311-
return
1312-
}
1279+
let args = args(["--debugger"], for: buildSystem, buildConfiguration: .release)
1280+
let command = try #require(SwiftTestCommand.parseAsRoot(args) as? SwiftTestCommand)
1281+
let (state, outputStream) = try commandState()
13131282

1314-
#expect(
1315-
stderr.contains("error: --debugger cannot be used with release configuration (debugging requires debug symbols)"),
1316-
"got stdout: \(stdout), stderr: \(stderr)",
1317-
)
1283+
let error = await #expect(throws: ExitCode.self) {
1284+
try await command.run(state)
13181285
}
1319-
}
13201286

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

1332-
#expect(
1333-
!stderr.contains("error: --debugger cannot be used with"),
1334-
"got stdout: \(stdout), stderr: \(stderr)",
1335-
)
1336-
}
1289+
let errorDescription = outputStream.bytes.description
1290+
#expect(
1291+
errorDescription.contains("--debugger cannot be used with release configuration"),
1292+
"Expected error about incompatible flags, got: \(errorDescription)"
1293+
)
13371294
}
13381295

13391296
@Test(arguments: SupportedBuildSystemOnAllPlatforms)
@@ -1352,8 +1309,14 @@ struct TestCommandTests {
13521309
"got stdout: \(stdout), stderr: \(stderr)",
13531310
)
13541311

1312+
#if os(macOS)
1313+
let targetName = "xctest"
1314+
#else
1315+
let targetName = buildSystem == .swiftbuild ? "test-runner" : "xctest"
1316+
#endif
1317+
13551318
#expect(
1356-
stdout.contains("target create") && stdout.contains("xctest"),
1319+
stdout.contains("target create") && stdout.contains(targetName),
13571320
"Expected LLDB to target xctest binary, got stdout: \(stdout), stderr: \(stderr)",
13581321
)
13591322

@@ -1380,8 +1343,14 @@ struct TestCommandTests {
13801343
"got stdout: \(stdout), stderr: \(stderr)",
13811344
)
13821345

1346+
#if os(macOS)
1347+
let targetName = "swiftpm-testing-helper"
1348+
#else
1349+
let targetName = "TestDebuggingTests-test-runner"
1350+
#endif
1351+
13831352
#expect(
1384-
stdout.contains("target create") && stdout.contains("swiftpm-testing-helper"),
1353+
stdout.contains("target create") && stdout.contains(targetName),
13851354
"Expected LLDB to target swiftpm-testing-helper binary, got stdout: \(stdout), stderr: \(stderr)",
13861355
)
13871356

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

0 commit comments

Comments
 (0)