Skip to content

Commit d86f87a

Browse files
authored
Remove obsolete methods and clean up argument conversion (#1639)
* HelpBuilder test improvement, cleanup * simplify Token.ToString * fix #1338 * remove late binding methods, clean up some tests & ArgumentConverter * clean up a bit more
1 parent 8152e35 commit d86f87a

16 files changed

+191
-395
lines changed

src/System.CommandLine.ApiCompatibility.Tests/ApiCompatibilityApprovalTests.System_CommandLine_api_is_not_changed.approved.txt

-15
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,6 @@ System.CommandLine.Builder
276276
public static CommandLineBuilder UseHelp(this CommandLineBuilder builder, System.Action<System.CommandLine.Help.HelpContext> customize, System.Nullable<System.Int32> maxWidth = null)
277277
public static TBuilder UseHelpBuilder<TBuilder>(this TBuilder builder, System.Func<System.CommandLine.Binding.BindingContext,System.CommandLine.Help.HelpBuilder> getHelpBuilder)
278278
public static CommandLineBuilder UseLocalizationResources(this CommandLineBuilder builder, System.CommandLine.LocalizationResources validationMessages)
279-
public static CommandLineBuilder UseMiddleware(this CommandLineBuilder builder, System.CommandLine.Invocation.InvocationMiddleware middleware, System.CommandLine.Invocation.MiddlewareOrder order = Default)
280-
public static CommandLineBuilder UseMiddleware(this CommandLineBuilder builder, System.Action<System.CommandLine.Invocation.InvocationContext> onInvoke, System.CommandLine.Invocation.MiddlewareOrder order = Default)
281279
public static CommandLineBuilder UseParseDirective(this CommandLineBuilder builder, System.Nullable<System.Int32> errorExitCode = null)
282280
public static CommandLineBuilder UseParseErrorReporting(this CommandLineBuilder builder, System.Nullable<System.Int32> errorExitCode = null)
283281
public static CommandLineBuilder UseSuggestDirective(this CommandLineBuilder builder)
@@ -467,23 +465,12 @@ System.CommandLine.Parsing
467465
public System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem> GetCompletions(System.Nullable<System.Int32> position = null)
468466
public System.Object GetValueForArgument(System.CommandLine.Argument argument)
469467
public T GetValueForArgument<T>(Argument<T> argument)
470-
public T GetValueForArgument<T>(System.CommandLine.Argument argument)
471468
public System.Object GetValueForOption(System.CommandLine.Option option)
472469
public T GetValueForOption<T>(Option<T> option)
473-
public T GetValueForOption<T>(System.CommandLine.Option option)
474470
public System.String ToString()
475-
public System.Object ValueForArgument(System.String alias)
476-
public System.Object ValueForArgument(System.CommandLine.Argument argument)
477-
public T ValueForArgument<T>(Argument<T> argument)
478-
public T ValueForArgument<T>(System.String name)
479-
public System.Object ValueForOption(System.String alias)
480-
public System.Object ValueForOption(System.CommandLine.Option option)
481-
public T ValueForOption<T>(Option<T> option)
482-
public T ValueForOption<T>(System.String alias)
483471
public static class ParseResultExtensions
484472
public static System.String Diagram(this ParseResult parseResult)
485473
public static System.Boolean HasOption(this ParseResult parseResult, System.CommandLine.Option option)
486-
public static System.Boolean HasOption(this ParseResult parseResult, System.String alias)
487474
public static System.Int32 Invoke(this ParseResult parseResult, System.CommandLine.IConsole console = null)
488475
public static System.Threading.Tasks.Task<System.Int32> InvokeAsync(this ParseResult parseResult, System.CommandLine.IConsole console = null)
489476
public static class ParserExtensions
@@ -507,10 +494,8 @@ System.CommandLine.Parsing
507494
public CommandResult FindResultFor(System.CommandLine.Command command)
508495
public OptionResult FindResultFor(System.CommandLine.Option option)
509496
public T GetValueForArgument<T>(Argument<T> argument)
510-
public T GetValueForArgument<T>(System.CommandLine.Argument argument)
511497
public System.Object GetValueForArgument(System.CommandLine.Argument argument)
512498
public T GetValueForOption<T>(Option<T> option)
513-
public T GetValueForOption<T>(System.CommandLine.Option option)
514499
public System.Object GetValueForOption(System.CommandLine.Option option)
515500
public System.String ToString()
516501
public struct Token : System.ValueType, System.IEquatable<Token>

src/System.CommandLine.NamingConventionBinder.Tests/ModelBindingCommandHandlerTests.cs

+1-19
Original file line numberDiff line numberDiff line change
@@ -67,25 +67,7 @@ public async Task When_argument_type_is_not_known_until_binding_then_bool_parame
6767

6868
received.Should().BeTrue();
6969
}
70-
71-
[Fact]
72-
public async Task When_argument_type_is_not_known_until_binding_then_int_parameter_is_bound_correctly()
73-
{
74-
int received = 0;
75-
76-
var handler = CommandHandler.Create((int x) => received = x);
77-
78-
var root = new RootCommand
79-
{
80-
new Option("-x", arity: new ArgumentArity(1, 1))
81-
};
82-
root.Handler = handler;
83-
84-
await root.InvokeAsync("-x 123");
85-
86-
received.Should().Be(123);
87-
}
88-
70+
8971
[Theory]
9072
[InlineData(typeof(ClassWithCtorParameter<int>), false)]
9173
[InlineData(typeof(ClassWithCtorParameter<int>), true)]

