@@ -188,5 +188,106 @@ public async Task Suggestions_favor_matches_with_prefix()
188188
189189 output . ToString ( ) . Should ( ) . Contain ( $ "'-all' was not matched. Did you mean one of the following?{ NewLine } -call") ;
190190 }
191+
192+ [ Fact ]
193+ public async Task Recursive_options_from_parent_command_are_suggested_for_subcommand_token ( )
194+ {
195+ var subcommand = new Command ( "sub" ) ;
196+ var rootCommand = new RootCommand
197+ {
198+ subcommand ,
199+ new Option < string > ( "--verbose" ) { Recursive = true }
200+ } ;
201+
202+ var output = new StringWriter ( ) ;
203+ var result = rootCommand . Parse ( "sub --verbos" ) ;
204+
205+ await result . InvokeAsync ( new ( ) { Output = output } , CancellationToken . None ) ;
206+
207+ output . ToString ( ) . Should ( ) . Contain ( $ "'--verbos' was not matched. Did you mean one of the following?{ NewLine } --verbose") ;
208+ }
209+
210+ [ Fact ]
211+ public async Task Non_recursive_options_from_parent_command_are_not_suggested_for_subcommand_token ( )
212+ {
213+ var subcommand = new Command ( "sub" ) ;
214+ var rootCommand = new RootCommand
215+ {
216+ subcommand ,
217+ new Option < string > ( "--verbose" ) { Recursive = false }
218+ } ;
219+
220+ var output = new StringWriter ( ) ;
221+ var result = rootCommand . Parse ( "sub --verbos" ) ;
222+
223+ await result . InvokeAsync ( new ( ) { Output = output } , CancellationToken . None ) ;
224+
225+ output . ToString ( ) . Should ( ) . NotContain ( "--verbose" ) ;
226+ }
227+
228+ [ Fact ]
229+ public async Task Hidden_recursive_options_from_parent_command_are_not_suggested_for_subcommand_token ( )
230+ {
231+ var subcommand = new Command ( "sub" ) ;
232+ var rootCommand = new RootCommand
233+ {
234+ subcommand ,
235+ new Option < string > ( "--verbose" ) { Recursive = true , Hidden = true }
236+ } ;
237+
238+ var output = new StringWriter ( ) ;
239+ var result = rootCommand . Parse ( "sub --verbos" ) ;
240+
241+ await result . InvokeAsync ( new ( ) { Output = output } , CancellationToken . None ) ;
242+
243+ output . ToString ( ) . Should ( ) . NotContain ( "--verbose" ) ;
244+ }
245+
246+ [ Fact ]
247+ public async Task Recursive_options_from_grandparent_command_are_suggested_for_deeply_nested_subcommand_token ( )
248+ {
249+ var grandchild = new Command ( "grandchild" ) ;
250+ var child = new Command ( "child" ) { grandchild } ;
251+ var rootCommand = new RootCommand
252+ {
253+ child ,
254+ new Option < string > ( "--output" ) { Recursive = true }
255+ } ;
256+
257+ var output = new StringWriter ( ) ;
258+ var result = rootCommand . Parse ( "child grandchild --outpu" ) ;
259+
260+ await result . InvokeAsync ( new ( ) { Output = output } , CancellationToken . None ) ;
261+
262+ output . ToString ( ) . Should ( ) . Contain ( $ "'--outpu' was not matched. Did you mean one of the following?{ NewLine } --output") ;
263+ }
264+
265+ [ Fact ]
266+ public async Task Recursive_options_from_parent_and_own_options_are_both_suggested ( )
267+ {
268+ var subcommand = new Command ( "sub" )
269+ {
270+ new Option < string > ( "--format" )
271+ } ;
272+ var rootCommand = new RootCommand
273+ {
274+ subcommand ,
275+ new Option < string > ( "--verbose" ) { Recursive = true }
276+ } ;
277+
278+ var output = new StringWriter ( ) ;
279+ // "forma" is close to "--format" but not close to "--verbose"
280+ var result = rootCommand . Parse ( "sub forma" ) ;
281+
282+ if ( result . Action is ParseErrorAction parseError )
283+ {
284+ parseError . ShowHelp = false ;
285+ }
286+
287+ await result . InvokeAsync ( new ( ) { Output = output } , CancellationToken . None ) ;
288+
289+ output . ToString ( ) . Should ( ) . Contain ( "--format" ) ;
290+ output . ToString ( ) . Should ( ) . NotContain ( "--verbose" ) ;
291+ }
191292 }
192293}
0 commit comments