Skip to content

Commit c33ead5

Browse files
adamsitnikjozkee
andauthored
Fluent APIs are not allowed in non-builder types (#1994)
* Argument.AcceptOnlyFromAmong should return void * Option.AcceptOnlyFromAmong should return void * Argument.AcceptLegalFilePathsOnly should return void * Option.AcceptLegalFilePathsOnly should return void * Argument.AcceptLegalFileNamesOnly should return void * Option.AcceptLegalFileNamesOnly should return void Co-authored-by: David Cantú <dacantu@microsoft.com>
1 parent 704e640 commit c33ead5

File tree

11 files changed

+120
-117
lines changed

11 files changed

+120
-117
lines changed

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ System.CommandLine
2121
.ctor(Func<System.CommandLine.Parsing.ArgumentResult,T> parse, System.Boolean isDefault = False)
2222
public System.Boolean HasDefaultValue { get; }
2323
public System.Type ValueType { get; }
24-
public Argument<T> AcceptLegalFileNamesOnly()
25-
public Argument<T> AcceptLegalFilePathsOnly()
26-
public Argument<T> AcceptOnlyFromAmong(System.String[] values)
24+
public System.Void AcceptLegalFileNamesOnly()
25+
public System.Void AcceptLegalFilePathsOnly()
26+
public System.Void AcceptOnlyFromAmong(System.String[] values)
2727
public System.Void SetDefaultValue(T value)
2828
public System.Void SetDefaultValueFactory(Func<T> defaultValueFactory)
2929
public System.Void SetDefaultValueFactory(Func<System.CommandLine.Parsing.ArgumentResult,T> defaultValueFactory)
@@ -198,9 +198,9 @@ System.CommandLine
198198
.ctor(System.String[] aliases, Func<System.CommandLine.Parsing.ArgumentResult,T> parseArgument, System.Boolean isDefault = False, System.String description = null)
199199
.ctor(System.String name, Func<T> defaultValueFactory, System.String description = null)
200200
.ctor(System.String[] aliases, Func<T> defaultValueFactory, System.String description = null)
201-
public Option<T> AcceptLegalFileNamesOnly()
202-
public Option<T> AcceptLegalFilePathsOnly()
203-
public Option<T> AcceptOnlyFromAmong(System.String[] values)
201+
public System.Void AcceptLegalFileNamesOnly()
202+
public System.Void AcceptLegalFilePathsOnly()
203+
public System.Void AcceptOnlyFromAmong(System.String[] values)
204204
public System.Void SetDefaultValue(T value)
205205
public System.Void SetDefaultValueFactory(Func<T> defaultValueFactory)
206206
public static class OptionValidation

src/System.CommandLine.Tests/ArgumentTests.cs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -769,8 +769,9 @@ public void OnlyTake_can_pass_on_all_tokens_from_a_single_arity_argument_to_anot
769769
[Fact]
770770
public void Argument_of_enum_can_limit_enum_members_as_valid_values()
771771
{
772-
var argument = new Argument<ConsoleColor>()
773-
.AcceptOnlyFromAmong(ConsoleColor.Red.ToString(), ConsoleColor.Green.ToString());
772+
var argument = new Argument<ConsoleColor>();
773+
argument.AcceptOnlyFromAmong(ConsoleColor.Red.ToString(), ConsoleColor.Green.ToString());
774+
774775
Command command = new("set-color")
775776
{
776777
argument
@@ -784,17 +785,6 @@ public void Argument_of_enum_can_limit_enum_members_as_valid_values()
784785
.BeEquivalentTo(new[] { $"Argument 'Fuschia' not recognized. Must be one of:\n\t'Red'\n\t'Green'" });
785786
}
786787

787-
[Fact]
788-
public void Argument_of_T_fluent_APIs_return_Argument_of_T()
789-
{
790-
Argument<string> argument = new Argument<string>("--path")
791-
.AcceptOnlyFromAmong("text")
792-
.AcceptLegalFileNamesOnly()
793-
.AcceptLegalFilePathsOnly();
794-
795-
argument.Should().BeOfType<Argument<string>>();
796-
}
797-
798788
protected override Symbol CreateSymbol(string name)
799789
{
800790
return new Argument<string>(name);

src/System.CommandLine.Tests/CompletionContextTests.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,13 @@ public void When_position_is_unspecified_in_string_command_line_ending_with_a_sp
109109
[Fact]
110110
public void When_position_is_greater_than_input_length_in_a_string_command_line_then_it_returns_empty()
111111
{
112+
Option<string> option1 = new ("--option1");
113+
option1.AcceptOnlyFromAmong("apple", "banana", "cherry", "durian");
114+
112115
var command = new Command("the-command")
113116
{
114117
new Argument<string>(),
115-
new Option<string>("--option1").AcceptOnlyFromAmong("apple", "banana", "cherry", "durian"),
118+
option1,
116119
new Option<string>("--option2")
117120
};
118121

@@ -176,9 +179,12 @@ public void When_position_is_unspecified_in_array_command_line_and_final_token_m
176179
[Fact]
177180
public void When_position_is_unspecified_in_array_command_line_and_final_token_matches_an_argument_then_it_returns_the_argument_value()
178181
{
182+
Option<string> option1 = new("--option1");
183+
option1.AcceptOnlyFromAmong("apple", "banana", "cherry", "durian");
184+
179185
var command = new Command("the-command")
180186
{
181-
new Option<string>("--option1").AcceptOnlyFromAmong("apple", "banana", "cherry", "durian"),
187+
option1,
182188
new Option<string>("--option2"),
183189
new Argument<string>()
184190
};

src/System.CommandLine.Tests/CompletionTests.cs

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -441,8 +441,8 @@ public void Parser_options_can_supply_context_sensitive_matches()
441441
{
442442
var parser = new RootCommand
443443
{
444-
new Option<string>("--bread").AcceptOnlyFromAmong("wheat", "sourdough", "rye"),
445-
new Option<string>("--cheese").AcceptOnlyFromAmong("provolone", "cheddar", "cream cheese")
444+
CreateOptionWithAcceptOnlyFromAmong(name: "--bread", "wheat", "sourdough", "rye"),
445+
CreateOptionWithAcceptOnlyFromAmong(name: "--cheese", "provolone", "cheddar", "cream cheese")
446446
};
447447

448448
var commandLine = "--bread";
@@ -546,8 +546,8 @@ public void Argument_completions_can_be_based_on_the_proximate_option()
546546
var parser = new Parser(
547547
new Command("outer")
548548
{
549-
new Option<string>("--one").AcceptOnlyFromAmong("one-a", "one-b"),
550-
new Option<string>("--two").AcceptOnlyFromAmong("two-a", "two-b")
549+
CreateOptionWithAcceptOnlyFromAmong(name: "--one", "one-a", "one-b"),
550+
CreateOptionWithAcceptOnlyFromAmong(name: "--two", "two-a", "two-b")
551551
});
552552

553553
var commandLine = "outer --two";
@@ -648,12 +648,9 @@ public void When_caller_does_the_tokenizing_then_argument_completions_are_based_
648648
{
649649
var command = new Command("outer")
650650
{
651-
new Option<string>("one")
652-
.AcceptOnlyFromAmong("one-a", "one-b", "one-c"),
653-
new Option<string>("two")
654-
.AcceptOnlyFromAmong("two-a", "two-b", "two-c"),
655-
new Option<string>("three")
656-
.AcceptOnlyFromAmong("three-a", "three-b", "three-c")
651+
CreateOptionWithAcceptOnlyFromAmong(name: "one", "one-a", "one-b", "one-c"),
652+
CreateOptionWithAcceptOnlyFromAmong(name: "two", "two-a", "two-b", "two-c"),
653+
CreateOptionWithAcceptOnlyFromAmong(name: "three", "three-a", "three-b", "three-c")
657654
};
658655

659656
var parser = new CommandLineBuilder(new RootCommand
@@ -675,12 +672,9 @@ public void When_parsing_from_array_then_argument_completions_are_based_on_the_p
675672
{
676673
var command = new Command("outer")
677674
{
678-
new Option<string>("one")
679-
.AcceptOnlyFromAmong("one-a", "one-b", "one-c"),
680-
new Option<string>("two")
681-
.AcceptOnlyFromAmong("two-a", "two-b", "two-c"),
682-
new Option<string>("three")
683-
.AcceptOnlyFromAmong("three-a", "three-b", "three-c")
675+
CreateOptionWithAcceptOnlyFromAmong(name: "one", "one-a", "one-b", "one-c"),
676+
CreateOptionWithAcceptOnlyFromAmong(name: "two", "two-a", "two-b", "two-c"),
677+
CreateOptionWithAcceptOnlyFromAmong(name: "three", "three-a", "three-b", "three-c")
684678
};
685679

686680
var result = command.Parse("outer two b");
@@ -698,15 +692,15 @@ public void When_parsing_from_text_then_argument_completions_are_based_on_the_pr
698692
{
699693
new Command("one")
700694
{
701-
new Argument<string>().AcceptOnlyFromAmong("one-a", "one-b", "one-c")
695+
CreateArgumentWithAcceptOnlyFromAmong("one-a", "one-b", "one-c")
702696
},
703697
new Command("two")
704698
{
705-
new Argument<string>().AcceptOnlyFromAmong("two-a", "two-b", "two-c")
699+
CreateArgumentWithAcceptOnlyFromAmong("two-a", "two-b", "two-c")
706700
},
707701
new Command("three")
708702
{
709-
new Argument<string>().AcceptOnlyFromAmong("three-a", "three-b", "three-c")
703+
CreateArgumentWithAcceptOnlyFromAmong("three-a", "three-b", "three-c")
710704
}
711705
};
712706

@@ -725,15 +719,15 @@ public void When_parsing_from_array_then_argument_completions_are_based_on_the_p
725719
{
726720
new Command("one")
727721
{
728-
new Argument<string>().AcceptOnlyFromAmong("one-a", "one-b", "one-c")
722+
CreateArgumentWithAcceptOnlyFromAmong("one-a", "one-b", "one-c")
729723
},
730724
new Command("two")
731725
{
732-
new Argument<string>().AcceptOnlyFromAmong("two-a", "two-b", "two-c")
726+
CreateArgumentWithAcceptOnlyFromAmong("two-a", "two-b", "two-c")
733727
},
734728
new Command("three")
735729
{
736-
new Argument<string>().AcceptOnlyFromAmong("three-a", "three-b", "three-c")
730+
CreateArgumentWithAcceptOnlyFromAmong("three-a", "three-b", "three-c")
737731
}
738732
};
739733

@@ -750,8 +744,8 @@ public void When_parsing_from_text_if_the_proximate_option_is_completed_then_com
750744
{
751745
var command = new RootCommand
752746
{
753-
new Option<string>("--framework").AcceptOnlyFromAmong("net7.0"),
754-
new Option<string>("--language").AcceptOnlyFromAmong("C#"),
747+
CreateOptionWithAcceptOnlyFromAmong(name: "--framework", "net7.0"),
748+
CreateOptionWithAcceptOnlyFromAmong(name: "--language", "C#"),
755749
new Option<string>("--langVersion")
756750
};
757751
var parser = new CommandLineBuilder(command).Build();
@@ -767,8 +761,8 @@ public void When_parsing_from_array_if_the_proximate_option_is_completed_then_co
767761
{
768762
var command = new RootCommand
769763
{
770-
new Option<string>("--framework").AcceptOnlyFromAmong("net7.0"),
771-
new Option<string>("--language").AcceptOnlyFromAmong("C#"),
764+
CreateOptionWithAcceptOnlyFromAmong(name: "--framework", "net7.0"),
765+
CreateOptionWithAcceptOnlyFromAmong(name: "--language", "C#"),
772766
new Option<string>("--langVersion")
773767
};
774768
var parser = new CommandLineBuilder(command).Build();
@@ -968,5 +962,19 @@ public void When_option_completions_are_available_then_they_are_suggested_when_a
968962
.Be(
969963
$"Cannot parse argument 'SleepyDay' for option '--day' as expected type 'System.DayOfWeek'. Did you mean one of the following?{NewLine}Friday{NewLine}Monday{NewLine}Saturday{NewLine}Sunday{NewLine}Thursday{NewLine}Tuesday{NewLine}Wednesday");
970964
}
965+
966+
private static Argument<string> CreateArgumentWithAcceptOnlyFromAmong(params string[] values)
967+
{
968+
Argument<string> argument = new();
969+
argument.AcceptOnlyFromAmong(values);
970+
return argument;
971+
}
972+
973+
private static Option<string> CreateOptionWithAcceptOnlyFromAmong(string name, params string[] values)
974+
{
975+
Option<string> option = new(name);
976+
option.AcceptOnlyFromAmong(values);
977+
return option;
978+
}
971979
}
972980
}

src/System.CommandLine.Tests/OptionTests.cs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,8 @@ public void Option_of_boolean_defaults_to_false_when_not_specified()
358358
[Fact]
359359
public void Option_of_enum_can_limit_enum_members_as_valid_values()
360360
{
361-
var option = new Option<ConsoleColor>("--color")
362-
.AcceptOnlyFromAmong(ConsoleColor.Red.ToString(), ConsoleColor.Green.ToString());
361+
Option<ConsoleColor> option = new("--color");
362+
option.AcceptOnlyFromAmong(ConsoleColor.Red.ToString(), ConsoleColor.Green.ToString());
363363

364364
var result = option.Parse("--color Fuschia");
365365

@@ -368,17 +368,6 @@ public void Option_of_enum_can_limit_enum_members_as_valid_values()
368368
.Should()
369369
.BeEquivalentTo(new[] { $"Argument 'Fuschia' not recognized. Must be one of:\n\t'Red'\n\t'Green'" });
370370
}
371-
372-
[Fact]
373-
public void Option_of_T_fluent_APIs_return_Option_of_T()
374-
{
375-
Option<string> option = new Option<string>("--path")
376-
.AcceptOnlyFromAmong("text")
377-
.AcceptLegalFileNamesOnly()
378-
.AcceptLegalFilePathsOnly();
379-
380-
option.Should().BeOfType<Option<string>>();
381-
}
382371

383372
protected override Symbol CreateSymbol(string name) => new Option<string>(name);
384373
}

src/System.CommandLine.Tests/ParseDiagramTests.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,12 @@ public void Parse_result_diagram_helps_explain_parse_operation()
3232
[Fact]
3333
public void Parse_result_diagram_displays_unmatched_tokens()
3434
{
35+
Option<string> option = new ("-x");
36+
option.AcceptOnlyFromAmong("arg1", "arg2", "arg3");
37+
3538
var command = new Command("command")
3639
{
37-
new Option<string>("-x").AcceptOnlyFromAmong("arg1", "arg2", "arg3")
40+
option
3841
};
3942

4043
var result = command.Parse("command -x ar");

src/System.CommandLine.Tests/ParserTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,8 @@ public void Parser_root_Options_can_be_specified_multiple_times_and_their_argume
350350
[Fact]
351351
public void Options_can_be_specified_multiple_times_and_their_arguments_are_collated()
352352
{
353-
var animalsOption = new Option<string[]>(new[] { "-a", "--animals" })
354-
.AcceptOnlyFromAmong("dog", "cat", "sheep");
353+
var animalsOption = new Option<string[]>(new[] { "-a", "--animals" });
354+
animalsOption.AcceptOnlyFromAmong("dog", "cat", "sheep");
355355
var vegetablesOption = new Option<string[]>(new[] { "-v", "--vegetables" });
356356
var parser = new Parser(
357357
new Command("the-command") {

0 commit comments

Comments
 (0)