src/System.CommandLine.NamingConventionBinder.Tests/ParameterBindingTests.cs

+1-24
Original file line numberDiff line numberDiff line change
@@ -38,30 +38,7 @@ void Execute(string name, int age)
3838
boundName.Should().Be("Gandalf");
3939
boundAge.Should().Be(425);
4040
}
41-
42-
[Fact]
43-
public async Task Method_parameters_on_the_invoked_method_are_bound_to_matching_option_aliases()
44-
{
45-
string boundName = default;
46-
int boundAge = default;
47-
48-
void Execute(string n, int a)
49-
{
50-
boundName = n;
51-
boundAge = a;
52-
}
53-
54-
var command = new Command("command");
55-
command.AddOption(new Option<string>(new[] { "-n", "--name" }));
56-
command.AddOption(new Option<string>(new[] { "-a", "--age" }));
57-
command.Handler = CommandHandler.Create<string, int>(Execute);
58-
59-
await command.InvokeAsync("command --age 425 --name Gandalf", _console);
60-
61-
boundName.Should().Be("Gandalf");
62-
boundAge.Should().Be(425);
63-
}
64-
41+
6542
[Fact]
6643
public async Task Method_parameters_on_the_invoked_method_can_be_bound_to_hyphenated_option_names()
6744
{

src/System.CommandLine.Tests/Binding/TypeConversionTests.cs

+42-60
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,6 @@ public void Argument_infers_arity_of_IEnumerable_types_as_OneOrMore(Type type)
117117
argument.Arity.Should().BeEquivalentTo(ArgumentArity.OneOrMore);
118118
}
119119

120-
[Fact]
121-
public void Argument_bool_will_default_to_true_when_no_argument_is_passed()
122-
{
123-
var option = new Option<bool>("-x");
124-
125-
var result = option.Parse("-x");
126-
127-
result.Errors.Should().BeEmpty();
128-
result.GetValueForOption(option).Should().Be(true);
129-
}
130-
131120
[Fact]
132121
public void Argument_parses_as_the_default_value_when_the_option_has_not_been_applied()
133122
{
@@ -144,7 +133,7 @@ public void Argument_parses_as_the_default_value_when_the_option_has_not_been_ap
144133
}
145134

