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