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