146135
[Fact]
147-
public void Argument_does_not_parse_as_the_default_value_when_the_option_has_been_applied()
136+
public void Option_does_not_parse_as_the_default_value_when_the_option_has_been_applied()
148137
{
149138
var option = new Option<int>("-x", () => 123);
150139

@@ -200,6 +189,26 @@ public void Nullable_bool_parses_as_true_when_the_option_has_been_applied(string
200189
.BeTrue();
201190
}
202191

192+
[Theory]
193+
[InlineData("the-command -x false")]
194+
[InlineData("the-command -x:false")]
195+
[InlineData("the-command -x=false")]
196+
public void Nullable_bool_parses_as_false_when_the_option_has_been_applied(string commandLine)
197+
{
198+
var option = new Option<bool?>("-x");
199+
200+
var command = new Command("the-command")
201+
{
202+
option
203+
};
204+
205+
command
206+
.Parse(commandLine)
207+
.GetValueForOption(option)
208+
.Should()
209+
.BeFalse();
210+
}
211+
203212
[Fact]
204213
public void Nullable_bool_parses_as_null_when_the_option_has_not_been_applied()
205214
{
@@ -288,27 +297,6 @@ public void When_zero_or_more_arguments_of_unspecified_type_are_expected_and_non
288297
.BeEmpty();
289298
}
290299

291-
[Fact]
292-
public void
293-
When_zero_or_more_arguments_of_unspecified_type_are_expected_and_none_are_provided_and_there_is_a_default_then_getting_value_returns_default_in_an_empty_sequence_of_strings()
294-
{
295-
var option = new Option("-x", getDefaultValue: () => "the-default", arity: ArgumentArity.ZeroOrMore);
296-
297-
var command = new Command("the-command")
298-
{
299-
option
300-
};
301-
302-
var result = command.Parse("the-command");
303-
304-
result.GetValueForOption(option)
305-
.Should()
306-
.BeAssignableTo<IReadOnlyCollection<string>>()
307-
.Which
308-
.Should()
309-
.BeEquivalentTo("the-default");
310-
}
311-
312300
[Fact]
313301
public void When_one_or_more_arguments_of_unspecified_type_are_expected_and_none_are_provided_then_getting_value_throws()
314302
{
@@ -576,39 +564,41 @@ public void Values_can_be_correctly_converted_to_nullable_DateTimeOffset_without
576564
[Fact]
577565
public void Values_can_be_correctly_converted_to_decimal_without_the_parser_specifying_a_custom_converter()
578566
{
579-
var option = new Option("-x", arity: ArgumentArity.ZeroOrOne);
567+
var option = new Option<decimal>("-x");
568+
569+
var result = option.Parse("-x 123.456");
580570

581-
var value = option.Parse("-x 123.456").GetValueForOption<decimal>(option);
571+
var value = result.GetValueForOption(option);
582572

583573
value.Should().Be(123.456m);
584574
}
585575

586576
[Fact]
587577
public void Values_can_be_correctly_converted_to_nullable_decimal_without_the_parser_specifying_a_custom_converter()
588578
{
589-
var option = new Option("-x", arity: ArgumentArity.ZeroOrOne);
579+
var option = new Option<decimal?>("-x");
590580

591-
var value = option.Parse("-x 123.456").GetValueForOption<decimal?>(option);
581+
var value = option.Parse("-x 123.456").GetValueForOption(option);
592582

593583
value.Should().Be(123.456m);
594584
}
595585

596586
[Fact]
597587
public void Values_can_be_correctly_converted_to_double_without_the_parser_specifying_a_custom_converter()
598588
{
599-
var option = new Option("-x", arity: ArgumentArity.ZeroOrOne);
589+
var option = new Option<double>("-x");
600590

601-
var value = option.Parse("-x 123.456").GetValueForOption<double>(option);
591+
var value = option.Parse("-x 123.456").GetValueForOption(option);
602592

603593
value.Should().Be(123.456d);
604594
}
605595

606596
[Fact]
607597
public void Values_can_be_correctly_converted_to_nullable_double_without_the_parser_specifying_a_custom_converter()
608598
{
609-
var option = new Option("-x", arity: ArgumentArity.ZeroOrOne);
599+
var option = new Option<double?>("-x");
610600

611-
var value = option.Parse("-x 123.456").GetValueForOption<double?>(option);
601+
var value = option.Parse("-x 123.456").GetValueForOption(option);
612602

613603
value.Should().Be(123.456d);
614604
}
@@ -658,28 +648,20 @@ public void Values_can_be_correctly_converted_to_nullable_Guid_without_the_parse
658648
[Fact]
659649
public void Values_can_be_correctly_converted_to_Uri_without_the_parser_specifying_a_custom_converter()
660650
{
661-
var option = new Option("-x", arity: ArgumentArity.ZeroOrOne);
651+
var option = new Option<Uri>("-x");
662652

663-
var value = option.Parse("-x http://example.com").GetValueForOption<Uri>(option);
653+
var value = option.Parse("-x http://example.com").GetValueForOption(option);
664654

665655
value.Should().BeEquivalentTo(new Uri("http://example.com"));
666656
}
667657

668-
[Fact]
669-
public void Options_with_no_arguments_specified_can_be_correctly_converted_to_bool_without_the_parser_specifying_it()
670-
{
671-
var option = new Option("-x", arity: ArgumentArity.ZeroOrOne);
672-
673-
option.Parse("-x").GetValueForOption<bool>(option).Should().BeTrue();
674-
}
675-
676658
[Fact]
677659
public void Options_with_arguments_specified_can_be_correctly_converted_to_bool_without_the_parser_specifying_a_custom_converter()
678660
{
679-
var option = new Option("-x", arity: ArgumentArity.ZeroOrOne);
661+
var option = new Option<bool>("-x");
680662

681-
option.Parse("-x false").GetValueForOption<bool>(option).Should().BeFalse();
682-
option.Parse("-x true").GetValueForOption<bool>(option).Should().BeTrue();
663+
option.Parse("-x false").GetValueForOption(option).Should().BeFalse();
664+
option.Parse("-x true").GetValueForOption(option).Should().BeTrue();
683665
}
684666

685667
[Fact]
@@ -765,9 +747,9 @@ public void Values_can_be_correctly_converted_to_nullable_ushort_without_the_par
765747
[Fact]
766748
public void Values_can_be_correctly_converted_to_array_of_int_without_the_parser_specifying_a_custom_converter()
767749
{
768-
var option = new Option("-x", arity: ArgumentArity.ZeroOrMore);
750+
var option = new Option<int[]>("-x");
769751

770-
var value = option.Parse("-x 1 -x 2 -x 3").GetValueForOption<int[]>(option);
752+
var value = option.Parse("-x 1 -x 2 -x 3").GetValueForOption(option);
771753

772754
value.Should().BeEquivalentTo(1, 2, 3);
773755
}
@@ -815,19 +797,19 @@ public void Max_arity_greater_than_1_converts_to_enumerable_types(
815797
[Fact]
816798
public void Values_can_be_correctly_converted_to_List_of_int_without_the_parser_specifying_a_custom_converter()
817799
{
818-
var option = new Option("-x", arity: ArgumentArity.ZeroOrMore);
800+
var option = new Option<List<int>>("-x");
819801

820-
var value = option.Parse("-x 1 -x 2 -x 3").GetValueForOption<List<int>>(option);
802+
var value = option.Parse("-x 1 -x 2 -x 3").GetValueForOption(option);
821803

822804
value.Should().BeEquivalentTo(1, 2, 3);
823805
}
824806

825807
[Fact]
826808
public void Values_can_be_correctly_converted_to_IEnumerable_of_int_without_the_parser_specifying_a_custom_converter()
827809
{
828-
var option = new Option("-x", arity: ArgumentArity.ZeroOrMore);
810+
var option = new Option<IEnumerable<int>>("-x");
829811

830-
var value = option.Parse("-x 1 -x 2 -x 3").GetValueForOption<IEnumerable<int>>(option);
812+
var value = option.Parse("-x 1 -x 2 -x 3").GetValueForOption(option);
831813

832814
value.Should().BeEquivalentTo(1, 2, 3);
833815
}

src/System.CommandLine.Tests/Help/HelpBuilderTests.cs

+32-9
Original file line numberDiff line numberDiff line change
@@ -1085,24 +1085,47 @@ public void Options_section_keeps_added_newlines()
10851085
public void Options_section_properly_wraps_description()
10861086
{
10871087
var longOptionText =
1088-
$"The option\t" +
1089-
$"with some tabs that is long enough to wrap to a\t" +
1090-
$"new line";
1088+
"The option whose description is long enough that it wraps to a new line";
10911089

10921090
var command = new Command("test-command", "Help text for the command")
10931091
{
1094-
new Option(
1095-
new[] { "-a", "--aaa" },
1096-
longOptionText)
1092+
new Option("-x", "Option with a short description"),
1093+
new Option(new[] { "-a", "--aaa" }, longOptionText),
1094+
new Option("-y", "Option with a short description"),
10971095
};
10981096

10991097
HelpBuilder helpBuilder = GetHelpBuilder(SmallMaxWidth);
11001098
helpBuilder.Write(command, _console);
11011099

11021100
var expected =
1103-
$"Options:{NewLine}" +
1104-
$"{_indentation}-a, --aaa{_columnPadding}The option\twith some tabs that is long enough to wrap to {NewLine}" +
1105-
$"{_indentation} {_columnPadding}a\tnew line{NewLine}{NewLine}";
1101+
$"{_indentation}-a, --aaa{_columnPadding}The option whose description is long enough that it {NewLine}" +
1102+
$"{_indentation} {_columnPadding}wraps to a new line{NewLine}";
1103+
1104+
Console.WriteLine(_console.ToString());
1105+
1106+
_console.ToString().Should().Contain(expected);
1107+
}
1108+
1109+
[Fact]
1110+
public void Options_section_properly_wraps_description_when_long_default_value_is_specified()
1111+
{
1112+
var longOptionText =
1113+
"The option whose description is long enough that it wraps to a new line";
1114+
1115+
var command = new Command("test-command", "Help text for the command")
1116+
{
1117+
new Option("-x", "Option with a short description"),
1118+
new Option(new[] { "-a", "--aaa" }, longOptionText, getDefaultValue: () => "the quick brown fox jumps over the lazy dog"),
1119+
new Option("-y", "Option with a short description"),
1120+
};
1121+
1122+
HelpBuilder helpBuilder = GetHelpBuilder(SmallMaxWidth);
1123+
helpBuilder.Write(command, _console);
1124+
1125+
var expected =
1126+
$"{_indentation}-a, --aaa <aaa>{_columnPadding}The option whose description is long enough that {NewLine}" +
1127+
$"{_indentation} {_columnPadding}it wraps to a new line [default: the quick brown {NewLine}" +
1128+
$"{_indentation} {_columnPadding}fox jumps over the lazy dog]{NewLine}";
11061129

11071130
_console.ToString().Should().Contain(expected);
11081131
}

src/System.CommandLine/Binding/ArgumentConverter.StringConverters.cs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ namespace System.CommandLine.Binding;
88

99
internal static partial class ArgumentConverter
1010
{
11+
private delegate bool TryConvertString(string token, out object? value);
12+
1113
private static readonly Dictionary<Type, TryConvertString> _stringConverters = new()
1214
{
1315
[typeof(bool)] = (string token, out object? value) =>

0 commit comments

Comments
 (0)