• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
2 // Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
3 // Ana Hobden (@hoverbear) <operator@hoverbear.org>
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 use clap::Parser;
11 
12 #[test]
basic()13 fn basic() {
14     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
15     enum ArgChoice {
16         Foo,
17         Bar,
18     }
19 
20     #[derive(Parser, PartialEq, Debug)]
21     struct Opt {
22         #[arg(value_enum)]
23         arg: ArgChoice,
24     }
25 
26     assert_eq!(
27         Opt {
28             arg: ArgChoice::Foo
29         },
30         Opt::try_parse_from(["", "foo"]).unwrap()
31     );
32     assert_eq!(
33         Opt {
34             arg: ArgChoice::Bar
35         },
36         Opt::try_parse_from(["", "bar"]).unwrap()
37     );
38     assert!(Opt::try_parse_from(["", "fOo"]).is_err());
39 }
40 
41 #[test]
default_value()42 fn default_value() {
43     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
44     enum ArgChoice {
45         Foo,
46         Bar,
47     }
48 
49     impl Default for ArgChoice {
50         fn default() -> Self {
51             Self::Bar
52         }
53     }
54 
55     #[derive(Parser, PartialEq, Debug)]
56     struct Opt {
57         #[arg(value_enum, default_value_t)]
58         arg: ArgChoice,
59     }
60 
61     assert_eq!(
62         Opt {
63             arg: ArgChoice::Foo
64         },
65         Opt::try_parse_from(["", "foo"]).unwrap()
66     );
67     assert_eq!(
68         Opt {
69             arg: ArgChoice::Bar
70         },
71         Opt::try_parse_from(["", "bar"]).unwrap()
72     );
73     assert_eq!(
74         Opt {
75             arg: ArgChoice::Bar
76         },
77         Opt::try_parse_from([""]).unwrap()
78     );
79 }
80 
81 #[test]
vec_for_default_values_t()82 fn vec_for_default_values_t() {
83     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
84     enum ArgChoice {
85         Foo,
86         Bar,
87     }
88 
89     #[derive(Parser, PartialEq, Debug)]
90     struct Opt {
91         #[arg(value_enum, default_values_t = vec![ArgChoice::Foo, ArgChoice::Bar])]
92         arg1: Vec<ArgChoice>,
93 
94         #[arg(
95             long,
96             value_enum,
97             default_values_t = clap::ValueEnum::value_variants()
98         )]
99         arg2: Vec<ArgChoice>,
100     }
101 
102     assert_eq!(
103         Opt {
104             arg1: vec![ArgChoice::Foo],
105             arg2: vec![ArgChoice::Foo, ArgChoice::Bar]
106         },
107         Opt::try_parse_from(["", "foo"]).unwrap()
108     );
109     assert_eq!(
110         Opt {
111             arg1: vec![ArgChoice::Bar],
112             arg2: vec![ArgChoice::Foo, ArgChoice::Bar]
113         },
114         Opt::try_parse_from(["", "bar"]).unwrap()
115     );
116     assert_eq!(
117         Opt {
118             arg1: vec![ArgChoice::Foo, ArgChoice::Bar],
119             arg2: vec![ArgChoice::Foo, ArgChoice::Bar]
120         },
121         Opt::try_parse_from([""]).unwrap()
122     );
123     assert_eq!(
124         Opt {
125             arg1: vec![ArgChoice::Foo, ArgChoice::Bar],
126             arg2: vec![ArgChoice::Foo]
127         },
128         Opt::try_parse_from(["", "--arg2", "foo"]).unwrap()
129     );
130 }
131 
132 #[test]
vec_for_default_values_os_t()133 fn vec_for_default_values_os_t() {
134     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
135     enum ArgChoice {
136         Foo,
137         Bar,
138     }
139 
140     #[derive(Parser, PartialEq, Debug)]
141     struct Opt {
142         #[arg(value_enum, default_values_os_t = vec![ArgChoice::Foo, ArgChoice::Bar])]
143         arg: Vec<ArgChoice>,
144 
145         #[arg(
146             long,
147             value_enum,
148             default_values_os_t = clap::ValueEnum::value_variants()
149         )]
150         arg2: Vec<ArgChoice>,
151     }
152 
153     assert_eq!(
154         Opt {
155             arg: vec![ArgChoice::Foo],
156             arg2: vec![ArgChoice::Foo, ArgChoice::Bar]
157         },
158         Opt::try_parse_from(["", "foo"]).unwrap()
159     );
160     assert_eq!(
161         Opt {
162             arg: vec![ArgChoice::Bar],
163             arg2: vec![ArgChoice::Foo, ArgChoice::Bar]
164         },
165         Opt::try_parse_from(["", "bar"]).unwrap()
166     );
167     assert_eq!(
168         Opt {
169             arg: vec![ArgChoice::Foo, ArgChoice::Bar],
170             arg2: vec![ArgChoice::Foo, ArgChoice::Bar]
171         },
172         Opt::try_parse_from([""]).unwrap()
173     );
174     assert_eq!(
175         Opt {
176             arg: vec![ArgChoice::Foo, ArgChoice::Bar],
177             arg2: vec![ArgChoice::Foo]
178         },
179         Opt::try_parse_from(["", "--arg2", "foo"]).unwrap()
180     );
181 }
182 
183 #[test]
multi_word_is_renamed_kebab()184 fn multi_word_is_renamed_kebab() {
185     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
186     #[allow(non_camel_case_types)]
187     enum ArgChoice {
188         FooBar,
189         BAR_BAZ,
190     }
191 
192     #[derive(Parser, PartialEq, Debug)]
193     struct Opt {
194         #[arg(value_enum)]
195         arg: ArgChoice,
196     }
197 
198     assert_eq!(
199         Opt {
200             arg: ArgChoice::FooBar
201         },
202         Opt::try_parse_from(["", "foo-bar"]).unwrap()
203     );
204     assert_eq!(
205         Opt {
206             arg: ArgChoice::BAR_BAZ
207         },
208         Opt::try_parse_from(["", "bar-baz"]).unwrap()
209     );
210     assert!(Opt::try_parse_from(["", "FooBar"]).is_err());
211 }
212 
213 #[test]
variant_with_defined_casing()214 fn variant_with_defined_casing() {
215     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
216     enum ArgChoice {
217         #[value(rename_all = "screaming_snake")]
218         FooBar,
219     }
220 
221     #[derive(Parser, PartialEq, Debug)]
222     struct Opt {
223         #[arg(value_enum)]
224         arg: ArgChoice,
225     }
226 
227     assert_eq!(
228         Opt {
229             arg: ArgChoice::FooBar
230         },
231         Opt::try_parse_from(["", "FOO_BAR"]).unwrap()
232     );
233     assert!(Opt::try_parse_from(["", "FooBar"]).is_err());
234 }
235 
236 #[test]
casing_is_propagated_from_parent()237 fn casing_is_propagated_from_parent() {
238     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
239     #[value(rename_all = "screaming_snake")]
240     enum ArgChoice {
241         FooBar,
242     }
243 
244     #[derive(Parser, PartialEq, Debug)]
245     struct Opt {
246         #[arg(value_enum)]
247         arg: ArgChoice,
248     }
249 
250     assert_eq!(
251         Opt {
252             arg: ArgChoice::FooBar
253         },
254         Opt::try_parse_from(["", "FOO_BAR"]).unwrap()
255     );
256     assert!(Opt::try_parse_from(["", "FooBar"]).is_err());
257 }
258 
259 #[test]
casing_propagation_is_overridden()260 fn casing_propagation_is_overridden() {
261     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
262     #[value(rename_all = "screaming_snake")]
263     enum ArgChoice {
264         #[value(rename_all = "camel")]
265         FooBar,
266     }
267 
268     #[derive(Parser, PartialEq, Debug)]
269     struct Opt {
270         #[arg(value_enum)]
271         arg: ArgChoice,
272     }
273 
274     assert_eq!(
275         Opt {
276             arg: ArgChoice::FooBar
277         },
278         Opt::try_parse_from(["", "fooBar"]).unwrap()
279     );
280     assert!(Opt::try_parse_from(["", "FooBar"]).is_err());
281     assert!(Opt::try_parse_from(["", "FOO_BAR"]).is_err());
282 }
283 
284 #[test]
ignore_case()285 fn ignore_case() {
286     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
287     enum ArgChoice {
288         Foo,
289     }
290 
291     #[derive(Parser, PartialEq, Debug)]
292     struct Opt {
293         #[arg(value_enum, ignore_case(true))]
294         arg: ArgChoice,
295     }
296 
297     assert_eq!(
298         Opt {
299             arg: ArgChoice::Foo
300         },
301         Opt::try_parse_from(["", "foo"]).unwrap()
302     );
303     assert_eq!(
304         Opt {
305             arg: ArgChoice::Foo
306         },
307         Opt::try_parse_from(["", "fOo"]).unwrap()
308     );
309 }
310 
311 #[test]
ignore_case_set_to_false()312 fn ignore_case_set_to_false() {
313     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
314     enum ArgChoice {
315         Foo,
316     }
317 
318     #[derive(Parser, PartialEq, Debug)]
319     struct Opt {
320         #[arg(value_enum, ignore_case(false))]
321         arg: ArgChoice,
322     }
323 
324     assert_eq!(
325         Opt {
326             arg: ArgChoice::Foo
327         },
328         Opt::try_parse_from(["", "foo"]).unwrap()
329     );
330     assert!(Opt::try_parse_from(["", "fOo"]).is_err());
331 }
332 
333 #[test]
alias()334 fn alias() {
335     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
336     enum ArgChoice {
337         #[value(alias = "TOTP")]
338         Totp,
339     }
340 
341     #[derive(Parser, PartialEq, Debug)]
342     struct Opt {
343         #[arg(value_enum, ignore_case(false))]
344         arg: ArgChoice,
345     }
346 
347     assert_eq!(
348         Opt {
349             arg: ArgChoice::Totp
350         },
351         Opt::try_parse_from(["", "totp"]).unwrap()
352     );
353     assert_eq!(
354         Opt {
355             arg: ArgChoice::Totp
356         },
357         Opt::try_parse_from(["", "TOTP"]).unwrap()
358     );
359 }
360 
361 #[test]
multiple_alias()362 fn multiple_alias() {
363     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
364     enum ArgChoice {
365         #[value(alias = "TOTP", alias = "t")]
366         Totp,
367     }
368 
369     #[derive(Parser, PartialEq, Debug)]
370     struct Opt {
371         #[arg(value_enum, ignore_case(false))]
372         arg: ArgChoice,
373     }
374 
375     assert_eq!(
376         Opt {
377             arg: ArgChoice::Totp
378         },
379         Opt::try_parse_from(["", "totp"]).unwrap()
380     );
381     assert_eq!(
382         Opt {
383             arg: ArgChoice::Totp
384         },
385         Opt::try_parse_from(["", "TOTP"]).unwrap()
386     );
387     assert_eq!(
388         Opt {
389             arg: ArgChoice::Totp
390         },
391         Opt::try_parse_from(["", "t"]).unwrap()
392     );
393 }
394 
395 #[test]
skip_variant()396 fn skip_variant() {
397     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
398     #[allow(dead_code)] // silence warning about `Baz` being unused
399     enum ArgChoice {
400         Foo,
401         Bar,
402         #[value(skip)]
403         Baz,
404     }
405 
406     assert_eq!(
407         <ArgChoice as clap::ValueEnum>::value_variants()
408             .iter()
409             .map(clap::ValueEnum::to_possible_value)
410             .map(Option::unwrap)
411             .collect::<Vec<_>>(),
412         vec![
413             clap::builder::PossibleValue::new("foo"),
414             clap::builder::PossibleValue::new("bar")
415         ]
416     );
417 
418     {
419         use clap::ValueEnum;
420         assert!(ArgChoice::from_str("foo", true).is_ok());
421         assert!(ArgChoice::from_str("bar", true).is_ok());
422         assert!(ArgChoice::from_str("baz", true).is_err());
423     }
424 }
425 
426 #[test]
skip_non_unit_variant()427 fn skip_non_unit_variant() {
428     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
429     #[allow(dead_code)] // silence warning about `Baz` being unused
430     enum ArgChoice {
431         Foo,
432         Bar,
433         #[value(skip)]
434         Baz(usize),
435     }
436 
437     assert_eq!(
438         <ArgChoice as clap::ValueEnum>::value_variants()
439             .iter()
440             .map(clap::ValueEnum::to_possible_value)
441             .map(Option::unwrap)
442             .collect::<Vec<_>>(),
443         vec![
444             clap::builder::PossibleValue::new("foo"),
445             clap::builder::PossibleValue::new("bar")
446         ]
447     );
448 
449     {
450         use clap::ValueEnum;
451         assert!(ArgChoice::from_str("foo", true).is_ok());
452         assert!(ArgChoice::from_str("bar", true).is_ok());
453         assert!(ArgChoice::from_str("baz", true).is_err());
454     }
455 }
456 
457 #[test]
from_str_invalid()458 fn from_str_invalid() {
459     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
460     enum ArgChoice {
461         Foo,
462     }
463 
464     {
465         use clap::ValueEnum;
466         assert!(ArgChoice::from_str("bar", true).is_err());
467     }
468 }
469 
470 #[test]
option_type()471 fn option_type() {
472     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
473     enum ArgChoice {
474         Foo,
475         Bar,
476     }
477 
478     #[derive(Parser, PartialEq, Debug)]
479     struct Opt {
480         #[arg(value_enum)]
481         arg: Option<ArgChoice>,
482     }
483 
484     assert_eq!(Opt { arg: None }, Opt::try_parse_from([""]).unwrap());
485     assert_eq!(
486         Opt {
487             arg: Some(ArgChoice::Foo)
488         },
489         Opt::try_parse_from(["", "foo"]).unwrap()
490     );
491     assert_eq!(
492         Opt {
493             arg: Some(ArgChoice::Bar)
494         },
495         Opt::try_parse_from(["", "bar"]).unwrap()
496     );
497     assert!(Opt::try_parse_from(["", "fOo"]).is_err());
498 }
499 
500 #[test]
option_option_type()501 fn option_option_type() {
502     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
503     enum ArgChoice {
504         Foo,
505         Bar,
506     }
507 
508     #[derive(Parser, PartialEq, Debug)]
509     struct Opt {
510         #[arg(value_enum, long)]
511         arg: Option<Option<ArgChoice>>,
512     }
513 
514     assert_eq!(Opt { arg: None }, Opt::try_parse_from([""]).unwrap());
515     assert_eq!(
516         Opt { arg: Some(None) },
517         Opt::try_parse_from(["", "--arg"]).unwrap()
518     );
519     assert_eq!(
520         Opt {
521             arg: Some(Some(ArgChoice::Foo))
522         },
523         Opt::try_parse_from(["", "--arg", "foo"]).unwrap()
524     );
525     assert_eq!(
526         Opt {
527             arg: Some(Some(ArgChoice::Bar))
528         },
529         Opt::try_parse_from(["", "--arg", "bar"]).unwrap()
530     );
531     assert!(Opt::try_parse_from(["", "--arg", "fOo"]).is_err());
532 }
533 
534 #[test]
vec_type()535 fn vec_type() {
536     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
537     enum ArgChoice {
538         Foo,
539         Bar,
540     }
541 
542     #[derive(Parser, PartialEq, Debug)]
543     struct Opt {
544         #[arg(value_enum, short, long)]
545         arg: Vec<ArgChoice>,
546     }
547 
548     assert_eq!(Opt { arg: vec![] }, Opt::try_parse_from([""]).unwrap());
549     assert_eq!(
550         Opt {
551             arg: vec![ArgChoice::Foo]
552         },
553         Opt::try_parse_from(["", "-a", "foo"]).unwrap()
554     );
555     assert_eq!(
556         Opt {
557             arg: vec![ArgChoice::Foo, ArgChoice::Bar]
558         },
559         Opt::try_parse_from(["", "-a", "foo", "-a", "bar"]).unwrap()
560     );
561     assert!(Opt::try_parse_from(["", "-a", "fOo"]).is_err());
562 }
563 
564 #[test]
option_vec_type()565 fn option_vec_type() {
566     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
567     enum ArgChoice {
568         Foo,
569         Bar,
570     }
571 
572     #[derive(Parser, PartialEq, Debug)]
573     struct Opt {
574         #[arg(value_enum, short, long)]
575         arg: Option<Vec<ArgChoice>>,
576     }
577 
578     assert_eq!(Opt { arg: None }, Opt::try_parse_from([""]).unwrap());
579     assert_eq!(
580         Opt {
581             arg: Some(vec![ArgChoice::Foo])
582         },
583         Opt::try_parse_from(["", "-a", "foo"]).unwrap()
584     );
585     assert_eq!(
586         Opt {
587             arg: Some(vec![ArgChoice::Foo, ArgChoice::Bar])
588         },
589         Opt::try_parse_from(["", "-a", "foo", "-a", "bar"]).unwrap()
590     );
591     assert!(Opt::try_parse_from(["", "-a", "fOo"]).is_err());
592 }
593 
594 #[test]
vec_type_default_value()595 fn vec_type_default_value() {
596     #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
597     enum ArgChoice {
598         Foo,
599         Bar,
600         Baz,
601     }
602 
603     #[derive(Parser, PartialEq, Debug)]
604     struct Opt {
605         #[arg(
606             value_enum,
607             short,
608             long,
609             default_value = "foo,bar",
610             value_delimiter = ','
611         )]
612         arg: Vec<ArgChoice>,
613     }
614 
615     assert_eq!(
616         Opt {
617             arg: vec![ArgChoice::Foo, ArgChoice::Bar]
618         },
619         Opt::try_parse_from([""]).unwrap()
620     );
621 
622     assert_eq!(
623         Opt {
624             arg: vec![ArgChoice::Foo, ArgChoice::Baz]
625         },
626         Opt::try_parse_from(["", "-a", "foo,baz"]).unwrap()
627     );
628 }
629