1 use clap::Args;
2 use clap::Parser;
3
4 #[test]
test_standalone_long_generates_kebab_case()5 fn test_standalone_long_generates_kebab_case() {
6 #[derive(Parser, Debug, PartialEq)]
7 #[allow(non_snake_case)]
8 struct Opt {
9 #[arg(long)]
10 FOO_OPTION: bool,
11 }
12
13 assert_eq!(
14 Opt { FOO_OPTION: true },
15 Opt::try_parse_from(["test", "--foo-option"]).unwrap()
16 );
17 }
18
19 #[test]
test_custom_long_overwrites_default_name()20 fn test_custom_long_overwrites_default_name() {
21 #[derive(Parser, Debug, PartialEq)]
22 struct Opt {
23 #[arg(long = "foo")]
24 foo_option: bool,
25 }
26
27 assert_eq!(
28 Opt { foo_option: true },
29 Opt::try_parse_from(["test", "--foo"]).unwrap()
30 );
31 }
32
33 #[test]
test_standalone_long_uses_previous_defined_custom_name()34 fn test_standalone_long_uses_previous_defined_custom_name() {
35 #[derive(Parser, Debug, PartialEq)]
36 struct Opt {
37 #[arg(id = "foo", long)]
38 foo_option: bool,
39 }
40
41 assert_eq!(
42 Opt { foo_option: true },
43 Opt::try_parse_from(["test", "--foo"]).unwrap()
44 );
45 }
46
47 #[test]
test_standalone_long_ignores_afterwards_defined_custom_name()48 fn test_standalone_long_ignores_afterwards_defined_custom_name() {
49 #[derive(Parser, Debug, PartialEq)]
50 struct Opt {
51 #[arg(long, id = "foo")]
52 foo_option: bool,
53 }
54
55 assert_eq!(
56 Opt { foo_option: true },
57 Opt::try_parse_from(["test", "--foo-option"]).unwrap()
58 );
59 }
60
61 #[test]
test_standalone_long_uses_previous_defined_custom_id()62 fn test_standalone_long_uses_previous_defined_custom_id() {
63 #[derive(Parser, Debug, PartialEq)]
64 struct Opt {
65 #[arg(id = "foo", long)]
66 foo_option: bool,
67 }
68
69 assert_eq!(
70 Opt { foo_option: true },
71 Opt::try_parse_from(["test", "--foo"]).unwrap()
72 );
73 }
74
75 #[test]
test_standalone_long_ignores_afterwards_defined_custom_id()76 fn test_standalone_long_ignores_afterwards_defined_custom_id() {
77 #[derive(Parser, Debug, PartialEq)]
78 struct Opt {
79 #[arg(long, id = "foo")]
80 foo_option: bool,
81 }
82
83 assert_eq!(
84 Opt { foo_option: true },
85 Opt::try_parse_from(["test", "--foo-option"]).unwrap()
86 );
87 }
88
89 #[test]
test_standalone_short_generates_kebab_case()90 fn test_standalone_short_generates_kebab_case() {
91 #[derive(Parser, Debug, PartialEq)]
92 #[allow(non_snake_case)]
93 struct Opt {
94 #[arg(short)]
95 FOO_OPTION: bool,
96 }
97
98 assert_eq!(
99 Opt { FOO_OPTION: true },
100 Opt::try_parse_from(["test", "-f"]).unwrap()
101 );
102 }
103
104 #[test]
test_custom_short_overwrites_default_name()105 fn test_custom_short_overwrites_default_name() {
106 #[derive(Parser, Debug, PartialEq)]
107 struct Opt {
108 #[arg(short = 'o')]
109 foo_option: bool,
110 }
111
112 assert_eq!(
113 Opt { foo_option: true },
114 Opt::try_parse_from(["test", "-o"]).unwrap()
115 );
116 }
117
118 #[test]
test_standalone_short_uses_previous_defined_custom_name()119 fn test_standalone_short_uses_previous_defined_custom_name() {
120 #[derive(Parser, Debug, PartialEq)]
121 struct Opt {
122 #[arg(id = "option", short)]
123 foo_option: bool,
124 }
125
126 assert_eq!(
127 Opt { foo_option: true },
128 Opt::try_parse_from(["test", "-o"]).unwrap()
129 );
130 }
131
132 #[test]
test_standalone_short_ignores_afterwards_defined_custom_name()133 fn test_standalone_short_ignores_afterwards_defined_custom_name() {
134 #[derive(Parser, Debug, PartialEq)]
135 struct Opt {
136 #[arg(short, id = "option")]
137 foo_option: bool,
138 }
139
140 assert_eq!(
141 Opt { foo_option: true },
142 Opt::try_parse_from(["test", "-f"]).unwrap()
143 );
144 }
145
146 #[test]
test_standalone_short_uses_previous_defined_custom_id()147 fn test_standalone_short_uses_previous_defined_custom_id() {
148 #[derive(Parser, Debug, PartialEq)]
149 struct Opt {
150 #[arg(id = "option", short)]
151 foo_option: bool,
152 }
153
154 assert_eq!(
155 Opt { foo_option: true },
156 Opt::try_parse_from(["test", "-o"]).unwrap()
157 );
158 }
159
160 #[test]
test_standalone_short_ignores_afterwards_defined_custom_id()161 fn test_standalone_short_ignores_afterwards_defined_custom_id() {
162 #[derive(Parser, Debug, PartialEq)]
163 struct Opt {
164 #[arg(short, id = "option")]
165 foo_option: bool,
166 }
167
168 assert_eq!(
169 Opt { foo_option: true },
170 Opt::try_parse_from(["test", "-f"]).unwrap()
171 );
172 }
173
174 #[test]
test_standalone_long_uses_previous_defined_casing()175 fn test_standalone_long_uses_previous_defined_casing() {
176 #[derive(Parser, Debug, PartialEq)]
177 struct Opt {
178 #[arg(rename_all = "screaming_snake", long)]
179 foo_option: bool,
180 }
181
182 assert_eq!(
183 Opt { foo_option: true },
184 Opt::try_parse_from(["test", "--FOO_OPTION"]).unwrap()
185 );
186 }
187
188 #[test]
test_standalone_short_uses_previous_defined_casing()189 fn test_standalone_short_uses_previous_defined_casing() {
190 #[derive(Parser, Debug, PartialEq)]
191 struct Opt {
192 #[arg(rename_all = "screaming_snake", short)]
193 foo_option: bool,
194 }
195
196 assert_eq!(
197 Opt { foo_option: true },
198 Opt::try_parse_from(["test", "-F"]).unwrap()
199 );
200 }
201
202 #[test]
test_standalone_long_works_with_verbatim_casing()203 fn test_standalone_long_works_with_verbatim_casing() {
204 #[derive(Parser, Debug, PartialEq)]
205 #[allow(non_snake_case)]
206 struct Opt {
207 #[arg(rename_all = "verbatim", long)]
208 _fOO_oPtiON: bool,
209 }
210
211 assert_eq!(
212 Opt { _fOO_oPtiON: true },
213 Opt::try_parse_from(["test", "--_fOO_oPtiON"]).unwrap()
214 );
215 }
216
217 #[test]
test_standalone_short_works_with_verbatim_casing()218 fn test_standalone_short_works_with_verbatim_casing() {
219 #[derive(Parser, Debug, PartialEq)]
220 struct Opt {
221 #[arg(rename_all = "verbatim", short)]
222 _foo: bool,
223 }
224
225 assert_eq!(
226 Opt { _foo: true },
227 Opt::try_parse_from(["test", "-_"]).unwrap()
228 );
229 }
230
231 #[test]
test_rename_all_is_propagated_from_struct_to_fields()232 fn test_rename_all_is_propagated_from_struct_to_fields() {
233 #[derive(Parser, Debug, PartialEq)]
234 #[command(rename_all = "screaming_snake")]
235 struct Opt {
236 #[arg(long)]
237 foo: bool,
238 }
239
240 assert_eq!(
241 Opt { foo: true },
242 Opt::try_parse_from(["test", "--FOO"]).unwrap()
243 );
244 }
245
246 #[test]
test_rename_all_is_not_propagated_from_struct_into_flattened()247 fn test_rename_all_is_not_propagated_from_struct_into_flattened() {
248 #[derive(Parser, Debug, PartialEq)]
249 #[command(rename_all = "screaming_snake")]
250 struct Opt {
251 #[command(flatten)]
252 foo: Foo,
253 }
254
255 #[derive(Args, Debug, PartialEq)]
256 struct Foo {
257 #[arg(long)]
258 foo: bool,
259 }
260
261 assert_eq!(
262 Opt {
263 foo: Foo { foo: true }
264 },
265 Opt::try_parse_from(["test", "--foo"]).unwrap()
266 );
267 }
268
269 #[test]
test_lower_is_renamed()270 fn test_lower_is_renamed() {
271 #[derive(Parser, Debug, PartialEq)]
272 struct Opt {
273 #[arg(rename_all = "lower", long)]
274 foo_option: bool,
275 }
276
277 assert_eq!(
278 Opt { foo_option: true },
279 Opt::try_parse_from(["test", "--foooption"]).unwrap()
280 );
281 }
282
283 #[test]
test_upper_is_renamed()284 fn test_upper_is_renamed() {
285 #[derive(Parser, Debug, PartialEq)]
286 struct Opt {
287 #[arg(rename_all = "upper", long)]
288 foo_option: bool,
289 }
290
291 assert_eq!(
292 Opt { foo_option: true },
293 Opt::try_parse_from(["test", "--FOOOPTION"]).unwrap()
294 );
295 }
296
297 #[test]
test_single_word_enum_variant_is_default_renamed_into_kebab_case()298 fn test_single_word_enum_variant_is_default_renamed_into_kebab_case() {
299 #[derive(Parser, Debug, PartialEq)]
300 enum Opt {
301 Command { foo: u32 },
302 }
303
304 assert_eq!(
305 Opt::Command { foo: 0 },
306 Opt::try_parse_from(["test", "command", "0"]).unwrap()
307 );
308 }
309
310 #[test]
test_multi_word_enum_variant_is_renamed()311 fn test_multi_word_enum_variant_is_renamed() {
312 #[derive(Parser, Debug, PartialEq)]
313 enum Opt {
314 FirstCommand { foo: u32 },
315 }
316
317 assert_eq!(
318 Opt::FirstCommand { foo: 0 },
319 Opt::try_parse_from(["test", "first-command", "0"]).unwrap()
320 );
321 }
322
323 #[test]
test_rename_all_is_not_propagated_from_struct_into_subcommand()324 fn test_rename_all_is_not_propagated_from_struct_into_subcommand() {
325 #[derive(Parser, Debug, PartialEq)]
326 #[command(rename_all = "screaming_snake")]
327 struct Opt {
328 #[command(subcommand)]
329 foo: Foo,
330 }
331
332 #[derive(Parser, Debug, PartialEq)]
333 enum Foo {
334 Command {
335 #[arg(long)]
336 foo: bool,
337 },
338 }
339
340 assert_eq!(
341 Opt {
342 foo: Foo::Command { foo: true }
343 },
344 Opt::try_parse_from(["test", "command", "--foo"]).unwrap()
345 );
346 }
347
348 #[test]
test_rename_all_is_propagated_from_enum_to_variants()349 fn test_rename_all_is_propagated_from_enum_to_variants() {
350 #[derive(Parser, Debug, PartialEq)]
351 #[command(rename_all = "screaming_snake")]
352 enum Opt {
353 FirstVariant,
354 SecondVariant {
355 #[arg(long)]
356 foo: String,
357 },
358 }
359
360 assert_eq!(
361 Opt::FirstVariant,
362 Opt::try_parse_from(["test", "FIRST_VARIANT"]).unwrap()
363 );
364 }
365
366 #[test]
test_rename_all_is_propagated_from_enum_to_variant_fields()367 fn test_rename_all_is_propagated_from_enum_to_variant_fields() {
368 #[derive(Parser, Debug, PartialEq)]
369 #[command(rename_all = "screaming_snake")]
370 enum Opt {
371 FirstVariant,
372 SecondVariant {
373 #[arg(long)]
374 foo: String,
375 },
376 }
377
378 assert_eq!(
379 Opt::SecondVariant {
380 foo: "value".into()
381 },
382 Opt::try_parse_from(["test", "SECOND_VARIANT", "--FOO", "value"]).unwrap()
383 );
384 }
385
386 #[test]
test_rename_all_is_propagation_can_be_overridden()387 fn test_rename_all_is_propagation_can_be_overridden() {
388 #[derive(Parser, Debug, PartialEq)]
389 #[command(rename_all = "screaming_snake")]
390 enum Opt {
391 #[command(rename_all = "kebab_case")]
392 FirstVariant {
393 #[arg(long)]
394 foo_option: bool,
395 },
396 SecondVariant {
397 #[arg(rename_all = "kebab_case", long)]
398 foo_option: bool,
399 },
400 }
401
402 assert_eq!(
403 Opt::FirstVariant { foo_option: true },
404 Opt::try_parse_from(["test", "first-variant", "--foo-option"]).unwrap()
405 );
406
407 assert_eq!(
408 Opt::SecondVariant { foo_option: true },
409 Opt::try_parse_from(["test", "SECOND_VARIANT", "--foo-option"]).unwrap()
410 );
411 }
412