1 use clap::{arg, error::ErrorKind, Arg, ArgAction, ArgMatches, Command};
2
3 #[cfg(feature = "error-context")]
4 use super::utils;
5
6 #[test]
require_equals_failnull7 fn require_equals_fail() {
8 let res = Command::new("prog")
9 .arg(
10 Arg::new("cfg")
11 .require_equals(true)
12 .value_parser(clap::builder::NonEmptyStringValueParser::new())
13 .action(ArgAction::Set)
14 .long("config"),
15 )
16 .try_get_matches_from(vec!["prog", "--config", "file.conf"]);
17 assert!(res.is_err());
18 assert_eq!(res.unwrap_err().kind(), ErrorKind::NoEquals);
19 }
20
21 #[test]
22 #[cfg(feature = "error-context")]
require_equals_fail_messagenull23 fn require_equals_fail_message() {
24 static NO_EQUALS: &str = "error: equal sign is needed when assigning values to '--config=<cfg>'
25
26 Usage: prog [OPTIONS]
27
28 For more information, try '--help'.
29 ";
30 let cmd = Command::new("prog").arg(
31 Arg::new("cfg")
32 .require_equals(true)
33 .action(ArgAction::Set)
34 .long("config"),
35 );
36 utils::assert_output(cmd, "prog --config file.conf", NO_EQUALS, true);
37 }
38
39 #[test]
require_equals_min_values_zeronull40 fn require_equals_min_values_zero() {
41 let res = Command::new("prog")
42 .arg(
43 Arg::new("cfg")
44 .action(ArgAction::Set)
45 .require_equals(true)
46 .num_args(0..)
47 .long("config"),
48 )
49 .arg(Arg::new("cmd"))
50 .try_get_matches_from(vec!["prog", "--config", "cmd"]);
51 assert!(res.is_ok(), "{}", res.unwrap_err());
52 let m = res.unwrap();
53 assert!(m.contains_id("cfg"));
54 assert_eq!(m.get_one::<String>("cmd").map(|v| v.as_str()), Some("cmd"));
55 }
56
57 #[test]
double_hyphen_as_valuenull58 fn double_hyphen_as_value() {
59 let res = Command::new("prog")
60 .arg(
61 Arg::new("cfg")
62 .action(ArgAction::Set)
63 .allow_hyphen_values(true)
64 .long("config"),
65 )
66 .try_get_matches_from(vec!["prog", "--config", "--"]);
67 assert!(res.is_ok(), "{:?}", res);
68 assert_eq!(
69 res.unwrap().get_one::<String>("cfg").map(|v| v.as_str()),
70 Some("--")
71 );
72 }
73
74 #[test]
require_equals_no_empty_values_failnull75 fn require_equals_no_empty_values_fail() {
76 let res = Command::new("prog")
77 .arg(
78 Arg::new("cfg")
79 .action(ArgAction::Set)
80 .require_equals(true)
81 .value_parser(clap::builder::NonEmptyStringValueParser::new())
82 .long("config"),
83 )
84 .arg(Arg::new("some"))
85 .try_get_matches_from(vec!["prog", "--config=", "file.conf"]);
86 assert!(res.is_err());
87 assert_eq!(res.unwrap_err().kind(), ErrorKind::InvalidValue);
88 }
89
90 #[test]
require_equals_empty_vals_passnull91 fn require_equals_empty_vals_pass() {
92 let res = Command::new("prog")
93 .arg(
94 Arg::new("cfg")
95 .action(ArgAction::Set)
96 .require_equals(true)
97 .long("config"),
98 )
99 .try_get_matches_from(vec!["prog", "--config="]);
100 assert!(res.is_ok(), "{}", res.unwrap_err());
101 }
102
103 #[test]
require_equals_passnull104 fn require_equals_pass() {
105 let res = Command::new("prog")
106 .arg(
107 Arg::new("cfg")
108 .action(ArgAction::Set)
109 .require_equals(true)
110 .long("config"),
111 )
112 .try_get_matches_from(vec!["prog", "--config=file.conf"]);
113 assert!(res.is_ok(), "{}", res.unwrap_err());
114 }
115
116 #[test]
stdin_charnull117 fn stdin_char() {
118 let r = Command::new("opts")
119 .arg(arg!(f: -f [flag] "some flag"))
120 .try_get_matches_from(vec!["", "-f", "-"]);
121 assert!(r.is_ok(), "{}", r.unwrap_err());
122 let m = r.unwrap();
123 assert!(m.contains_id("f"));
124 assert_eq!(m.get_one::<String>("f").map(|v| v.as_str()).unwrap(), "-");
125 }
126
127 #[test]
opts_using_shortnull128 fn opts_using_short() {
129 let r = Command::new("opts")
130 .args([
131 arg!(f: -f [flag] "some flag"),
132 arg!(c: -c [color] "some other flag"),
133 ])
134 .try_get_matches_from(vec!["", "-f", "some", "-c", "other"]);
135 assert!(r.is_ok(), "{}", r.unwrap_err());
136 let m = r.unwrap();
137 assert!(m.contains_id("f"));
138 assert_eq!(
139 m.get_one::<String>("f").map(|v| v.as_str()).unwrap(),
140 "some"
141 );
142 assert!(m.contains_id("c"));
143 assert_eq!(
144 m.get_one::<String>("c").map(|v| v.as_str()).unwrap(),
145 "other"
146 );
147 }
148
149 #[test]
lots_o_valsnull150 fn lots_o_vals() {
151 let r = Command::new("opts")
152 .arg(arg!(o: -o <opt> "some opt").num_args(1..).required(true))
153 .try_get_matches_from(vec![
154 "", "-o", "some", "some", "some", "some", "some", "some", "some", "some", "some",
155 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
156 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
157 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
158 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
159 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
160 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
161 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
162 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
163 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
164 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
165 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
166 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
167 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
168 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
169 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
170 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
171 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
172 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
173 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
174 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
175 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
176 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
177 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
178 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
179 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
180 "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
181 "some", "some",
182 ]);
183 assert!(r.is_ok(), "{}", r.unwrap_err());
184 let m = r.unwrap();
185 assert!(m.contains_id("o"));
186 assert_eq!(m.get_many::<String>("o").unwrap().count(), 297); // i.e. more than u8
187 }
188
189 #[test]
opts_using_long_spacenull190 fn opts_using_long_space() {
191 let r = Command::new("opts")
192 .args([
193 arg!(--flag [flag] "some flag"),
194 arg!(--color [color] "some other flag"),
195 ])
196 .try_get_matches_from(vec!["", "--flag", "some", "--color", "other"]);
197 assert!(r.is_ok(), "{}", r.unwrap_err());
198 let m = r.unwrap();
199 assert!(m.contains_id("flag"));
200 assert_eq!(
201 m.get_one::<String>("flag").map(|v| v.as_str()).unwrap(),
202 "some"
203 );
204 assert!(m.contains_id("color"));
205 assert_eq!(
206 m.get_one::<String>("color").map(|v| v.as_str()).unwrap(),
207 "other"
208 );
209 }
210
211 #[test]
opts_using_long_equalsnull212 fn opts_using_long_equals() {
213 let r = Command::new("opts")
214 .args([
215 arg!(--flag [flag] "some flag"),
216 arg!(--color [color] "some other flag"),
217 ])
218 .try_get_matches_from(vec!["", "--flag=some", "--color=other"]);
219 assert!(r.is_ok(), "{}", r.unwrap_err());
220 let m = r.unwrap();
221 assert!(m.contains_id("flag"));
222 assert_eq!(
223 m.get_one::<String>("flag").map(|v| v.as_str()).unwrap(),
224 "some"
225 );
226 assert!(m.contains_id("color"));
227 assert_eq!(
228 m.get_one::<String>("color").map(|v| v.as_str()).unwrap(),
229 "other"
230 );
231 }
232
233 #[test]
opts_using_mixednull234 fn opts_using_mixed() {
235 let r = Command::new("opts")
236 .args([
237 arg!(-f --flag [flag] "some flag"),
238 arg!(-c --color [color] "some other flag"),
239 ])
240 .try_get_matches_from(vec!["", "-f", "some", "--color", "other"]);
241 assert!(r.is_ok(), "{}", r.unwrap_err());
242 let m = r.unwrap();
243 assert!(m.contains_id("flag"));
244 assert_eq!(
245 m.get_one::<String>("flag").map(|v| v.as_str()).unwrap(),
246 "some"
247 );
248 assert!(m.contains_id("color"));
249 assert_eq!(
250 m.get_one::<String>("color").map(|v| v.as_str()).unwrap(),
251 "other"
252 );
253 }
254
255 #[test]
opts_using_mixed2null256 fn opts_using_mixed2() {
257 let r = Command::new("opts")
258 .args([
259 arg!(-f --flag [flag] "some flag"),
260 arg!(-c --color [color] "some other flag"),
261 ])
262 .try_get_matches_from(vec!["", "--flag=some", "-c", "other"]);
263 assert!(r.is_ok(), "{}", r.unwrap_err());
264 let m = r.unwrap();
265 assert!(m.contains_id("flag"));
266 assert_eq!(
267 m.get_one::<String>("flag").map(|v| v.as_str()).unwrap(),
268 "some"
269 );
270 assert!(m.contains_id("color"));
271 assert_eq!(
272 m.get_one::<String>("color").map(|v| v.as_str()).unwrap(),
273 "other"
274 );
275 }
276
277 #[test]
default_values_user_valuenull278 fn default_values_user_value() {
279 let r = Command::new("df")
280 .arg(arg!(o: -o [opt] "some opt").default_value("default"))
281 .try_get_matches_from(vec!["", "-o", "value"]);
282 assert!(r.is_ok(), "{}", r.unwrap_err());
283 let m = r.unwrap();
284 assert!(m.contains_id("o"));
285 assert_eq!(
286 m.get_one::<String>("o").map(|v| v.as_str()).unwrap(),
287 "value"
288 );
289 }
290
291 #[test]
multiple_vals_pos_arg_equalsnull292 fn multiple_vals_pos_arg_equals() {
293 let r = Command::new("mvae")
294 .arg(arg!(o: -o [opt] ... "some opt"))
295 .arg(arg!([file] "some file"))
296 .try_get_matches_from(vec!["", "-o=1", "some"]);
297 assert!(r.is_ok(), "{}", r.unwrap_err());
298 let m = r.unwrap();
299 assert!(m.contains_id("o"));
300 assert_eq!(m.get_one::<String>("o").map(|v| v.as_str()).unwrap(), "1");
301 assert!(m.contains_id("file"));
302 assert_eq!(
303 m.get_one::<String>("file").map(|v| v.as_str()).unwrap(),
304 "some"
305 );
306 }
307
308 #[test]
require_delims_no_delimnull309 fn require_delims_no_delim() {
310 let r = Command::new("mvae")
311 .arg(arg!(o: -o [opt] ... "some opt").value_delimiter(','))
312 .arg(arg!([file] "some file"))
313 .try_get_matches_from(vec!["mvae", "-o", "1", "2", "some"]);
314 assert!(r.is_err());
315 let err = r.unwrap_err();
316 assert_eq!(err.kind(), ErrorKind::UnknownArgument);
317 }
318
319 #[test]
require_delimsnull320 fn require_delims() {
321 let r = Command::new("mvae")
322 .arg(
323 arg!(o: -o <opt> "some opt")
324 .value_delimiter(',')
325 .required(true),
326 )
327 .arg(arg!([file] "some file"))
328 .try_get_matches_from(vec!["", "-o", "1,2", "some"]);
329 assert!(r.is_ok(), "{}", r.unwrap_err());
330 let m = r.unwrap();
331 assert!(m.contains_id("o"));
332 assert_eq!(
333 m.get_many::<String>("o")
334 .unwrap()
335 .map(|v| v.as_str())
336 .collect::<Vec<_>>(),
337 ["1", "2"]
338 );
339 assert!(m.contains_id("file"));
340 assert_eq!(
341 m.get_one::<String>("file").map(|v| v.as_str()).unwrap(),
342 "some"
343 );
344 }
345
346 #[test]
leading_hyphen_passnull347 fn leading_hyphen_pass() {
348 let r = Command::new("mvae")
349 .arg(
350 arg!(o: -o <opt> "some opt")
351 .required(true)
352 .num_args(1..)
353 .allow_hyphen_values(true),
354 )
355 .try_get_matches_from(vec!["", "-o", "-2", "3"]);
356 assert!(r.is_ok(), "{}", r.unwrap_err());
357 let m = r.unwrap();
358 assert!(m.contains_id("o"));
359 assert_eq!(
360 m.get_many::<String>("o")
361 .unwrap()
362 .map(|v| v.as_str())
363 .collect::<Vec<_>>(),
364 ["-2", "3"]
365 );
366 }
367
368 #[test]
leading_hyphen_failnull369 fn leading_hyphen_fail() {
370 let r = Command::new("mvae")
371 .arg(arg!(o: -o <opt> "some opt").required(true))
372 .try_get_matches_from(vec!["", "-o", "-2"]);
373 assert!(r.is_err());
374 let m = r.unwrap_err();
375 assert_eq!(m.kind(), ErrorKind::UnknownArgument);
376 }
377
378 #[test]
leading_hyphen_with_flag_afternull379 fn leading_hyphen_with_flag_after() {
380 let r = Command::new("mvae")
381 .arg(
382 arg!(o: -o <opt> "some opt")
383 .required(true)
384 .num_args(1..)
385 .allow_hyphen_values(true),
386 )
387 .arg(arg!(f: -f "some flag").action(ArgAction::SetTrue))
388 .try_get_matches_from(vec!["", "-o", "-2", "-f"]);
389 assert!(r.is_ok(), "{}", r.unwrap_err());
390 let m = r.unwrap();
391 assert!(m.contains_id("o"));
392 assert_eq!(
393 m.get_many::<String>("o")
394 .unwrap()
395 .map(|v| v.as_str())
396 .collect::<Vec<_>>(),
397 ["-2", "-f"]
398 );
399 assert!(!*m.get_one::<bool>("f").expect("defaulted by clap"));
400 }
401
402 #[test]
leading_hyphen_with_flag_beforenull403 fn leading_hyphen_with_flag_before() {
404 let r = Command::new("mvae")
405 .arg(arg!(o: -o [opt] ... "some opt").allow_hyphen_values(true))
406 .arg(arg!(f: -f "some flag").action(ArgAction::SetTrue))
407 .try_get_matches_from(vec!["", "-f", "-o", "-2"]);
408 assert!(r.is_ok(), "{}", r.unwrap_err());
409 let m = r.unwrap();
410 assert!(m.contains_id("o"));
411 assert_eq!(
412 m.get_many::<String>("o")
413 .unwrap()
414 .map(|v| v.as_str())
415 .collect::<Vec<_>>(),
416 ["-2"]
417 );
418 assert!(*m.get_one::<bool>("f").expect("defaulted by clap"));
419 }
420
421 #[test]
leading_hyphen_with_only_pos_followsnull422 fn leading_hyphen_with_only_pos_follows() {
423 let r = Command::new("mvae")
424 .arg(
425 arg!(o: -o [opt] ... "some opt")
426 .action(ArgAction::Set)
427 .allow_hyphen_values(true),
428 )
429 .arg(arg!([arg] "some arg"))
430 .try_get_matches_from(vec!["", "-o", "-2", "--", "val"]);
431 assert!(r.is_ok(), "{:?}", r);
432 let m = r.unwrap();
433 assert!(m.contains_id("o"));
434 assert_eq!(
435 m.get_many::<String>("o")
436 .unwrap()
437 .map(|v| v.as_str())
438 .collect::<Vec<_>>(),
439 ["-2"]
440 );
441 assert_eq!(m.get_one::<String>("arg").map(|v| v.as_str()), Some("val"));
442 }
443
444 #[test]
445 #[cfg(feature = "suggestions")]
446 #[cfg(feature = "error-context")]
did_you_meannull447 fn did_you_mean() {
448 static DYM: &str = "\
449 error: unexpected argument '--optio' found
450
451 note: argument '--option' exists
452
453 Usage: clap-test --option <opt>... [positional] [positional2] [positional3]...
454
455 For more information, try '--help'.
456 ";
457
458 utils::assert_output(utils::complex_app(), "clap-test --optio=foo", DYM, true);
459 }
460
461 #[test]
issue_1047_min_zero_vals_default_valnull462 fn issue_1047_min_zero_vals_default_val() {
463 let m = Command::new("foo")
464 .arg(
465 Arg::new("del")
466 .short('d')
467 .long("del")
468 .action(ArgAction::Set)
469 .require_equals(true)
470 .num_args(0..)
471 .default_missing_value("default"),
472 )
473 .try_get_matches_from(vec!["foo", "-d"])
474 .unwrap();
475 assert_eq!(
476 m.get_one::<String>("del").map(|v| v.as_str()),
477 Some("default")
478 );
479 }
480
issue_1105_setupnull481 fn issue_1105_setup(argv: Vec<&'static str>) -> Result<ArgMatches, clap::Error> {
482 Command::new("opts")
483 .arg(arg!(-o --option <opt> "some option").required(true))
484 .arg(arg!(--flag "some flag"))
485 .try_get_matches_from(argv)
486 }
487
488 #[test]
489 fn issue_1105_empty_value_long_fail() {
490 let r = issue_1105_setup(vec!["cmd", "--option", "--flag"]);
491 assert!(r.is_err());
492 assert_eq!(r.unwrap_err().kind(), ErrorKind::InvalidValue);
493 }
494
495 #[test]
issue_1105_empty_value_long_explicitnull496 fn issue_1105_empty_value_long_explicit() {
497 let r = issue_1105_setup(vec!["cmd", "--option", ""]);
498 assert!(r.is_ok(), "{}", r.unwrap_err());
499 let m = r.unwrap();
500 assert_eq!(m.get_one::<String>("option").map(|v| v.as_str()), Some(""));
501 }
502
503 #[test]
issue_1105_empty_value_long_equalsnull504 fn issue_1105_empty_value_long_equals() {
505 let r = issue_1105_setup(vec!["cmd", "--option="]);
506 assert!(r.is_ok(), "{}", r.unwrap_err());
507 let m = r.unwrap();
508 assert_eq!(m.get_one::<String>("option").map(|v| v.as_str()), Some(""));
509 }
510
511 #[test]
issue_1105_empty_value_short_failnull512 fn issue_1105_empty_value_short_fail() {
513 let r = issue_1105_setup(vec!["cmd", "-o", "--flag"]);
514 assert!(r.is_err());
515 assert_eq!(r.unwrap_err().kind(), ErrorKind::InvalidValue);
516 }
517
518 #[test]
issue_1105_empty_value_short_explicitnull519 fn issue_1105_empty_value_short_explicit() {
520 let r = issue_1105_setup(vec!["cmd", "-o", ""]);
521 assert!(r.is_ok(), "{}", r.unwrap_err());
522 let m = r.unwrap();
523 assert_eq!(m.get_one::<String>("option").map(|v| v.as_str()), Some(""));
524 }
525
526 #[test]
issue_1105_empty_value_short_equalsnull527 fn issue_1105_empty_value_short_equals() {
528 let r = issue_1105_setup(vec!["cmd", "-o="]);
529 assert!(r.is_ok(), "{}", r.unwrap_err());
530 let m = r.unwrap();
531 assert_eq!(m.get_one::<String>("option").map(|v| v.as_str()), Some(""));
532 }
533
534 #[test]
issue_1105_empty_value_short_explicit_no_spacenull535 fn issue_1105_empty_value_short_explicit_no_space() {
536 let r = issue_1105_setup(vec!["cmd", "-o", ""]);
537 assert!(r.is_ok(), "{}", r.unwrap_err());
538 let m = r.unwrap();
539 assert_eq!(m.get_one::<String>("option").map(|v| v.as_str()), Some(""));
540 }
541
542 #[test]
543 #[cfg(feature = "suggestions")]
544 #[cfg(feature = "error-context")]
issue_1073_suboptimal_flag_suggestionnull545 fn issue_1073_suboptimal_flag_suggestion() {
546 static DYM_ISSUE_1073: &str = "\
547 error: unexpected argument '--files-without-matches' found
548
549 note: argument '--files-without-match' exists
550
551 Usage: ripgrep-616 --files-without-match
552
553 For more information, try '--help'.
554 ";
555
556 let cmd = Command::new("ripgrep-616")
557 .arg(
558 Arg::new("files-with-matches")
559 .long("files-with-matches")
560 .action(ArgAction::SetTrue),
561 )
562 .arg(
563 Arg::new("files-without-match")
564 .long("files-without-match")
565 .action(ArgAction::SetTrue),
566 );
567 utils::assert_output(
568 cmd,
569 "ripgrep-616 --files-without-matches",
570 DYM_ISSUE_1073,
571 true,
572 );
573 }
574
575 #[test]
short_non_ascii_no_spacenull576 fn short_non_ascii_no_space() {
577 let matches = Command::new("cmd")
578 .arg(arg!(opt: -'磨' <opt>).required(true))
579 .try_get_matches_from(["test", "-磨VALUE"])
580 .unwrap();
581
582 assert_eq!(
583 "VALUE",
584 matches
585 .get_one::<String>("opt")
586 .map(|v| v.as_str())
587 .unwrap()
588 );
589 }
590
591 #[test]
short_eq_val_starts_with_eqnull592 fn short_eq_val_starts_with_eq() {
593 let matches = Command::new("cmd")
594 .arg(arg!(opt: -f <opt>).required(true))
595 .try_get_matches_from(["test", "-f==value"])
596 .unwrap();
597
598 assert_eq!(
599 "=value",
600 matches
601 .get_one::<String>("opt")
602 .map(|v| v.as_str())
603 .unwrap()
604 );
605 }
606
607 #[test]
long_eq_val_starts_with_eqnull608 fn long_eq_val_starts_with_eq() {
609 let matches = Command::new("cmd")
610 .arg(arg!(opt: --foo <opt>).required(true))
611 .try_get_matches_from(["test", "--foo==value"])
612 .unwrap();
613
614 assert_eq!(
615 "=value",
616 matches
617 .get_one::<String>("opt")
618 .map(|v| v.as_str())
619 .unwrap()
620 );
621 }
622
623 #[test]
issue_2022_get_flags_misusenull624 fn issue_2022_get_flags_misuse() {
625 let cmd = Command::new("test")
626 .next_help_heading(Some("test"))
627 .arg(Arg::new("a").long("a").default_value("32"));
628 let matches = cmd.try_get_matches_from([""]).unwrap();
629 assert!(matches.get_one::<String>("a").map(|v| v.as_str()).is_some())
630 }
631
632 #[test]
issue_2279null633 fn issue_2279() {
634 let before_help_heading = Command::new("cmd")
635 .arg(Arg::new("foo").short('f').default_value("bar"))
636 .next_help_heading(Some("This causes default_value to be ignored"))
637 .try_get_matches_from([""])
638 .unwrap();
639
640 assert_eq!(
641 before_help_heading
642 .get_one::<String>("foo")
643 .map(|v| v.as_str()),
644 Some("bar")
645 );
646
647 let after_help_heading = Command::new("cmd")
648 .next_help_heading(Some("This causes default_value to be ignored"))
649 .arg(Arg::new("foo").short('f').default_value("bar"))
650 .try_get_matches_from([""])
651 .unwrap();
652
653 assert_eq!(
654 after_help_heading
655 .get_one::<String>("foo")
656 .map(|v| v.as_str()),
657 Some("bar")
658 );
659 }
660
661 #[test]
infer_long_argnull662 fn infer_long_arg() {
663 let cmd = Command::new("test")
664 .infer_long_args(true)
665 .arg(
666 Arg::new("racetrack")
667 .long("racetrack")
668 .alias("autobahn")
669 .action(ArgAction::SetTrue),
670 )
671 .arg(Arg::new("racecar").long("racecar").action(ArgAction::Set));
672
673 let matches = cmd
674 .clone()
675 .try_get_matches_from(["test", "--racec=hello"])
676 .unwrap();
677 assert!(!*matches
678 .get_one::<bool>("racetrack")
679 .expect("defaulted by clap"));
680 assert_eq!(
681 matches.get_one::<String>("racecar").map(|v| v.as_str()),
682 Some("hello")
683 );
684
685 let matches = cmd
686 .clone()
687 .try_get_matches_from(["test", "--racet"])
688 .unwrap();
689 assert!(*matches
690 .get_one::<bool>("racetrack")
691 .expect("defaulted by clap"));
692 assert_eq!(
693 matches.get_one::<String>("racecar").map(|v| v.as_str()),
694 None
695 );
696
697 let matches = cmd
698 .clone()
699 .try_get_matches_from(["test", "--auto"])
700 .unwrap();
701 assert!(*matches
702 .get_one::<bool>("racetrack")
703 .expect("defaulted by clap"));
704 assert_eq!(
705 matches.get_one::<String>("racecar").map(|v| v.as_str()),
706 None
707 );
708
709 let cmd = Command::new("test")
710 .infer_long_args(true)
711 .arg(Arg::new("arg").long("arg").action(ArgAction::SetTrue));
712
713 let matches = cmd.clone().try_get_matches_from(["test", "--"]).unwrap();
714 assert!(!*matches.get_one::<bool>("arg").expect("defaulted by clap"));
715
716 let matches = cmd.clone().try_get_matches_from(["test", "--a"]).unwrap();
717 assert!(*matches.get_one::<bool>("arg").expect("defaulted by clap"));
718 }
719