1
+ // Copyright (c) .NET Foundation and contributors. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ using FluentAssertions ;
5
+ using Xunit ;
6
+
7
+ namespace System . CommandLine . Tests ;
8
+
9
+ public class CommandLineConfigurationTests
10
+ {
11
+ [ Fact ]
12
+ public void ThrowIfInvalid_throws_if_there_are_duplicate_sibling_option_aliases_on_the_root_command ( )
13
+ {
14
+ var option1 = new Option < string > ( "--dupe" ) ;
15
+ var option2 = new Option < string > ( "-y" ) ;
16
+ option2 . AddAlias ( "--dupe" ) ;
17
+
18
+ var command = new RootCommand
19
+ {
20
+ option1 ,
21
+ option2
22
+ } ;
23
+
24
+ var config = new CommandLineConfiguration ( command ) ;
25
+
26
+ var validate = ( ) => config . ThrowIfInvalid ( ) ;
27
+
28
+ validate . Should ( )
29
+ . Throw < CommandLineConfigurationException > ( )
30
+ . Which
31
+ . Message
32
+ . Should ( )
33
+ . Be ( $ "Duplicate alias '--dupe' found on command '{ command . Name } '.") ;
34
+ }
35
+
36
+ [ Fact ]
37
+ public void ThrowIfInvalid_throws_if_there_are_duplicate_sibling_option_aliases_on_a_subcommand ( )
38
+ {
39
+ var option1 = new Option < string > ( "--dupe" ) ;
40
+ var option2 = new Option < string > ( "--ok" ) ;
41
+ option2 . AddAlias ( "--dupe" ) ;
42
+
43
+ var command = new RootCommand
44
+ {
45
+ new Command ( "subcommand" )
46
+ {
47
+ option1 ,
48
+ option2
49
+ }
50
+ } ;
51
+
52
+ var config = new CommandLineConfiguration ( command ) ;
53
+
54
+ var validate = ( ) => config . ThrowIfInvalid ( ) ;
55
+
56
+ validate . Should ( )
57
+ . Throw < CommandLineConfigurationException > ( )
58
+ . Which
59
+ . Message
60
+ . Should ( )
61
+ . Be ( "Duplicate alias '--dupe' found on command 'subcommand'." ) ;
62
+ }
63
+
64
+ [ Fact ]
65
+ public void ThrowIfInvalid_throws_if_there_are_duplicate_sibling_subcommand_aliases_on_the_root_command ( )
66
+ {
67
+ var command1 = new Command ( "dupe" ) ;
68
+ var command2 = new Command ( "not-a-dupe" ) ;
69
+ command2 . AddAlias ( "dupe" ) ;
70
+
71
+ var rootCommand = new RootCommand
72
+ {
73
+ command1 ,
74
+ command2
75
+ } ;
76
+
77
+ var config = new CommandLineConfiguration ( rootCommand ) ;
78
+
79
+ var validate = ( ) => config . ThrowIfInvalid ( ) ;
80
+
81
+ validate . Should ( )
82
+ . Throw < CommandLineConfigurationException > ( )
83
+ . Which
84
+ . Message
85
+ . Should ( )
86
+ . Be ( $ "Duplicate alias 'dupe' found on command '{ rootCommand . Name } '.") ;
87
+ }
88
+
89
+ [ Fact ]
90
+ public void ThrowIfInvalid_throws_if_there_are_duplicate_sibling_subcommand_aliases_on_a_subcommand ( )
91
+ {
92
+ var command1 = new Command ( "dupe" ) ;
93
+ var command2 = new Command ( "not-a-dupe" ) ;
94
+ command2 . AddAlias ( "dupe" ) ;
95
+
96
+ var command = new RootCommand
97
+ {
98
+ new Command ( "subcommand" )
99
+ {
100
+ command1 ,
101
+ command2
102
+ }
103
+ } ;
104
+
105
+ var config = new CommandLineConfiguration ( command ) ;
106
+
107
+ var validate = ( ) => config . ThrowIfInvalid ( ) ;
108
+
109
+ validate . Should ( )
110
+ . Throw < CommandLineConfigurationException > ( )
111
+ . Which
112
+ . Message
113
+ . Should ( )
114
+ . Be ( "Duplicate alias 'dupe' found on command 'subcommand'." ) ;
115
+ }
116
+
117
+ [ Fact ]
118
+ public void ThrowIfInvalid_throws_if_sibling_command_and_option_aliases_collide_on_the_root_command ( )
119
+ {
120
+ var option = new Option ( "dupe" ) ;
121
+ var command = new Command ( "not-a-dupe" ) ;
122
+ command . AddAlias ( "dupe" ) ;
123
+
124
+ var rootCommand = new RootCommand
125
+ {
126
+ option ,
127
+ command
128
+ } ;
129
+
130
+ var config = new CommandLineConfiguration ( rootCommand ) ;
131
+
132
+ var validate = ( ) => config . ThrowIfInvalid ( ) ;
133
+
134
+ validate . Should ( )
135
+ . Throw < CommandLineConfigurationException > ( )
136
+ . Which
137
+ . Message
138
+ . Should ( )
139
+ . Be ( $ "Duplicate alias 'dupe' found on command '{ rootCommand . Name } '.") ;
140
+ }
141
+
142
+ [ Fact ]
143
+ public void ThrowIfInvalid_throws_if_sibling_command_and_option_aliases_collide_on_a_subcommand ( )
144
+ {
145
+ var option = new Option ( "dupe" ) ;
146
+ var command = new Command ( "not-a-dupe" ) ;
147
+ command . AddAlias ( "dupe" ) ;
148
+
149
+ var rootCommand = new RootCommand
150
+ {
151
+ new Command ( "subcommand" )
152
+ {
153
+ option ,
154
+ command
155
+ }
156
+ } ;
157
+
158
+ var config = new CommandLineConfiguration ( rootCommand ) ;
159
+
160
+ var validate = ( ) => config . ThrowIfInvalid ( ) ;
161
+
162
+ validate . Should ( )
163
+ . Throw < CommandLineConfigurationException > ( )
164
+ . Which
165
+ . Message
166
+ . Should ( )
167
+ . Be ( "Duplicate alias 'dupe' found on command 'subcommand'." ) ;
168
+ }
169
+
170
+ [ Fact ]
171
+ public void ThrowIfInvalid_throws_if_there_are_duplicate_sibling_global_option_aliases_on_the_root_command ( )
172
+ {
173
+ var option1 = new Option < string > ( "--dupe" ) ;
174
+ var option2 = new Option < string > ( "-y" ) ;
175
+ option2 . AddAlias ( "--dupe" ) ;
176
+
177
+ var command = new RootCommand ( ) ;
178
+ command . AddGlobalOption ( option1 ) ;
179
+ command . AddGlobalOption ( option2 ) ;
180
+
181
+ var config = new CommandLineConfiguration ( command ) ;
182
+
183
+ var validate = ( ) => config . ThrowIfInvalid ( ) ;
184
+
185
+ validate . Should ( )
186
+ . Throw < CommandLineConfigurationException > ( )
187
+ . Which
188
+ . Message
189
+ . Should ( )
190
+ . Be ( $ "Duplicate alias '--dupe' found on command '{ command . Name } '.") ;
191
+ }
192
+
193
+ [ Fact ]
194
+ public void ThrowIfInvalid_does_not_throw_if_global_option_alias_is_the_same_as_local_option_alias ( )
195
+ {
196
+ var rootCommand = new RootCommand
197
+ {
198
+ new Command ( "subcommand" )
199
+ {
200
+ new Option < string > ( "--dupe" )
201
+ }
202
+ } ;
203
+ rootCommand . AddGlobalOption ( new Option < string > ( "--dupe" ) ) ;
204
+
205
+ var config = new CommandLineConfiguration ( rootCommand ) ;
206
+
207
+ var validate = ( ) => config . ThrowIfInvalid ( ) ;
208
+
209
+ validate . Should ( ) . NotThrow ( ) ;
210
+ }
211
+
212
+ [ Fact ]
213
+ public void ThrowIfInvalid_does_not_throw_if_global_option_alias_is_the_same_as_subcommand_alias ( )
214
+ {
215
+ var rootCommand = new RootCommand
216
+ {
217
+ new Command ( "subcommand" )
218
+ {
219
+ new Command ( "--dupe" )
220
+ }
221
+ } ;
222
+ rootCommand . AddGlobalOption ( new Option < string > ( "--dupe" ) ) ;
223
+
224
+ var config = new CommandLineConfiguration ( rootCommand ) ;
225
+
226
+ var validate = ( ) => config . ThrowIfInvalid ( ) ;
227
+
228
+ validate . Should ( ) . NotThrow ( ) ;
229
+ }
230
+
231
+ [ Fact ]
232
+ public void ThrowIfInvalid_throws_if_a_command_is_its_own_parent ( )
233
+ {
234
+ var command = new RootCommand ( ) ;
235
+ command . Add ( command ) ;
236
+
237
+ var config = new CommandLineConfiguration ( command ) ;
238
+
239
+ var validate = ( ) => config . ThrowIfInvalid ( ) ;
240
+
241
+ validate . Should ( )
242
+ . Throw < CommandLineConfigurationException > ( )
243
+ . Which
244
+ . Message
245
+ . Should ( )
246
+ . Be ( $ "Cycle detected in command tree. Command '{ command . Name } ' is its own ancestor.") ;
247
+ }
248
+
249
+ [ Fact ]
250
+ public void ThrowIfInvalid_throws_if_a_parentage_cycle_is_detected ( )
251
+ {
252
+ var command = new Command ( "command" ) ;
253
+ var rootCommand = new RootCommand { command } ;
254
+ command . Add ( rootCommand ) ;
255
+
256
+ var config = new CommandLineConfiguration ( rootCommand ) ;
257
+
258
+ var validate = ( ) => config . ThrowIfInvalid ( ) ;
259
+
260
+ validate . Should ( )
261
+ . Throw < CommandLineConfigurationException > ( )
262
+ . Which
263
+ . Message
264
+ . Should ( )
265
+ . Be ( $ "Cycle detected in command tree. Command '{ rootCommand . Name } ' is its own ancestor.") ;
266
+ }
267
+ }
0 commit comments