1use clap::{arg, Arg, ArgAction, Command};
2
3#[test]
4fn multiple_occurrences_of_flags_long() {
5    let m = Command::new("mo_flags_long")
6        .args_override_self(true)
7        .arg(arg!(--multflag "allowed multiple flag").action(ArgAction::SetTrue))
8        .arg(arg!(--flag "disallowed multiple flag").action(ArgAction::SetTrue))
9        .try_get_matches_from(vec!["", "--multflag", "--flag", "--multflag"])
10        .unwrap();
11    assert!(m.contains_id("multflag"));
12    assert_eq!(m.get_one::<bool>("multflag").copied(), Some(true));
13    assert!(m.contains_id("flag"));
14    assert_eq!(m.get_one::<bool>("flag").copied(), Some(true));
15}
16
17#[test]
18fn multiple_occurrences_of_flags_short() {
19    let m = Command::new("mo_flags_short")
20        .args_override_self(true)
21        .arg(arg!(-m --multflag "allowed multiple flag").action(ArgAction::SetTrue))
22        .arg(arg!(-f --flag "disallowed multiple flag").action(ArgAction::SetTrue))
23        .try_get_matches_from(vec!["", "-m", "-f", "-m"])
24        .unwrap();
25    assert!(m.contains_id("multflag"));
26    assert_eq!(m.get_one::<bool>("multflag").copied(), Some(true));
27    assert!(m.contains_id("flag"));
28    assert_eq!(m.get_one::<bool>("flag").copied(), Some(true));
29}
30
31#[test]
32fn multiple_occurrences_of_positional() {
33    let cmd = Command::new("test").arg(Arg::new("multi").num_args(1..).action(ArgAction::Append));
34
35    let m = cmd
36        .clone()
37        .try_get_matches_from(["test"])
38        .expect("zero occurrences work");
39    assert!(!m.contains_id("multi"));
40    assert!(m.get_many::<String>("multi").is_none());
41
42    let m = cmd
43        .clone()
44        .try_get_matches_from(["test", "one"])
45        .expect("single occurrence work");
46    assert!(m.contains_id("multi"));
47    assert_eq!(
48        m.get_many::<String>("multi")
49            .unwrap()
50            .map(|v| v.as_str())
51            .collect::<Vec<_>>(),
52        ["one"]
53    );
54
55    let m = cmd
56        .clone()
57        .try_get_matches_from(["test", "one", "two", "three", "four"])
58        .expect("many occurrences work");
59    assert!(m.contains_id("multi"));
60    assert_eq!(
61        m.get_many::<String>("multi")
62            .unwrap()
63            .map(|v| v.as_str())
64            .collect::<Vec<_>>(),
65        ["one", "two", "three", "four"]
66    );
67}
68
69#[test]
70fn multiple_occurrences_of_flags_large_quantity() {
71    let cmd = Command::new("mo_flags_large_qty")
72        .arg(arg!(-m --multflag "allowed multiple flag").action(ArgAction::Count));
73
74    let args: Vec<&str> = vec![""]
75        .into_iter()
76        .chain(vec!["-m"; 200].into_iter())
77        .collect();
78    let m = cmd.clone().try_get_matches_from(args).unwrap();
79    assert!(m.contains_id("multflag"));
80    assert_eq!(m.get_one::<u8>("multflag").copied(), Some(200));
81
82    let args: Vec<&str> = vec![""]
83        .into_iter()
84        .chain(vec!["-m"; 500].into_iter())
85        .collect();
86    let m = cmd.try_get_matches_from(args).unwrap();
87    assert!(m.contains_id("multflag"));
88    assert_eq!(m.get_one::<u8>("multflag").copied(), Some(u8::MAX));
89}
90
91#[cfg(feature = "env")]
92#[test]
93fn multiple_occurrences_of_before_env() {
94    let cmd = Command::new("mo_before_env").arg(
95        Arg::new("verbose")
96            .env("VERBOSE")
97            .short('v')
98            .long("verbose")
99            .action(ArgAction::Count),
100    );
101
102    let m = cmd.clone().try_get_matches_from(vec![""]);
103    assert!(m.is_ok(), "{}", m.unwrap_err());
104    let m = m.unwrap();
105    assert_eq!(m.get_one::<u8>("verbose").copied(), Some(0));
106
107    let m = cmd.clone().try_get_matches_from(vec!["", "-v"]);
108    assert!(m.is_ok(), "{}", m.unwrap_err());
109    let m = m.unwrap();
110    assert_eq!(m.get_one::<u8>("verbose").copied(), Some(1));
111
112    let m = cmd.clone().try_get_matches_from(vec!["", "-vv"]);
113    assert!(m.is_ok(), "{}", m.unwrap_err());
114    let m = m.unwrap();
115    assert_eq!(m.get_one::<u8>("verbose").copied(), Some(2));
116
117    let m = cmd.clone().try_get_matches_from(vec!["", "-vvv"]);
118    assert!(m.is_ok(), "{}", m.unwrap_err());
119    let m = m.unwrap();
120    assert_eq!(m.get_one::<u8>("verbose").copied(), Some(3));
121}
122
123#[cfg(feature = "env")]
124#[test]
125fn multiple_occurrences_of_after_env() {
126    let cmd = Command::new("mo_after_env").arg(
127        Arg::new("verbose")
128            .short('v')
129            .long("verbose")
130            .action(ArgAction::Count)
131            .env("VERBOSE"),
132    );
133
134    let m = cmd.clone().try_get_matches_from(vec![""]);
135    assert!(m.is_ok(), "{}", m.unwrap_err());
136    let m = m.unwrap();
137    assert_eq!(m.get_one::<u8>("verbose").copied(), Some(0));
138
139    let m = cmd.clone().try_get_matches_from(vec!["", "-v"]);
140    assert!(m.is_ok(), "{}", m.unwrap_err());
141    let m = m.unwrap();
142    assert_eq!(m.get_one::<u8>("verbose").copied(), Some(1));
143
144    let m = cmd.clone().try_get_matches_from(vec!["", "-vv"]);
145    assert!(m.is_ok(), "{}", m.unwrap_err());
146    let m = m.unwrap();
147    assert_eq!(m.get_one::<u8>("verbose").copied(), Some(2));
148
149    let m = cmd.clone().try_get_matches_from(vec!["", "-vvv"]);
150    assert!(m.is_ok(), "{}", m.unwrap_err());
151    let m = m.unwrap();
152    assert_eq!(m.get_one::<u8>("verbose").copied(), Some(3));
153}
154