Skip to content

Commit 8f593be

Browse files
committed
Fix crash when --filter is the last argument
1 parent 43751f8 commit 8f593be

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

Sources/Testing/ABI/EntryPoints/EntryPoint.swift

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -357,24 +357,31 @@ extension RandomAccessCollection<String> {
357357
///
358358
/// - Parameters:
359359
/// - key: The key or name of the argument, e.g. `"--attachments-path"`.
360+
/// - index: Optionally, the index where `key` should be found.
360361
///
361362
/// - Returns: The value of the argument named by `key`. If no value is
362363
/// available, returns `nil`.
363364
///
364365
/// This function handles arguments of the form `--key value` and
365366
/// `--key=value`. Other argument syntaxes are not supported.
366-
fileprivate func argumentValue(forKey key: String) -> String? {
367-
if let index = firstIndex(of: key) {
367+
fileprivate func argumentValue(forKey key: String, at index: Index? = nil) -> String? {
368+
guard let index else {
369+
return indices.lazy
370+
.compactMap { argumentValue(forKey: key, at: $0) }
371+
.first
372+
}
373+
374+
let element = self[index]
375+
if element == key {
368376
let nextIndex = self.index(after: index)
369377
if nextIndex < endIndex {
370378
return self[nextIndex]
371379
}
372380
} else {
373381
// Find an element equal to something like "--foo=bar" and split it.
374382
let prefix = "\(key)="
375-
let index = self.firstIndex { $0.hasPrefix(prefix) }
376-
if let index, case let key = self[index], let equalsIndex = key.firstIndex(of: "=") {
377-
return String(key[equalsIndex...].dropFirst())
383+
if element.hasPrefix(prefix), let equalsIndex = element.firstIndex(of: "=") {
384+
return String(element[equalsIndex...].dropFirst())
378385
}
379386
}
380387

@@ -498,9 +505,7 @@ func parseCommandLineArguments(from args: [String]) throws -> __CommandLineArgum
498505

499506
// Filtering
500507
func filterValues(forArgumentsWithLabel label: String) -> [String] {
501-
args.indices.lazy
502-
.filter { args[$0] == label && $0 < args.endIndex }
503-
.map { args[args.index(after: $0)] }
508+
args.indices.compactMap { args.argumentValue(forKey: label, at: $0) }
504509
}
505510
let filter = filterValues(forArgumentsWithLabel: "--filter")
506511
if !filter.isEmpty {

Tests/TestingTests/SwiftPMTests.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ struct SwiftPMTests {
9090
@available(_regexAPI, *)
9191
func filter() async throws {
9292
let configuration = try configurationForEntryPoint(withArguments: ["PATH", "--filter", "hello"])
93+
print(configuration)
9394
let test1 = Test(name: "hello") {}
9495
let test2 = Test(name: "goodbye") {}
9596
let plan = await Runner.Plan(tests: [test1, test2], configuration: configuration)
@@ -145,6 +146,13 @@ struct SwiftPMTests {
145146
#expect(planTests.contains(test2))
146147
}
147148

149+
@Test("--filter or --skip argument as last argument")
150+
@available(_regexAPI, *)
151+
func filterOrSkipAsLast() async throws {
152+
_ = try configurationForEntryPoint(withArguments: ["PATH", "--filter"])
153+
_ = try configurationForEntryPoint(withArguments: ["PATH", "--skip"])
154+
}
155+
148156
@Test(".hidden trait", .tags(.traitRelated))
149157
func hidden() async throws {
150158
let configuration = try configurationForEntryPoint(withArguments: ["PATH"])

0 commit comments

Comments
 (0)