1 use clap::{arg, error::ErrorKind, Arg, ArgAction, Command};
2 
3 #[test]
only_pos_follownull4 fn only_pos_follow() {
5     let r = Command::new("onlypos")
6         .args([arg!(f: -f [flag] "some opt"), arg!([arg] "some arg")])
7         .try_get_matches_from(vec!["", "--", "-f"]);
8     assert!(r.is_ok(), "{}", r.unwrap_err());
9     let m = r.unwrap();
10     assert!(m.contains_id("arg"));
11     assert!(!m.contains_id("f"));
12     assert_eq!(
13         m.get_one::<String>("arg").map(|v| v.as_str()).unwrap(),
14         "-f"
15     );
16 }
17 
18 #[test]
issue_946null19 fn issue_946() {
20     let r = Command::new("compiletest")
21         .arg(arg!(--exact    "filters match exactly").action(ArgAction::SetTrue))
22         .arg(
23             clap::Arg::new("filter")
24                 .index(1)
25                 .action(ArgAction::Set)
26                 .allow_hyphen_values(true)
27                 .help("filters to apply to output"),
28         )
29         .try_get_matches_from(vec!["compiletest", "--exact"]);
30     assert!(r.is_ok(), "{:#?}", r);
31     let matches = r.unwrap();
32 
33     assert!(*matches.get_one::<bool>("exact").expect("defaulted by clap"));
34     assert!(matches
35         .get_one::<String>("filter")
36         .map(|v| v.as_str())
37         .is_none());
38 }
39 
40 #[test]
positionalnull41 fn positional() {
42     let r = Command::new("positional")
43         .args([
44             arg!(-f --flag "some flag").action(ArgAction::SetTrue),
45             Arg::new("positional").index(1),
46         ])
47         .try_get_matches_from(vec!["", "-f", "test"]);
48     assert!(r.is_ok(), "{:#?}", r);
49     let m = r.unwrap();
50     assert!(m.contains_id("positional"));
51     assert!(*m.get_one::<bool>("flag").expect("defaulted by clap"));
52     assert_eq!(
53         m.get_one::<String>("positional")
54             .map(|v| v.as_str())
55             .unwrap(),
56         "test"
57     );
58 
59     let m = Command::new("positional")
60         .args([
61             arg!(-f --flag "some flag").action(ArgAction::SetTrue),
62             Arg::new("positional").index(1),
63         ])
64         .try_get_matches_from(vec!["", "test", "--flag"])
65         .unwrap();
66     assert!(m.contains_id("positional"));
67     assert!(*m.get_one::<bool>("flag").expect("defaulted by clap"));
68     assert_eq!(
69         m.get_one::<String>("positional")
70             .map(|v| v.as_str())
71             .unwrap(),
72         "test"
73     );
74 }
75 
76 #[test]
lots_o_valsnull77 fn lots_o_vals() {
78     let r = Command::new("opts")
79         .arg(arg!(<opt>... "some pos"))
80         .try_get_matches_from(vec![
81             "", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
82             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
83             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
84             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
85             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
86             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
87             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
88             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
89             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
90             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
91             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
92             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
93             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
94             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
95             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
96             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
97             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
98             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
99             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
100             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
101             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
102             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
103             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
104             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
105             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
106             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
107             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
108             "some",
109         ]);
110     assert!(r.is_ok(), "{}", r.unwrap_err());
111     let m = r.unwrap();
112     assert!(m.contains_id("opt"));
113     assert_eq!(m.get_many::<String>("opt").unwrap().count(), 297); // i.e. more than u8
114 }
115 
116 #[test]
positional_multiplenull117 fn positional_multiple() {
118     let r = Command::new("positional_multiple")
119         .args([
120             arg!(-f --flag "some flag").action(ArgAction::SetTrue),
121             Arg::new("positional")
122                 .index(1)
123                 .action(ArgAction::Set)
124                 .num_args(1..),
125         ])
126         .try_get_matches_from(vec!["", "-f", "test1", "test2", "test3"]);
127     assert!(r.is_ok(), "{:#?}", r);
128     let m = r.unwrap();
129     assert!(m.contains_id("positional"));
130     assert!(*m.get_one::<bool>("flag").expect("defaulted by clap"));
131     assert_eq!(
132         &*m.get_many::<String>("positional")
133             .unwrap()
134             .map(|v| v.as_str())
135             .collect::<Vec<_>>(),
136         ["test1", "test2", "test3"]
137     );
138 }
139 
140 #[test]
positional_multiple_3null141 fn positional_multiple_3() {
142     let r = Command::new("positional_multiple")
143         .args([
144             arg!(-f  --flag "some flag").action(ArgAction::SetTrue),
145             Arg::new("positional")
146                 .index(1)
147                 .action(ArgAction::Set)
148                 .num_args(1..),
149         ])
150         .try_get_matches_from(vec!["", "test1", "test2", "test3", "--flag"]);
151     assert!(r.is_ok(), "{:#?}", r);
152     let m = r.unwrap();
153     assert!(m.contains_id("positional"));
154     assert!(*m.get_one::<bool>("flag").expect("defaulted by clap"));
155     assert_eq!(
156         &*m.get_many::<String>("positional")
157             .unwrap()
158             .map(|v| v.as_str())
159             .collect::<Vec<_>>(),
160         ["test1", "test2", "test3"]
161     );
162 }
163 
164 #[test]
positional_multiple_2null165 fn positional_multiple_2() {
166     let result = Command::new("positional_multiple")
167         .args([arg!(-f --flag "some flag"), Arg::new("positional").index(1)])
168         .try_get_matches_from(vec!["", "-f", "test1", "test2", "test3"]);
169     assert!(result.is_err());
170     let err = result.err().unwrap();
171     assert_eq!(err.kind(), ErrorKind::UnknownArgument);
172 }
173 
174 #[test]
positional_possible_valuesnull175 fn positional_possible_values() {
176     let r = Command::new("positional_possible_values")
177         .args([
178             arg!(-f --flag "some flag").action(ArgAction::SetTrue),
179             Arg::new("positional").index(1).value_parser(["test123"]),
180         ])
181         .try_get_matches_from(vec!["", "-f", "test123"]);
182     assert!(r.is_ok(), "{r:#?}");
183     let m = r.unwrap();
184     assert!(m.contains_id("positional"));
185     assert!(*m.get_one::<bool>("flag").expect("defaulted by clap"));
186     assert_eq!(
187         &*m.get_many::<String>("positional")
188             .unwrap()
189             .map(|v| v.as_str())
190             .collect::<Vec<_>>(),
191         ["test123"]
192     );
193 }
194 
195 #[test]
create_positionalnull196 fn create_positional() {
197     let _ = Command::new("test")
198         .arg(Arg::new("test").index(1).help("testing testing"))
199         .try_get_matches_from(vec![""])
200         .unwrap();
201 }
202 
203 #[test]
positional_hyphen_does_not_panicnull204 fn positional_hyphen_does_not_panic() {
205     let _ = Command::new("test")
206         .arg(Arg::new("dummy"))
207         .try_get_matches_from(vec!["test", "-"])
208         .unwrap();
209 }
210 
211 #[test]
single_positional_usage_stringnull212 fn single_positional_usage_string() {
213     let mut cmd = Command::new("test").arg(arg!([FILE] "some file"));
214     crate::utils::assert_eq(cmd.render_usage().to_string(), "Usage: test [FILE]");
215 }
216 
217 #[test]
single_positional_multiple_usage_stringnull218 fn single_positional_multiple_usage_string() {
219     let mut cmd = Command::new("test").arg(arg!([FILE]... "some file"));
220     crate::utils::assert_eq(cmd.render_usage().to_string(), "Usage: test [FILE]...");
221 }
222 
223 #[test]
multiple_positional_usage_stringnull224 fn multiple_positional_usage_string() {
225     let mut cmd = Command::new("test")
226         .arg(arg!([FILE] "some file"))
227         .arg(arg!([FILES]... "some file"));
228     crate::utils::assert_eq(
229         cmd.render_usage().to_string(),
230         "\
231 Usage: test [FILE] [FILES]...",
232     );
233 }
234 
235 #[test]
multiple_positional_one_required_usage_stringnull236 fn multiple_positional_one_required_usage_string() {
237     let mut cmd = Command::new("test")
238         .arg(arg!(<FILE> "some file"))
239         .arg(arg!([FILES]... "some file"));
240     crate::utils::assert_eq(
241         cmd.render_usage().to_string(),
242         "Usage: test <FILE> [FILES]...",
243     );
244 }
245 
246 #[test]
single_positional_required_usage_stringnull247 fn single_positional_required_usage_string() {
248     let mut cmd = Command::new("test").arg(arg!(<FILE> "some file"));
249     crate::utils::assert_eq(cmd.render_usage().to_string(), "Usage: test <FILE>");
250 }
251 
252 // This tests a programmer error and will only succeed with debug_assertions
253 #[cfg(debug_assertions)]
254 #[test]
255 #[should_panic = "Found non-required positional argument \
256 with a lower index than a required positional argument"]
missing_requirednull257 fn missing_required() {
258     let _ = Command::new("test")
259         .arg(arg!([FILE1] "some file"))
260         .arg(arg!(<FILE2> "some file"))
261         .try_get_matches_from(vec![""]);
262 }
263 
264 #[test]
missing_required_2null265 fn missing_required_2() {
266     let r = Command::new("test")
267         .arg(arg!(<FILE1> "some file"))
268         .arg(arg!(<FILE2> "some file"))
269         .try_get_matches_from(vec!["test", "file"]);
270     assert!(r.is_err());
271     assert_eq!(r.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
272 }
273 
274 #[test]
last_positionalnull275 fn last_positional() {
276     let r = Command::new("test")
277         .arg(arg!(<TARGET> "some target"))
278         .arg(arg!([CORPUS] "some corpus"))
279         .arg(arg!([ARGS]... "some file").last(true))
280         .try_get_matches_from(vec!["test", "tgt", "--", "arg"]);
281     assert!(r.is_ok(), "{}", r.unwrap_err());
282     let m = r.unwrap();
283     assert_eq!(
284         m.get_many::<String>("ARGS")
285             .unwrap()
286             .map(|v| v.as_str())
287             .collect::<Vec<_>>(),
288         ["arg"]
289     );
290 }
291 
292 #[test]
last_positional_no_double_dashnull293 fn last_positional_no_double_dash() {
294     let r = Command::new("test")
295         .arg(arg!(<TARGET> "some target"))
296         .arg(arg!([CORPUS] "some corpus"))
297         .arg(arg!([ARGS]... "some file").last(true))
298         .try_get_matches_from(vec!["test", "tgt", "crp", "arg"]);
299     assert!(r.is_err());
300     assert_eq!(r.unwrap_err().kind(), ErrorKind::UnknownArgument);
301 }
302 
303 #[test]
last_positional_second_to_last_multnull304 fn last_positional_second_to_last_mult() {
305     let r = Command::new("test")
306         .arg(arg!(<TARGET> "some target"))
307         .arg(arg!([CORPUS]... "some corpus"))
308         .arg(arg!([ARGS]... "some file").last(true))
309         .try_get_matches_from(vec!["test", "tgt", "crp1", "crp2", "--", "arg"]);
310     assert!(r.is_ok(), "{:?}", r.unwrap_err().kind());
311 }
312 
313 #[cfg(debug_assertions)]
314 #[test]
315 #[should_panic = "Argument 'arg' is a positional argument and can't have short or long name versions"]
positional_arg_with_longnull316 fn positional_arg_with_long() {
317     use clap::{Arg, Command};
318 
319     let _ = Command::new("test")
320         .arg(Arg::new("arg").index(1).long("arg"))
321         .try_get_matches();
322 }
323 
324 #[cfg(debug_assertions)]
325 #[test]
326 #[should_panic = "Argument 'arg' is a positional argument and can't have short or long name versions"]
positional_arg_with_shortnull327 fn positional_arg_with_short() {
328     use clap::{Arg, Command};
329 
330     let _ = Command::new("test")
331         .arg(Arg::new("arg").index(1).short('a'))
332         .try_get_matches();
333 }
334 
335 #[test]
ignore_hyphen_values_on_lastnull336 fn ignore_hyphen_values_on_last() {
337     let cmd = clap::Command::new("foo")
338         .arg(
339             clap::Arg::new("cmd")
340                 .num_args(1..)
341                 .last(true)
342                 .allow_hyphen_values(true),
343         )
344         .arg(
345             clap::Arg::new("name")
346                 .long("name")
347                 .short('n')
348                 .action(ArgAction::Set)
349                 .required(false),
350         );
351 
352     let matches = cmd.try_get_matches_from(["test", "-n", "foo"]).unwrap();
353     assert_eq!(
354         matches.get_one::<String>("name").map(|v| v.as_str()),
355         Some("foo")
356     );
357 }
358