• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_fail()7 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_message()23 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_zero()40 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_value()58 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_fail()75 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_pass()91 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_pass()104 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_char()117 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_short()128 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_vals()150 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_space()190 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_equals()212 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_mixed()234 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_mixed2()256 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_value()278 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_equals()292 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_delim()309 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_delims()320 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_pass()347 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_fail()369 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_after()379 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_before()403 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_follows()422 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_mean()447 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_val()462 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_setup(argv: Vec<&'static str>) -> Result<ArgMatches, clap::Error>481 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]
issue_1105_empty_value_long_fail()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_explicit()496 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_equals()504 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_fail()512 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_explicit()519 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_equals()527 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_space()535 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_suggestion()545 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_space()576 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_eq()592 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_eq()608 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_misuse()624 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_2279()633 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_arg()662 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