From 68b94a4c7341d9bbb11a5b882cd37ea4f1e5a508 Mon Sep 17 00:00:00 2001 From: konomae Date: Wed, 18 May 2022 01:36:30 +0900 Subject: [PATCH] List valid options in error messages for enum array argument (#445) When an array of argument values fails to parse, no custom error message is provided, and a list of valid candidate values is available, include the list as part of the error message. Addresses #401. --- .../Parsable Properties/Argument.swift | 7 ++- .../ErrorMessageTests.swift | 53 +++++++++++++------ 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/Sources/ArgumentParser/Parsable Properties/Argument.swift b/Sources/ArgumentParser/Parsable Properties/Argument.swift index 2847f7751..54e0e0998 100644 --- a/Sources/ArgumentParser/Parsable Properties/Argument.swift +++ b/Sources/ArgumentParser/Parsable Properties/Argument.swift @@ -338,7 +338,12 @@ extension Argument { helpDefaultValue = nil } - let help = ArgumentDefinition.Help(options: [.isOptional, .isRepeating], help: help, key: key) + let help = ArgumentDefinition.Help( + allValues: Element.allValueStrings, + options: [.isOptional, .isRepeating], + help: help, + key: key + ) var arg = ArgumentDefinition( kind: .positional, help: help, diff --git a/Tests/ArgumentParserUnitTests/ErrorMessageTests.swift b/Tests/ArgumentParserUnitTests/ErrorMessageTests.swift index 597c959f7..d3cf274fb 100644 --- a/Tests/ArgumentParserUnitTests/ErrorMessageTests.swift +++ b/Tests/ArgumentParserUnitTests/ErrorMessageTests.swift @@ -64,28 +64,39 @@ extension ErrorMessageTests { } } -fileprivate struct Foo: ParsableArguments { - enum Format: String, Equatable, Decodable, ExpressibleByArgument, CaseIterable { - case text - case json - case csv - } +fileprivate enum Format: String, Equatable, Decodable, ExpressibleByArgument, CaseIterable { + case text + case json + case csv +} - enum Name: String, Equatable, Decodable, ExpressibleByArgument, CaseIterable { - case bruce - case clint - case hulk - case natasha - case steve - case thor - case tony - } +fileprivate enum Name: String, Equatable, Decodable, ExpressibleByArgument, CaseIterable { + case bruce + case clint + case hulk + case natasha + case steve + case thor + case tony +} + +fileprivate struct Foo: ParsableArguments { @Option(name: [.short, .long]) var format: Format @Option(name: [.short, .long]) var name: Name? } +fileprivate struct EnumWithFewCasesArrayArgument: ParsableArguments { + @Argument + var formats: [Format] +} + +fileprivate struct EnumWithManyCasesArrayArgument: ParsableArguments { + @Argument + var names: [Name] +} + extension ErrorMessageTests { func testWrongEnumValue() { AssertErrorMessage(Foo.self, ["--format", "png"], "The value 'png' is invalid for '--format '. Please provide one of 'text', 'json' or 'csv'.") @@ -112,6 +123,18 @@ extension ErrorMessageTests { - thor - tony """) + AssertErrorMessage(EnumWithFewCasesArrayArgument.self, ["png"], "The value 'png' is invalid for ''. Please provide one of 'text', 'json' or 'csv'.") + AssertErrorMessage(EnumWithManyCasesArrayArgument.self, ["loki"], + """ + The value 'loki' is invalid for ''. Please provide one of the following: + - bruce + - clint + - hulk + - natasha + - steve + - thor + - tony + """) } }