1+ using System ;
2+ using System . Diagnostics . CodeAnalysis ;
3+ using System . Threading . Tasks ;
4+ using CommandDotNet . Parsing ;
5+ using CommandDotNet . Tests . FeatureTests . Suggestions ;
6+ using CommandDotNet . TestTools . Scenarios ;
7+ using Xunit ;
8+ using Xunit . Abstractions ;
9+ using static System . Environment ;
10+
11+ namespace CommandDotNet . Tests . FeatureTests . SuggestDirective ;
12+
13+ public class SuggestDirectiveTests
14+ {
15+ public SuggestDirectiveTests ( ITestOutputHelper output )
16+ {
17+ Ambient . Output = output ;
18+ }
19+
20+ /* Test list:
21+ * - operands
22+ * - extra operand
23+ * - spaces
24+ * - after argument
25+ * - after partial **
26+ * - FileInfo
27+ * - file names
28+ * - DirectoryInfo
29+ * - directory names
30+ * - after argument separator
31+ * ? - how to know if after arg separator vs looking for options?
32+ * - response files
33+ * - file names
34+ * - directory names
35+ * - clubbed options
36+ *
37+ * - check position argument
38+ * ? - is this used commonly? The tests in System.CommandLine all
39+ * seem to have the position as the end of the string.
40+ *
41+ * - check feature list for other considerations
42+ */
43+
44+ [ SuppressMessage ( "Usage" , "xUnit1026:Theory methods should use all of their parameters" ) ]
45+
46+ [ Theory ]
47+ [ InlineData (
48+ "command - includes subcommands, options and next operand allowed values" ,
49+ "" , "--togo/nClosed/nOpened/nOrder/nReserve" ) ]
50+ [ InlineData ( "command - invalid name" , "Blah" , "" ) ]
51+ [ InlineData ( "command - partial name" , "Or" , "Order" ) ]
52+ [ InlineData ( "subcommand" , "Order " , "--juices/n--water/nBreakfast/nDinner/nLunch" ) ]
53+ [ InlineData ( "subcommand - not returned when not available" , "Opened" , "--togo" ) ]
54+ [ InlineData ( "option - show allowed values" , "Reserve --meal" , "Breakfast/nDinner/nLunch" ) ]
55+ [ InlineData ( "option - option prefix shows only options 1" , "Order --" , "--juices/n--water" ) ]
56+ [ InlineData ( "option - option prefix shows only options 2" , "Order -" , "--juices/n--water" ) ]
57+ [ InlineData ( "option - option prefix shows only options 3" , "Order /" , "/juices/n/water" ) ]
58+ [ InlineData ( "option - does not show already provided option" , "Order --water --" , "--juices" ) ]
59+ [ InlineData ( "option - does not show already provided option using short name" , "Order -w --" , "--juices" ) ]
60+ [ InlineData ( "option - partial name" , "Order --jui" , "--juices" ) ]
61+ [ InlineData ( "option - partial name with backslash" , "Order /jui" , "/juices" ) ]
62+ [ InlineData ( "option - partial allowed value" , "Reserve --meal Br" , "Breakfast" ) ]
63+ [ InlineData ( "option - trailing space" , "Order --juices" , "Apple/nBanana/nCherry" ) ]
64+ [ InlineData ( "operand - partial allowed value" , "Op" , "Opened" ) ]
65+ [ InlineData ( "typo before request for autocompletion 1" , "Or --jui" , "" , 1 ) ]
66+ [ InlineData ( "typo before request for autocompletion 2" , "Reserv --meal Br" , "" , 1 ) ]
67+ [ InlineData ( "typo before request for autocompletion 3" , "Reserve --mea Br" , "" , 1 ) ]
68+ public void Suggest ( string scenario , string input , string expected , int exitCode = 0 )
69+ {
70+ new AppRunner < DinerApp > ( )
71+ . UseSuggestDirective_Experimental ( )
72+ . Verify ( new Scenario
73+ {
74+ When = { Args = $ "[suggest] { input } "} ,
75+ Then =
76+ {
77+ Output = NewLine == "/n" ? expected : expected . Replace ( "/n" , NewLine ) ,
78+ ExitCode = exitCode
79+ }
80+ } ) ;
81+ }
82+
83+ [ Fact ]
84+ public void Suggest_works_with_default_middleware ( )
85+ {
86+ var expected = "--togo/n--version/nClosed/nOpened/nOrder/nReserve" ;
87+ new AppRunner < DinerApp > ( )
88+ . UseDefaultMiddleware ( )
89+ . UseCommandLogger ( )
90+ . UseSuggestDirective_Experimental ( )
91+ . Verify ( new Scenario
92+ {
93+ When = { Args = "[suggest]" } ,
94+ Then =
95+ {
96+ Output = NewLine == "/n" ? expected : expected . Replace ( "/n" , NewLine )
97+ }
98+ } ) ;
99+ }
100+
101+ public class DinerApp
102+ {
103+ public enum Status { Opened , Closed }
104+
105+ public enum PartySize { one , two , three , four , five , six , seven , eight , nine , ten }
106+
107+ public Task < int > Interceptor ( InterceptorExecutionDelegate next , IConsole console , [ Option ] bool togo )
108+ {
109+ console . WriteLine ( "DinerApp.Interceptor" ) ;
110+ return Task . FromResult ( 0 ) ;
111+ }
112+
113+ [ DefaultCommand ]
114+ public void Default ( IConsole console , Status status )
115+ {
116+ console . WriteLine ( "DinerApp.Default" ) ;
117+ }
118+
119+ public void Reserve ( IConsole console ,
120+ [ Operand ] PartySize partySize , [ Operand ] string name ,
121+ [ Operand ] DateOnly date , [ Operand ] TimeOnly time , [ Option ] Meal meal )
122+ {
123+ console . WriteLine ( "DinerApp.Reserve" ) ;
124+ }
125+
126+ public void Order ( IConsole console ,
127+ [ Operand ] Meal meal , [ Operand ] Main main , [ Operand ] Vegetable vegetable , [ Operand ] Fruit fruit ,
128+ [ Option ( 'w' ) ] bool water , [ Option ] Fruit juices )
129+ {
130+ console . WriteLine ( "DinerApp.Order" ) ;
131+ }
132+ }
133+ }
0 commit comments