• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![cfg(feature = "help")]
2 
3 use clap::{arg, builder::PossibleValue, error::ErrorKind, Arg, ArgAction, ArgGroup, Command};
4 
5 use super::utils;
6 
setup() -> Command7 fn setup() -> Command {
8     Command::new("test")
9         .author("Kevin K.")
10         .about("tests stuff")
11         .version("1.3")
12 }
13 
empty_args() -> impl IntoIterator<Item = String>14 fn empty_args() -> impl IntoIterator<Item = String> {
15     std::iter::empty()
16 }
17 
18 #[test]
help_short()19 fn help_short() {
20     let m = setup().try_get_matches_from(vec!["myprog", "-h"]);
21 
22     assert!(m.is_err());
23     assert_eq!(m.unwrap_err().kind(), ErrorKind::DisplayHelp);
24 }
25 
26 #[test]
help_long()27 fn help_long() {
28     let m = setup().try_get_matches_from(vec!["myprog", "--help"]);
29 
30     assert!(m.is_err());
31     assert_eq!(m.unwrap_err().kind(), ErrorKind::DisplayHelp);
32 }
33 
34 #[test]
help_no_subcommand()35 fn help_no_subcommand() {
36     let m = setup().try_get_matches_from(vec!["myprog", "help"]);
37 
38     assert!(m.is_err());
39     assert_eq!(m.unwrap_err().kind(), ErrorKind::UnknownArgument);
40 }
41 
42 #[test]
help_subcommand()43 fn help_subcommand() {
44     let m = setup()
45         .subcommand(
46             Command::new("test")
47                 .about("tests things")
48                 .arg(arg!(-v --verbose "with verbosity")),
49         )
50         .try_get_matches_from(vec!["myprog", "help"]);
51 
52     assert!(m.is_err());
53     assert_eq!(m.unwrap_err().kind(), ErrorKind::DisplayHelp);
54 }
55 
56 #[test]
57 #[cfg(feature = "error-context")]
help_multi_subcommand_error()58 fn help_multi_subcommand_error() {
59     let cmd = Command::new("ctest").subcommand(
60         Command::new("subcmd").subcommand(
61             Command::new("multi")
62                 .about("tests subcommands")
63                 .author("Kevin K. <kbknapp@gmail.com>")
64                 .version("0.1")
65                 .arg(arg!(
66                     -f --flag                    "tests flags"
67                 ))
68                 .arg(
69                     arg!(
70                         -o --option <scoption>    "tests options"
71                     )
72                     .required(false)
73                     .num_args(1..)
74                     .action(ArgAction::Append),
75                 ),
76         ),
77     );
78     let err = cmd
79         .try_get_matches_from(["ctest", "help", "subcmd", "multi", "foo"])
80         .unwrap_err();
81 
82     static EXPECTED: &str = "error: unrecognized subcommand 'foo'
83 
84 Usage: ctest subcmd multi [OPTIONS]
85 
86 For more information, try '--help'.
87 ";
88     utils::assert_eq(EXPECTED, err.to_string());
89 }
90 
91 #[test]
req_last_arg_usage()92 fn req_last_arg_usage() {
93     static LAST_ARG_REQ_MULT: &str = "\
94 Usage: example <FIRST>... -- <SECOND>...
95 
96 Arguments:
97   <FIRST>...   First
98   <SECOND>...  Second
99 
100 Options:
101   -h, --help     Print help
102   -V, --version  Print version
103 ";
104 
105     let cmd = Command::new("example")
106         .version("1.0")
107         .arg(Arg::new("FIRST").help("First").num_args(1..).required(true))
108         .arg(
109             Arg::new("SECOND")
110                 .help("Second")
111                 .num_args(1..)
112                 .required(true)
113                 .last(true),
114         );
115     utils::assert_output(cmd, "example --help", LAST_ARG_REQ_MULT, false);
116 }
117 
118 #[test]
args_with_last_usage()119 fn args_with_last_usage() {
120     static LAST_ARG_USAGE: &str = "\
121 Usage: flamegraph [OPTIONS] [BINFILE] [-- <ARGS>...]
122 
123 Arguments:
124   [BINFILE]  The path of the binary to be profiled. for a binary.
125   [ARGS]...  Any arguments you wish to pass to the being profiled.
126 
127 Options:
128   -v, --verbose            Prints out more stuff.
129   -t, --timeout <SECONDS>  Timeout in seconds.
130   -f, --frequency <HERTZ>  The sampling frequency.
131   -h, --help               Print help
132   -V, --version            Print version
133 ";
134 
135     let cmd = Command::new("flamegraph")
136         .version("0.1")
137         .arg(
138             Arg::new("verbose")
139                 .help("Prints out more stuff.")
140                 .short('v')
141                 .long("verbose")
142                 .action(ArgAction::SetTrue),
143         )
144         .arg(
145             Arg::new("timeout")
146                 .help("Timeout in seconds.")
147                 .short('t')
148                 .long("timeout")
149                 .value_name("SECONDS"),
150         )
151         .arg(
152             Arg::new("frequency")
153                 .help("The sampling frequency.")
154                 .short('f')
155                 .long("frequency")
156                 .value_name("HERTZ"),
157         )
158         .arg(
159             Arg::new("binary path")
160                 .help("The path of the binary to be profiled. for a binary.")
161                 .value_name("BINFILE"),
162         )
163         .arg(
164             Arg::new("pass through args")
165                 .help("Any arguments you wish to pass to the being profiled.")
166                 .action(ArgAction::Set)
167                 .num_args(1..)
168                 .last(true)
169                 .value_name("ARGS"),
170         );
171     utils::assert_output(cmd, "flamegraph --help", LAST_ARG_USAGE, false);
172 }
173 
174 #[test]
subcommand_short_help()175 fn subcommand_short_help() {
176     let m = utils::complex_app().try_get_matches_from(vec!["clap-test", "subcmd", "-h"]);
177 
178     assert!(m.is_err());
179     assert_eq!(m.unwrap_err().kind(), ErrorKind::DisplayHelp);
180 }
181 
182 #[test]
subcommand_long_help()183 fn subcommand_long_help() {
184     let m = utils::complex_app().try_get_matches_from(vec!["clap-test", "subcmd", "--help"]);
185 
186     assert!(m.is_err());
187     assert_eq!(m.unwrap_err().kind(), ErrorKind::DisplayHelp);
188 }
189 
190 #[test]
subcommand_help_rev()191 fn subcommand_help_rev() {
192     let m = utils::complex_app().try_get_matches_from(vec!["clap-test", "help", "subcmd"]);
193 
194     assert!(m.is_err());
195     assert_eq!(m.unwrap_err().kind(), ErrorKind::DisplayHelp);
196 }
197 
198 #[test]
complex_help_output()199 fn complex_help_output() {
200     static HELP: &str = "\
201 clap-test v1.4.8
202 Kevin K. <kbknapp@gmail.com>
203 tests clap library
204 
205 Usage: clap-test [OPTIONS] [positional] [positional2] [positional3]... [COMMAND]
206 
207 Commands:
208   subcmd  tests subcommands
209   help    Print this message or the help of the given subcommand(s)
210 
211 Arguments:
212   [positional]      tests positionals
213   [positional2]     tests positionals with exclusions
214   [positional3]...  tests specific values [possible values: vi, emacs]
215 
216 Options:
217   -o, --option <opt>...                  tests options
218   -f, --flag...                          tests flags
219   -F                                     tests flags with exclusions
220       --long-option-2 <option2>          tests long options with exclusions
221   -O, --option3 <option3>                specific vals [possible values: fast, slow]
222       --multvals <one> <two>             Tests multiple values, not mult occs
223       --multvalsmo <one> <two>           Tests multiple values, and mult occs
224       --minvals2 <minvals> <minvals>...  Tests 2 min vals
225       --maxvals3 <maxvals>...            Tests 3 max vals
226       --optvaleq[=<optval>]              Tests optional value, require = sign
227       --optvalnoeq [<optval>]            Tests optional value
228   -h, --help                             Print help
229   -V, --version                          Print version
230 ";
231 
232     utils::assert_output(utils::complex_app(), "clap-test --help", HELP, false);
233 }
234 
235 #[test]
after_and_before_help_output()236 fn after_and_before_help_output() {
237     static AFTER_HELP: &str = "some text that comes before the help
238 
239 tests clap library
240 
241 Usage: clap-test
242 
243 Options:
244   -h, --help     Print help
245   -V, --version  Print version
246 
247 some text that comes after the help
248 ";
249 
250     let cmd = Command::new("clap-test")
251         .version("v1.4.8")
252         .about("tests clap library")
253         .before_help("some text that comes before the help")
254         .after_help("some text that comes after the help");
255     utils::assert_output(cmd.clone(), "clap-test -h", AFTER_HELP, false);
256     utils::assert_output(cmd, "clap-test --help", AFTER_HELP, false);
257 }
258 
259 #[test]
after_and_before_long_help_output()260 fn after_and_before_long_help_output() {
261     static AFTER_HELP: &str = "some text that comes before the help
262 
263 tests clap library
264 
265 Usage: clap-test
266 
267 Options:
268   -h, --help     Print help (see more with '--help')
269   -V, --version  Print version
270 
271 some text that comes after the help
272 ";
273 
274     static AFTER_LONG_HELP: &str = "some longer text that comes before the help
275 
276 tests clap library
277 
278 Usage: clap-test
279 
280 Options:
281   -h, --help
282           Print help (see a summary with '-h')
283 
284   -V, --version
285           Print version
286 
287 some longer text that comes after the help
288 ";
289 
290     let cmd = Command::new("clap-test")
291         .version("v1.4.8")
292         .about("tests clap library")
293         .before_help("some text that comes before the help")
294         .after_help("some text that comes after the help")
295         .before_long_help("some longer text that comes before the help")
296         .after_long_help("some longer text that comes after the help");
297     utils::assert_output(cmd.clone(), "clap-test --help", AFTER_LONG_HELP, false);
298     utils::assert_output(cmd, "clap-test -h", AFTER_HELP, false);
299 }
300 
301 static MULTI_SC_HELP: &str = "\
302 tests subcommands
303 
304 Usage: ctest subcmd multi [OPTIONS]
305 
306 Options:
307   -f, --flag                  tests flags
308   -o, --option <scoption>...  tests options
309   -h, --help                  Print help
310   -V, --version               Print version
311 ";
312 
313 #[test]
multi_level_sc_help()314 fn multi_level_sc_help() {
315     let cmd = Command::new("ctest").subcommand(
316         Command::new("subcmd").subcommand(
317             Command::new("multi")
318                 .about("tests subcommands")
319                 .author("Kevin K. <kbknapp@gmail.com>")
320                 .version("0.1")
321                 .arg(arg!(
322                     -f --flag                    "tests flags"
323                 ))
324                 .arg(
325                     arg!(
326                         -o --option <scoption>    "tests options"
327                     )
328                     .required(false)
329                     .num_args(1..)
330                     .action(ArgAction::Append),
331                 ),
332         ),
333     );
334     utils::assert_output(cmd, "ctest help subcmd multi", MULTI_SC_HELP, false);
335 }
336 
337 #[test]
no_wrap_default_help()338 fn no_wrap_default_help() {
339     static DEFAULT_HELP: &str = "\
340 Usage: ctest
341 
342 Options:
343   -h, --help     Print help
344   -V, --version  Print version
345 ";
346 
347     let cmd = Command::new("ctest").version("1.0").term_width(0);
348     utils::assert_output(cmd, "ctest --help", DEFAULT_HELP, false);
349 }
350 
351 #[test]
352 #[cfg(feature = "wrap_help")]
wrapped_help()353 fn wrapped_help() {
354     static WRAPPED_HELP: &str = "\
355 Usage: test [OPTIONS]
356 
357 Options:
358   -a, --all            Also do versioning for private crates (will
359                        not be published)
360       --exact          Specify inter dependency version numbers
361                        exactly with `=`
362       --no-git-commit  Do not commit version changes
363       --no-git-push    Do not push generated commit and tags to git
364                        remote
365   -h, --help           Print help
366 ";
367     let cmd = Command::new("test")
368         .term_width(67)
369         .arg(
370             Arg::new("all")
371                 .short('a')
372                 .long("all")
373                 .action(ArgAction::SetTrue)
374                 .help("Also do versioning for private crates (will not be published)"),
375         )
376         .arg(
377             Arg::new("exact")
378                 .long("exact")
379                 .action(ArgAction::SetTrue)
380                 .help("Specify inter dependency version numbers exactly with `=`"),
381         )
382         .arg(
383             Arg::new("no_git_commit")
384                 .long("no-git-commit")
385                 .action(ArgAction::SetTrue)
386                 .help("Do not commit version changes"),
387         )
388         .arg(
389             Arg::new("no_git_push")
390                 .long("no-git-push")
391                 .action(ArgAction::SetTrue)
392                 .help("Do not push generated commit and tags to git remote"),
393         );
394     utils::assert_output(cmd, "test --help", WRAPPED_HELP, false);
395 }
396 
397 #[test]
398 #[cfg(feature = "wrap_help")]
unwrapped_help()399 fn unwrapped_help() {
400     static UNWRAPPED_HELP: &str = "\
401 Usage: test [OPTIONS]
402 
403 Options:
404   -a, --all            Also do versioning for private crates (will
405                        not be published)
406       --exact          Specify inter dependency version numbers
407                        exactly with `=`
408       --no-git-commit  Do not commit version changes
409       --no-git-push    Do not push generated commit and tags to git
410                        remote
411   -h, --help           Print help
412 ";
413     let cmd = Command::new("test")
414         .term_width(68)
415         .arg(
416             Arg::new("all")
417                 .short('a')
418                 .long("all")
419                 .action(ArgAction::SetTrue)
420                 .help("Also do versioning for private crates (will not be published)"),
421         )
422         .arg(
423             Arg::new("exact")
424                 .long("exact")
425                 .action(ArgAction::SetTrue)
426                 .help("Specify inter dependency version numbers exactly with `=`"),
427         )
428         .arg(
429             Arg::new("no_git_commit")
430                 .long("no-git-commit")
431                 .action(ArgAction::SetTrue)
432                 .help("Do not commit version changes"),
433         )
434         .arg(
435             Arg::new("no_git_push")
436                 .long("no-git-push")
437                 .action(ArgAction::SetTrue)
438                 .help("Do not push generated commit and tags to git remote"),
439         );
440     utils::assert_output(cmd, "test --help", UNWRAPPED_HELP, false);
441 }
442 
443 #[test]
444 #[cfg(all(feature = "wrap_help"))]
possible_value_wrapped_help()445 fn possible_value_wrapped_help() {
446     static WRAPPED_HELP: &str = "\
447 Usage: test [OPTIONS]
448 
449 Options:
450       --possible-values <possible_values>
451           Possible values:
452           - short_name:
453             Long enough help message, barely warrant wrapping
454           - second:
455             Short help gets handled the same
456 
457       --possible-values-with-new-line <possible_values_with_new_line>
458           Possible values:
459           - long enough name to trigger new line:
460             Really long enough help message to clearly warrant
461             wrapping believe me
462           - second
463 
464       --possible-values-without-new-line <possible_values_without_new_line>
465           Possible values:
466           - name:   Short enough help message with no wrapping
467           - second: short help
468 
469   -h, --help
470           Print help (see a summary with '-h')
471 ";
472     let cmd = Command::new("test")
473         .term_width(67)
474         .arg(
475             Arg::new("possible_values")
476                 .long("possible-values")
477                 .action(ArgAction::Set)
478                 .value_parser([
479                     PossibleValue::new("short_name")
480                         .help("Long enough help message, barely warrant wrapping"),
481                     PossibleValue::new("second").help("Short help gets handled the same"),
482                 ]),
483         )
484         .arg(
485             Arg::new("possible_values_with_new_line")
486                 .long("possible-values-with-new-line")
487                 .action(ArgAction::Set)
488                 .value_parser([
489                     PossibleValue::new("long enough name to trigger new line").help(
490                         "Really long enough help message to clearly warrant wrapping believe me",
491                     ),
492                     PossibleValue::new("second"),
493                 ]),
494         )
495         .arg(
496             Arg::new("possible_values_without_new_line")
497                 .long("possible-values-without-new-line")
498                 .action(ArgAction::Set)
499                 .value_parser([
500                     PossibleValue::new("name").help("Short enough help message with no wrapping"),
501                     PossibleValue::new("second").help("short help"),
502                 ]),
503         );
504     utils::assert_output(cmd, "test --help", WRAPPED_HELP, false);
505 }
506 
507 #[test]
complex_subcommand_help_output()508 fn complex_subcommand_help_output() {
509     static SC_HELP: &str = "clap-test-subcmd 0.1
510 Kevin K. <kbknapp@gmail.com>
511 tests subcommands
512 
513 Usage: clap-test subcmd [OPTIONS] [scpositional]
514 
515 Arguments:
516   [scpositional]  tests positionals
517 
518 Options:
519   -o, --option <scoption>...   tests options
520   -f, --flag...                tests flags
521   -s, --subcmdarg <subcmdarg>  tests other args
522   -h, --help                   Print help
523   -V, --version                Print version
524 ";
525 
526     let a = utils::complex_app();
527     utils::assert_output(a, "clap-test subcmd --help", SC_HELP, false);
528 }
529 
530 #[test]
531 #[cfg(feature = "wrap_help")]
issue_626_unicode_cutoff()532 fn issue_626_unicode_cutoff() {
533     static ISSUE_626_CUTOFF: &str = "\
534 Usage: ctest [OPTIONS]
535 
536 Options:
537   -c, --cafe <FILE>  A coffeehouse, coffee shop, or café is an
538                      establishment which primarily serves hot coffee,
539                      related coffee beverages (e.g., café latte,
540                      cappuccino, espresso), tea, and other hot
541                      beverages. Some coffeehouses also serve cold
542                      beverages such as iced coffee and iced tea. Many
543                      cafés also serve some type of food, such as light
544                      snacks, muffins, or pastries.
545   -h, --help         Print help
546   -V, --version      Print version
547 ";
548 
549     let cmd = Command::new("ctest").version("0.1").term_width(70).arg(
550         Arg::new("cafe")
551             .short('c')
552             .long("cafe")
553             .value_name("FILE")
554             .help(
555                 "A coffeehouse, coffee shop, or café is an establishment \
556              which primarily serves hot coffee, related coffee beverages \
557              (e.g., café latte, cappuccino, espresso), tea, and other hot \
558              beverages. Some coffeehouses also serve cold beverages such as \
559              iced coffee and iced tea. Many cafés also serve some type of \
560              food, such as light snacks, muffins, or pastries.",
561             )
562             .action(ArgAction::Set),
563     );
564     utils::assert_output(cmd, "ctest --help", ISSUE_626_CUTOFF, false);
565 }
566 
567 static HIDE_POS_VALS: &str = "\
568 Usage: ctest [OPTIONS]
569 
570 Options:
571   -p, --pos <VAL>    Some vals [possible values: fast, slow]
572   -c, --cafe <FILE>  A coffeehouse, coffee shop, or café.
573   -h, --help         Print help
574   -V, --version      Print version
575 ";
576 
577 #[test]
hide_possible_vals()578 fn hide_possible_vals() {
579     let cmd = Command::new("ctest")
580         .version("0.1")
581         .arg(
582             Arg::new("pos")
583                 .short('p')
584                 .long("pos")
585                 .value_name("VAL")
586                 .value_parser(["fast", "slow"])
587                 .help("Some vals")
588                 .action(ArgAction::Set),
589         )
590         .arg(
591             Arg::new("cafe")
592                 .short('c')
593                 .long("cafe")
594                 .value_name("FILE")
595                 .hide_possible_values(true)
596                 .value_parser(["fast", "slow"])
597                 .help("A coffeehouse, coffee shop, or café.")
598                 .action(ArgAction::Set),
599         );
600     utils::assert_output(cmd, "ctest --help", HIDE_POS_VALS, false);
601 }
602 
603 #[test]
hide_single_possible_val()604 fn hide_single_possible_val() {
605     let cmd = Command::new("ctest")
606         .version("0.1")
607         .arg(
608             Arg::new("pos")
609                 .short('p')
610                 .long("pos")
611                 .value_name("VAL")
612                 .value_parser([
613                     "fast".into(),
614                     "slow".into(),
615                     PossibleValue::new("secret speed").hide(true),
616                 ])
617                 .help("Some vals")
618                 .action(ArgAction::Set),
619         )
620         .arg(
621             Arg::new("cafe")
622                 .short('c')
623                 .long("cafe")
624                 .value_name("FILE")
625                 .help("A coffeehouse, coffee shop, or café.")
626                 .action(ArgAction::Set),
627         );
628     utils::assert_output(cmd, "ctest --help", HIDE_POS_VALS, false);
629 }
630 
631 #[test]
possible_vals_with_help()632 fn possible_vals_with_help() {
633     static POS_VALS_HELP: &str = "\
634 Usage: ctest [OPTIONS]
635 
636 Options:
637   -p, --pos <VAL>
638           Some vals
639 
640           Possible values:
641           - fast
642           - slow: not as fast
643 
644   -c, --cafe <FILE>
645           A coffeehouse, coffee shop, or café.
646 
647   -h, --help
648           Print help (see a summary with '-h')
649 
650   -V, --version
651           Print version
652 ";
653     let app = Command::new("ctest")
654         .version("0.1")
655         .arg(
656             Arg::new("pos")
657                 .short('p')
658                 .long("pos")
659                 .value_name("VAL")
660                 .value_parser([
661                     PossibleValue::new("fast"),
662                     PossibleValue::new("slow").help("not as fast"),
663                     PossibleValue::new("secret speed").hide(true),
664                 ])
665                 .help("Some vals")
666                 .action(ArgAction::Set),
667         )
668         .arg(
669             Arg::new("cafe")
670                 .short('c')
671                 .long("cafe")
672                 .value_name("FILE")
673                 .help("A coffeehouse, coffee shop, or café.")
674                 .action(ArgAction::Set),
675         );
676     utils::assert_output(app, "ctest --help", POS_VALS_HELP, false);
677 }
678 
679 #[test]
680 #[cfg(feature = "wrap_help")]
issue_626_panic()681 fn issue_626_panic() {
682     static ISSUE_626_PANIC: &str = "\
683 Usage: ctest [OPTIONS]
684 
685 Options:
686   -c, --cafe <FILE>
687           La culture du café est très développée
688           dans de nombreux pays à climat chaud
689           d\'Amérique, d\'Afrique et d\'Asie, dans des
690           plantations qui sont cultivées pour les
691           marchés d\'exportation. Le café est souvent
692           une contribution majeure aux exportations
693           des régions productrices.
694   -h, --help
695           Print help
696   -V, --version
697           Print version
698 ";
699 
700     let cmd = Command::new("ctest")
701         .version("0.1")
702         .term_width(52)
703         .arg(Arg::new("cafe")
704            .short('c')
705            .long("cafe")
706            .value_name("FILE")
707            .help("La culture du café est très développée dans de nombreux pays à climat chaud d'Amérique, \
708            d'Afrique et d'Asie, dans des plantations qui sont cultivées pour les marchés d'exportation. \
709            Le café est souvent une contribution majeure aux exportations des régions productrices.")
710            .action(ArgAction::Set));
711     utils::assert_output(cmd, "ctest --help", ISSUE_626_PANIC, false);
712 }
713 
714 #[test]
715 #[cfg(feature = "wrap_help")]
issue_626_variable_panic()716 fn issue_626_variable_panic() {
717     for i in 10..320 {
718         let _ = Command::new("ctest")
719             .version("0.1")
720             .term_width(i)
721             .arg(Arg::new("cafe")
722                .short('c')
723                .long("cafe")
724                .value_name("FILE")
725                .help("La culture du café est très développée dans de nombreux pays à climat chaud d'Amérique, \
726                d'Afrique et d'Asie, dans des plantations qui sont cultivées pour les marchés d'exportation. \
727                Le café est souvent une contribution majeure aux exportations des régions productrices.")
728                .action(ArgAction::Set))
729             .try_get_matches_from(vec!["ctest", "--help"]);
730     }
731 }
732 
733 #[test]
734 #[cfg(feature = "wrap_help")]
final_word_wrapping()735 fn final_word_wrapping() {
736     static FINAL_WORD_WRAPPING: &str = "\
737 Usage: ctest
738 
739 Options:
740   -h, --help
741           Print help
742   -V, --version
743           Print version
744 ";
745 
746     let cmd = Command::new("ctest").version("0.1").term_width(24);
747     utils::assert_output(cmd, "ctest --help", FINAL_WORD_WRAPPING, false);
748 }
749 
750 #[test]
751 #[cfg(feature = "wrap_help")]
wrapping_newline_chars()752 fn wrapping_newline_chars() {
753     static WRAPPING_NEWLINE_CHARS: &str = "\
754 Usage: ctest [mode]
755 
756 Arguments:
757   [mode]  x, max, maximum   20 characters, contains symbols.
758           l, long           Copy-friendly, 14 characters,
759           contains symbols.
760           m, med, medium    Copy-friendly, 8 characters,
761           contains symbols.
762 
763 Options:
764   -h, --help     Print help
765   -V, --version  Print version
766 ";
767 
768     let cmd = Command::new("ctest")
769         .version("0.1")
770         .term_width(60)
771         .arg(Arg::new("mode").help(
772             "x, max, maximum   20 characters, contains symbols.\n\
773              l, long           Copy-friendly, 14 characters, contains symbols.\n\
774              m, med, medium    Copy-friendly, 8 characters, contains symbols.\n",
775         ));
776     utils::assert_output(cmd, "ctest --help", WRAPPING_NEWLINE_CHARS, false);
777 }
778 
779 #[test]
780 #[cfg(feature = "wrap_help")]
wrapping_newline_variables()781 fn wrapping_newline_variables() {
782     static WRAPPING_NEWLINE_CHARS: &str = "\
783 Usage: ctest [mode]
784 
785 Arguments:
786   [mode]  x, max, maximum   20 characters, contains symbols.
787           l, long           Copy-friendly, 14 characters,
788           contains symbols.
789           m, med, medium    Copy-friendly, 8 characters,
790           contains symbols.
791 
792 Options:
793   -h, --help     Print help
794   -V, --version  Print version
795 ";
796 
797     let cmd = Command::new("ctest")
798         .version("0.1")
799         .term_width(60)
800         .arg(Arg::new("mode").help(
801             "x, max, maximum   20 characters, contains symbols.{n}\
802              l, long           Copy-friendly, 14 characters, contains symbols.{n}\
803              m, med, medium    Copy-friendly, 8 characters, contains symbols.{n}",
804         ));
805     utils::assert_output(cmd, "ctest --help", WRAPPING_NEWLINE_CHARS, false);
806 }
807 
808 #[test]
809 #[cfg(feature = "wrap_help")]
dont_wrap_urls()810 fn dont_wrap_urls() {
811     let cmd = Command::new("Example")
812         .term_width(30)
813         .subcommand(Command::new("update").arg(
814             Arg::new("force-non-host")
815                 .help("Install toolchains that require an emulator. See https://github.com/rust-lang/rustup/wiki/Non-host-toolchains")
816                 .long("force-non-host")
817                 .action(ArgAction::SetTrue))
818     );
819 
820     const EXPECTED: &str = "\
821 Usage: Example update [OPTIONS]
822 
823 Options:
824       --force-non-host
825           Install toolchains
826           that require an
827           emulator. See
828           https://github.com/rust-lang/rustup/wiki/Non-host-toolchains
829   -h, --help
830           Print help
831 ";
832     utils::assert_output(cmd, "Example update --help", EXPECTED, false);
833 }
834 
835 static OLD_NEWLINE_CHARS: &str = "\
836 Usage: ctest [OPTIONS]
837 
838 Options:
839   -m             Some help with some wrapping
840                  (Defaults to something)
841   -h, --help     Print help
842   -V, --version  Print version
843 ";
844 
845 #[test]
old_newline_chars()846 fn old_newline_chars() {
847     let cmd = Command::new("ctest").version("0.1").arg(
848         Arg::new("mode")
849             .short('m')
850             .action(ArgAction::SetTrue)
851             .help("Some help with some wrapping\n(Defaults to something)"),
852     );
853     utils::assert_output(cmd, "ctest --help", OLD_NEWLINE_CHARS, false);
854 }
855 
856 #[test]
old_newline_variables()857 fn old_newline_variables() {
858     let cmd = Command::new("ctest").version("0.1").arg(
859         Arg::new("mode")
860             .short('m')
861             .action(ArgAction::SetTrue)
862             .help("Some help with some wrapping{n}(Defaults to something)"),
863     );
864     utils::assert_output(cmd, "ctest --help", OLD_NEWLINE_CHARS, false);
865 }
866 
867 #[test]
868 #[cfg(feature = "wrap_help")]
issue_688_hide_pos_vals()869 fn issue_688_hide_pos_vals() {
870     static ISSUE_688: &str = "\
871 Usage: ctest [OPTIONS]
872 
873 Options:
874       --filter <filter>  Sets the filter, or sampling method, to use for interpolation when resizing the particle
875                          images. The default is Linear (Bilinear). [possible values: Nearest, Linear, Cubic, Gaussian,
876                          Lanczos3]
877   -h, --help             Print help
878   -V, --version          Print version
879 ";
880 
881     let filter_values = ["Nearest", "Linear", "Cubic", "Gaussian", "Lanczos3"];
882 
883     let app1 = Command::new("ctest")
884         .version("0.1")
885 			.term_width(120)
886 			.hide_possible_values(true)
887 			.arg(Arg::new("filter")
888 				.help("Sets the filter, or sampling method, to use for interpolation when resizing the particle \
889             images. The default is Linear (Bilinear). [possible values: Nearest, Linear, Cubic, Gaussian, Lanczos3]")
890 				.long("filter")
891 				.value_parser(filter_values)
892 				.action(ArgAction::Set));
893     utils::assert_output(app1, "ctest --help", ISSUE_688, false);
894 
895     let app2 = Command::new("ctest")
896         .version("0.1")
897 			.term_width(120)
898 			.arg(Arg::new("filter")
899 				.help("Sets the filter, or sampling method, to use for interpolation when resizing the particle \
900             images. The default is Linear (Bilinear).")
901 				.long("filter")
902 				.value_parser(filter_values)
903 				.action(ArgAction::Set));
904     utils::assert_output(app2, "ctest --help", ISSUE_688, false);
905 
906     let app3 = Command::new("ctest")
907         .version("0.1")
908 			.term_width(120)
909 			.arg(Arg::new("filter")
910 				.help("Sets the filter, or sampling method, to use for interpolation when resizing the particle \
911             images. The default is Linear (Bilinear). [possible values: Nearest, Linear, Cubic, Gaussian, Lanczos3]")
912 				.long("filter")
913 				.action(ArgAction::Set));
914     utils::assert_output(app3, "ctest --help", ISSUE_688, false);
915 }
916 
917 #[test]
issue_702_multiple_values()918 fn issue_702_multiple_values() {
919     static ISSUE_702: &str = "\
920 bar
921 
922 Usage: myapp [OPTIONS] [arg1] [arg2]...
923 
924 Arguments:
925   [arg1]     some option
926   [arg2]...  some option
927 
928 Options:
929   -s, --some <some>       some option
930   -o, --other <other>     some other option
931   -l, --label <label>...  a label
932   -h, --help              Print help
933   -V, --version           Print version
934 ";
935 
936     let cmd = Command::new("myapp")
937         .version("1.0")
938         .author("foo")
939         .about("bar")
940         .arg(Arg::new("arg1").help("some option"))
941         .arg(
942             Arg::new("arg2")
943                 .action(ArgAction::Set)
944                 .num_args(1..)
945                 .help("some option"),
946         )
947         .arg(
948             Arg::new("some")
949                 .help("some option")
950                 .short('s')
951                 .long("some")
952                 .action(ArgAction::Set),
953         )
954         .arg(
955             Arg::new("other")
956                 .help("some other option")
957                 .short('o')
958                 .long("other")
959                 .action(ArgAction::Set),
960         )
961         .arg(
962             Arg::new("label")
963                 .help("a label")
964                 .short('l')
965                 .long("label")
966                 .num_args(1..)
967                 .action(ArgAction::Set),
968         );
969     utils::assert_output(cmd, "myapp --help", ISSUE_702, false);
970 }
971 
972 #[test]
long_about()973 fn long_about() {
974     static LONG_ABOUT: &str = "\
975 something really really long, with
976 multiple lines of text
977 that should be displayed
978 
979 Usage: myapp [arg1]
980 
981 Arguments:
982   [arg1]
983           some option
984 
985 Options:
986   -h, --help
987           Print help (see a summary with '-h')
988 
989   -V, --version
990           Print version
991 ";
992 
993     let cmd = Command::new("myapp")
994         .version("1.0")
995         .author("foo")
996         .about("bar")
997         .long_about(
998             "something really really long, with\nmultiple lines of text\nthat should be displayed",
999         )
1000         .arg(Arg::new("arg1").help("some option"));
1001     utils::assert_output(cmd, "myapp --help", LONG_ABOUT, false);
1002 }
1003 
1004 #[test]
ripgrep_usage()1005 fn ripgrep_usage() {
1006     static RIPGREP_USAGE: &str = "\
1007 Usage: rg [OPTIONS] <pattern> [<path> ...]
1008        rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
1009        rg [OPTIONS] --files [<path> ...]
1010        rg [OPTIONS] --type-list
1011 
1012 Options:
1013   -h, --help     Print help
1014   -V, --version  Print version
1015 ";
1016 
1017     let cmd = Command::new("ripgrep").version("0.5").override_usage(
1018         "rg [OPTIONS] <pattern> [<path> ...]
1019        rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
1020        rg [OPTIONS] --files [<path> ...]
1021        rg [OPTIONS] --type-list",
1022     );
1023 
1024     utils::assert_output(cmd, "rg --help", RIPGREP_USAGE, false);
1025 }
1026 
1027 #[test]
ripgrep_usage_using_templates()1028 fn ripgrep_usage_using_templates() {
1029     static RIPGREP_USAGE: &str = "\
1030 ripgrep 0.5
1031 
1032 Usage: rg [OPTIONS] <pattern> [<path> ...]
1033        rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
1034        rg [OPTIONS] --files [<path> ...]
1035        rg [OPTIONS] --type-list
1036 
1037 Options:
1038   -h, --help     Print help
1039   -V, --version  Print version
1040 ";
1041 
1042     #[cfg(not(feature = "unstable-v5"))]
1043     let cmd = Command::new("ripgrep")
1044         .version("0.5")
1045         .override_usage(
1046             "\
1047        rg [OPTIONS] <pattern> [<path> ...]
1048        rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
1049        rg [OPTIONS] --files [<path> ...]
1050        rg [OPTIONS] --type-list",
1051         )
1052         .help_template(
1053             "\
1054 {bin} {version}
1055 
1056 Usage: {usage}
1057 
1058 Options:
1059 {options}",
1060         );
1061 
1062     #[cfg(feature = "unstable-v5")]
1063     let cmd = Command::new("ripgrep")
1064         .version("0.5")
1065         .override_usage(
1066             "\
1067        rg [OPTIONS] <pattern> [<path> ...]
1068        rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
1069        rg [OPTIONS] --files [<path> ...]
1070        rg [OPTIONS] --type-list",
1071         )
1072         .help_template(
1073             "\
1074 {name} {version}
1075 
1076 Usage: {usage}
1077 
1078 Options:
1079 {options}",
1080         );
1081 
1082     utils::assert_output(cmd, "rg --help", RIPGREP_USAGE, false);
1083 }
1084 
1085 #[test]
sc_negates_reqs()1086 fn sc_negates_reqs() {
1087     static SC_NEGATES_REQS: &str = "\
1088 Usage: prog --opt <FILE> [PATH]
1089        prog [PATH] <COMMAND>
1090 
1091 Commands:
1092   test
1093   help  Print this message or the help of the given subcommand(s)
1094 
1095 Arguments:
1096   [PATH]  help
1097 
1098 Options:
1099   -o, --opt <FILE>  tests options
1100   -h, --help        Print help
1101   -V, --version     Print version
1102 ";
1103 
1104     let cmd = Command::new("prog")
1105         .version("1.0")
1106         .subcommand_negates_reqs(true)
1107         .arg(arg!(-o --opt <FILE> "tests options").required(true))
1108         .arg(Arg::new("PATH").help("help"))
1109         .subcommand(Command::new("test"));
1110     utils::assert_output(cmd, "prog --help", SC_NEGATES_REQS, false);
1111 }
1112 
1113 #[test]
hide_args()1114 fn hide_args() {
1115     static HIDDEN_ARGS: &str = "\
1116 Usage: prog [OPTIONS]
1117 
1118 Options:
1119   -f, --flag        testing flags
1120   -o, --opt <FILE>  tests options
1121   -h, --help        Print help
1122   -V, --version     Print version
1123 ";
1124 
1125     let cmd = Command::new("prog")
1126         .version("1.0")
1127         .arg(arg!(-f --flag "testing flags"))
1128         .arg(arg!(-o --opt <FILE> "tests options"))
1129         .arg(Arg::new("pos").hide(true));
1130     utils::assert_output(cmd, "prog --help", HIDDEN_ARGS, false);
1131 }
1132 
1133 #[test]
args_negate_sc()1134 fn args_negate_sc() {
1135     static ARGS_NEGATE_SC: &str = "\
1136 Usage: prog [OPTIONS] [PATH]
1137        prog <COMMAND>
1138 
1139 Commands:
1140   test
1141   help  Print this message or the help of the given subcommand(s)
1142 
1143 Arguments:
1144   [PATH]  help
1145 
1146 Options:
1147   -f, --flag        testing flags
1148   -o, --opt <FILE>  tests options
1149   -h, --help        Print help
1150   -V, --version     Print version
1151 ";
1152 
1153     let cmd = Command::new("prog")
1154         .version("1.0")
1155         .args_conflicts_with_subcommands(true)
1156         .arg(arg!(-f --flag "testing flags"))
1157         .arg(arg!(-o --opt <FILE> "tests options"))
1158         .arg(Arg::new("PATH").help("help"))
1159         .subcommand(Command::new("test"));
1160     utils::assert_output(cmd, "prog --help", ARGS_NEGATE_SC, false);
1161 }
1162 
1163 #[test]
issue_1046_hide_scs()1164 fn issue_1046_hide_scs() {
1165     static ISSUE_1046_HIDDEN_SCS: &str = "\
1166 Usage: prog [OPTIONS] [PATH]
1167 
1168 Arguments:
1169   [PATH]  some
1170 
1171 Options:
1172   -f, --flag        testing flags
1173   -o, --opt <FILE>  tests options
1174   -h, --help        Print help
1175   -V, --version     Print version
1176 ";
1177 
1178     let cmd = Command::new("prog")
1179         .version("1.0")
1180         .arg(arg!(-f --flag "testing flags"))
1181         .arg(arg!(-o --opt <FILE> "tests options"))
1182         .arg(Arg::new("PATH").help("some"))
1183         .subcommand(Command::new("test").hide(true));
1184     utils::assert_output(cmd, "prog --help", ISSUE_1046_HIDDEN_SCS, false);
1185 }
1186 
1187 #[test]
1188 #[cfg(feature = "wrap_help")]
issue_777_wrap_all_things()1189 fn issue_777_wrap_all_things() {
1190     static ISSUE_777: &str = "A cmd with a crazy very long long
1191 long name hahaha 1.0
1192 Some Very Long Name and crazy long
1193 email <email@server.com>
1194 Show how the about text is not
1195 wrapped
1196 
1197 Usage: ctest
1198 
1199 Options:
1200   -h, --help     Print help
1201   -V, --version  Print version
1202 ";
1203 
1204     let cmd = Command::new("A cmd with a crazy very long long long name hahaha")
1205         .version("1.0")
1206         .author("Some Very Long Name and crazy long email <email@server.com>")
1207         .about("Show how the about text is not wrapped")
1208         .help_template(utils::FULL_TEMPLATE)
1209         .term_width(35);
1210     utils::assert_output(cmd, "ctest --help", ISSUE_777, false);
1211 }
1212 
1213 static OVERRIDE_HELP_SHORT: &str = "\
1214 Usage: test
1215 
1216 Options:
1217   -H, --help     Print help
1218   -V, --version  Print version
1219 ";
1220 
1221 #[test]
override_help_short()1222 fn override_help_short() {
1223     let cmd = Command::new("test")
1224         .version("0.1")
1225         .arg(arg!(-H --help "Print help").action(ArgAction::Help))
1226         .disable_help_flag(true);
1227 
1228     utils::assert_output(cmd.clone(), "test --help", OVERRIDE_HELP_SHORT, false);
1229     utils::assert_output(cmd, "test -H", OVERRIDE_HELP_SHORT, false);
1230 }
1231 
1232 static OVERRIDE_HELP_LONG: &str = "\
1233 Usage: test [OPTIONS]
1234 
1235 Options:
1236   -h, --hell     Print help
1237   -V, --version  Print version
1238 ";
1239 
1240 #[test]
override_help_long()1241 fn override_help_long() {
1242     let cmd = Command::new("test")
1243         .version("0.1")
1244         .arg(arg!(-h --hell "Print help").action(ArgAction::Help))
1245         .disable_help_flag(true);
1246 
1247     utils::assert_output(cmd.clone(), "test --hell", OVERRIDE_HELP_LONG, false);
1248     utils::assert_output(cmd, "test -h", OVERRIDE_HELP_LONG, false);
1249 }
1250 
1251 static OVERRIDE_HELP_ABOUT: &str = "\
1252 Usage: test
1253 
1254 Options:
1255   -h, --help     Print custom help information
1256   -V, --version  Print version
1257 ";
1258 
1259 #[test]
override_help_about()1260 fn override_help_about() {
1261     let cmd = Command::new("test")
1262         .version("0.1")
1263         .arg(arg!(-h --help "Print custom help information").action(ArgAction::Help))
1264         .disable_help_flag(true);
1265 
1266     utils::assert_output(cmd.clone(), "test --help", OVERRIDE_HELP_ABOUT, false);
1267     utils::assert_output(cmd, "test -h", OVERRIDE_HELP_ABOUT, false);
1268 }
1269 
1270 #[test]
1271 #[cfg(debug_assertions)]
1272 #[should_panic = "Command conflict: Argument names must be unique, but 'help' is in use by more than one argument or group (call `cmd.disable_help_flag(true)` to remove the auto-generated `--help`)"]
arg_id_conflict_with_help()1273 fn arg_id_conflict_with_help() {
1274     Command::new("conflict")
1275         .arg(Arg::new("help").short('?').action(ArgAction::SetTrue))
1276         .build();
1277 }
1278 
1279 #[test]
1280 #[cfg(debug_assertions)]
1281 #[should_panic = "Command conflict: Short option names must be unique for each argument, but '-h' is in use by both 'home' and 'help' (call `cmd.disable_help_flag(true)` to remove the auto-generated `--help`)"]
arg_short_conflict_with_help()1282 fn arg_short_conflict_with_help() {
1283     Command::new("conflict")
1284         .arg(Arg::new("home").short('h').action(ArgAction::SetTrue))
1285         .build();
1286 }
1287 
1288 #[test]
1289 #[cfg(debug_assertions)]
1290 #[should_panic = "Command conflict: Long option names must be unique for each argument, but '--help' is in use by both 'custom-help' and 'help' (call `cmd.disable_help_flag(true)` to remove the auto-generated `--help`)"]
arg_long_conflict_with_help()1291 fn arg_long_conflict_with_help() {
1292     Command::new("conflict")
1293         .arg(
1294             Arg::new("custom-help")
1295                 .long("help")
1296                 .action(ArgAction::SetTrue),
1297         )
1298         .build();
1299 }
1300 
1301 #[test]
last_arg_mult_usage()1302 fn last_arg_mult_usage() {
1303     static LAST_ARG: &str = "\
1304 Usage: last <TARGET> [CORPUS] [-- <ARGS>...]
1305 
1306 Arguments:
1307   <TARGET>   some
1308   [CORPUS]   some
1309   [ARGS]...  some
1310 
1311 Options:
1312   -h, --help     Print help
1313   -V, --version  Print version
1314 ";
1315 
1316     let cmd = Command::new("last")
1317         .version("0.1")
1318         .arg(Arg::new("TARGET").required(true).help("some"))
1319         .arg(Arg::new("CORPUS").help("some"))
1320         .arg(
1321             Arg::new("ARGS")
1322                 .action(ArgAction::Set)
1323                 .num_args(1..)
1324                 .last(true)
1325                 .help("some"),
1326         );
1327     utils::assert_output(cmd, "last --help", LAST_ARG, false);
1328 }
1329 
1330 #[test]
last_arg_mult_usage_req()1331 fn last_arg_mult_usage_req() {
1332     static LAST_ARG_REQ: &str = "\
1333 Usage: last <TARGET> [CORPUS] -- <ARGS>...
1334 
1335 Arguments:
1336   <TARGET>   some
1337   [CORPUS]   some
1338   <ARGS>...  some
1339 
1340 Options:
1341   -h, --help     Print help
1342   -V, --version  Print version
1343 ";
1344 
1345     let cmd = Command::new("last")
1346         .version("0.1")
1347         .arg(Arg::new("TARGET").required(true).help("some"))
1348         .arg(Arg::new("CORPUS").help("some"))
1349         .arg(
1350             Arg::new("ARGS")
1351                 .action(ArgAction::Set)
1352                 .num_args(1..)
1353                 .last(true)
1354                 .required(true)
1355                 .help("some"),
1356         );
1357     utils::assert_output(cmd, "last --help", LAST_ARG_REQ, false);
1358 }
1359 
1360 #[test]
last_arg_mult_usage_req_with_sc()1361 fn last_arg_mult_usage_req_with_sc() {
1362     static LAST_ARG_REQ_SC: &str = "\
1363 Usage: last <TARGET> [CORPUS] -- <ARGS>...
1364        last [TARGET] [CORPUS] <COMMAND>
1365 
1366 Commands:
1367   test  some
1368   help  Print this message or the help of the given subcommand(s)
1369 
1370 Arguments:
1371   <TARGET>   some
1372   [CORPUS]   some
1373   <ARGS>...  some
1374 
1375 Options:
1376   -h, --help     Print help
1377   -V, --version  Print version
1378 ";
1379 
1380     let cmd = Command::new("last")
1381         .version("0.1")
1382         .subcommand_negates_reqs(true)
1383         .arg(Arg::new("TARGET").required(true).help("some"))
1384         .arg(Arg::new("CORPUS").help("some"))
1385         .arg(
1386             Arg::new("ARGS")
1387                 .action(ArgAction::Set)
1388                 .num_args(1..)
1389                 .last(true)
1390                 .required(true)
1391                 .help("some"),
1392         )
1393         .subcommand(Command::new("test").about("some"));
1394     utils::assert_output(cmd, "last --help", LAST_ARG_REQ_SC, false);
1395 }
1396 
1397 #[test]
last_arg_mult_usage_with_sc()1398 fn last_arg_mult_usage_with_sc() {
1399     static LAST_ARG_SC: &str = "\
1400 Usage: last <TARGET> [CORPUS] [-- <ARGS>...]
1401        last <COMMAND>
1402 
1403 Commands:
1404   test  some
1405   help  Print this message or the help of the given subcommand(s)
1406 
1407 Arguments:
1408   <TARGET>   some
1409   [CORPUS]   some
1410   [ARGS]...  some
1411 
1412 Options:
1413   -h, --help     Print help
1414   -V, --version  Print version
1415 ";
1416 
1417     let cmd = Command::new("last")
1418         .version("0.1")
1419         .args_conflicts_with_subcommands(true)
1420         .arg(Arg::new("TARGET").required(true).help("some"))
1421         .arg(Arg::new("CORPUS").help("some"))
1422         .arg(
1423             Arg::new("ARGS")
1424                 .action(ArgAction::Set)
1425                 .num_args(1..)
1426                 .last(true)
1427                 .help("some"),
1428         )
1429         .subcommand(Command::new("test").about("some"));
1430     utils::assert_output(cmd, "last --help", LAST_ARG_SC, false);
1431 }
1432 
1433 static HIDE_DEFAULT_VAL: &str = "\
1434 Usage: default [OPTIONS]
1435 
1436 Options:
1437       --arg <argument>  Pass an argument to the program. [default: default-argument]
1438   -h, --help            Print help
1439   -V, --version         Print version
1440 ";
1441 
1442 #[test]
hide_default_val()1443 fn hide_default_val() {
1444     let app1 = Command::new("default").version("0.1").term_width(120).arg(
1445         Arg::new("argument")
1446             .help("Pass an argument to the program. [default: default-argument]")
1447             .long("arg")
1448             .default_value("default-argument")
1449             .hide_default_value(true),
1450     );
1451     utils::assert_output(app1, "default --help", HIDE_DEFAULT_VAL, false);
1452 
1453     let app2 = Command::new("default").version("0.1").term_width(120).arg(
1454         Arg::new("argument")
1455             .help("Pass an argument to the program.")
1456             .long("arg")
1457             .default_value("default-argument"),
1458     );
1459     utils::assert_output(app2, "default --help", HIDE_DEFAULT_VAL, false);
1460 }
1461 
1462 #[test]
1463 #[cfg(feature = "wrap_help")]
escaped_whitespace_values()1464 fn escaped_whitespace_values() {
1465     static ESCAPED_DEFAULT_VAL: &str = "\
1466 Usage: default [OPTIONS]
1467 
1468 Options:
1469       --arg <argument>  Pass an argument to the program. [default: \"\\n\"] [possible values: normal, \" \", \"\\n\", \"\\t\",
1470                         other]
1471   -h, --help            Print help
1472   -V, --version         Print version
1473 ";
1474 
1475     let app1 = Command::new("default").version("0.1").term_width(120).arg(
1476         Arg::new("argument")
1477             .help("Pass an argument to the program.")
1478             .long("arg")
1479             .default_value("\n")
1480             .value_parser(["normal", " ", "\n", "\t", "other"]),
1481     );
1482     utils::assert_output(app1, "default --help", ESCAPED_DEFAULT_VAL, false);
1483 }
1484 
issue_1112_setup() -> Command1485 fn issue_1112_setup() -> Command {
1486     Command::new("test")
1487         .version("1.3")
1488         .disable_help_flag(true)
1489         .arg(
1490             Arg::new("help1")
1491                 .long("help")
1492                 .short('h')
1493                 .help("some help")
1494                 .action(ArgAction::SetTrue),
1495         )
1496         .subcommand(
1497             Command::new("foo").arg(
1498                 Arg::new("help1")
1499                     .long("help")
1500                     .short('h')
1501                     .help("some help")
1502                     .action(ArgAction::SetTrue),
1503             ),
1504         )
1505 }
1506 
1507 #[test]
prefer_user_help_long_1112()1508 fn prefer_user_help_long_1112() {
1509     let m = issue_1112_setup().try_get_matches_from(vec!["test", "--help"]);
1510 
1511     assert!(m.is_ok(), "{}", m.unwrap_err());
1512     let m = m.unwrap();
1513     assert!(*m.get_one::<bool>("help1").expect("defaulted by clap"));
1514 }
1515 
1516 #[test]
prefer_user_help_short_1112()1517 fn prefer_user_help_short_1112() {
1518     let m = issue_1112_setup().try_get_matches_from(vec!["test", "-h"]);
1519 
1520     assert!(m.is_ok(), "{}", m.unwrap_err());
1521     let m = m.unwrap();
1522     assert!(*m.get_one::<bool>("help1").expect("defaulted by clap"));
1523 }
1524 
1525 #[test]
prefer_user_subcmd_help_long_1112()1526 fn prefer_user_subcmd_help_long_1112() {
1527     let m = issue_1112_setup().try_get_matches_from(vec!["test", "foo", "--help"]);
1528 
1529     assert!(m.is_ok(), "{}", m.unwrap_err());
1530     let m = m.unwrap();
1531     assert!(*m
1532         .subcommand_matches("foo")
1533         .unwrap()
1534         .get_one::<bool>("help1")
1535         .expect("defaulted by clap"));
1536 }
1537 
1538 #[test]
prefer_user_subcmd_help_short_1112()1539 fn prefer_user_subcmd_help_short_1112() {
1540     let m = issue_1112_setup().try_get_matches_from(vec!["test", "foo", "-h"]);
1541 
1542     assert!(m.is_ok(), "{}", m.unwrap_err());
1543     let m = m.unwrap();
1544     assert!(m
1545         .subcommand_matches("foo")
1546         .unwrap()
1547         .get_one::<bool>("help1")
1548         .expect("defaulted by clap"));
1549 }
1550 
1551 #[test]
issue_1052_require_delim_help()1552 fn issue_1052_require_delim_help() {
1553     static REQUIRE_DELIM_HELP: &str = "\
1554 tests stuff
1555 
1556 Usage: test --fake <some> <val>
1557 
1558 Options:
1559   -f, --fake <some> <val>  some help
1560   -h, --help               Print help
1561   -V, --version            Print version
1562 ";
1563 
1564     let cmd = Command::new("test")
1565         .author("Kevin K.")
1566         .about("tests stuff")
1567         .version("1.3")
1568         .arg(
1569             arg!(-f --fake <s> "some help")
1570                 .required(true)
1571                 .value_names(["some", "val"])
1572                 .action(ArgAction::Set)
1573                 .value_delimiter(':'),
1574         );
1575 
1576     utils::assert_output(cmd, "test --help", REQUIRE_DELIM_HELP, false);
1577 }
1578 
1579 #[test]
custom_headers_headers()1580 fn custom_headers_headers() {
1581     static CUSTOM_HELP_SECTION: &str = "\
1582 does stuff
1583 
1584 Usage: test [OPTIONS] --fake <some> <val>
1585 
1586 Options:
1587   -f, --fake <some> <val>  some help
1588   -h, --help               Print help
1589   -V, --version            Print version
1590 
1591 NETWORKING:
1592   -n, --no-proxy  Do not use system proxy settings
1593       --port
1594 ";
1595 
1596     let cmd = Command::new("blorp")
1597         .author("Will M.")
1598         .about("does stuff")
1599         .version("1.4")
1600         .arg(
1601             arg!(-f --fake <s> "some help")
1602                 .required(true)
1603                 .value_names(["some", "val"])
1604                 .action(ArgAction::Set)
1605                 .value_delimiter(':'),
1606         )
1607         .next_help_heading(Some("NETWORKING"))
1608         .arg(
1609             Arg::new("no-proxy")
1610                 .short('n')
1611                 .long("no-proxy")
1612                 .action(ArgAction::SetTrue)
1613                 .help("Do not use system proxy settings"),
1614         )
1615         .args([Arg::new("port").long("port").action(ArgAction::SetTrue)]);
1616 
1617     utils::assert_output(cmd, "test --help", CUSTOM_HELP_SECTION, false);
1618 }
1619 
1620 static MULTIPLE_CUSTOM_HELP_SECTIONS: &str = "\
1621 does stuff
1622 
1623 Usage: test [OPTIONS] --fake <some> <val> --birthday-song <song> --birthday-song-volume <volume>
1624 
1625 Options:
1626   -f, --fake <some> <val>  some help
1627       --style <style>      Choose musical style to play the song
1628   -s, --speed <SPEED>      How fast? [possible values: fast, slow]
1629   -h, --help               Print help
1630   -V, --version            Print version
1631 
1632 NETWORKING:
1633   -n, --no-proxy     Do not use system proxy settings
1634   -a, --server-addr  Set server address
1635 
1636 OVERRIDE SPECIAL:
1637   -b, --birthday-song <song>  Change which song is played for birthdays
1638 
1639 SPECIAL:
1640   -v, --birthday-song-volume <volume>  Change the volume of the birthday song
1641 ";
1642 
1643 #[test]
multiple_custom_help_headers()1644 fn multiple_custom_help_headers() {
1645     let cmd = Command::new("blorp")
1646         .author("Will M.")
1647         .about("does stuff")
1648         .version("1.4")
1649         .arg(
1650             arg!(-f --fake <s> "some help")
1651                 .required(true)
1652                 .value_names(["some", "val"])
1653                 .action(ArgAction::Set)
1654                 .value_delimiter(':'),
1655         )
1656         .next_help_heading(Some("NETWORKING"))
1657         .arg(
1658             Arg::new("no-proxy")
1659                 .short('n')
1660                 .long("no-proxy")
1661                 .action(ArgAction::SetTrue)
1662                 .help("Do not use system proxy settings"),
1663         )
1664         .next_help_heading(Some("SPECIAL"))
1665         .arg(
1666             arg!(-b --"birthday-song" <song> "Change which song is played for birthdays")
1667                 .required(true)
1668                 .help_heading(Some("OVERRIDE SPECIAL")),
1669         )
1670         .arg(arg!(--style <style> "Choose musical style to play the song").help_heading(None))
1671         .arg(
1672             arg!(
1673                 -v --"birthday-song-volume" <volume> "Change the volume of the birthday song"
1674             )
1675             .required(true),
1676         )
1677         .next_help_heading(None)
1678         .arg(
1679             Arg::new("server-addr")
1680                 .short('a')
1681                 .long("server-addr")
1682                 .action(ArgAction::SetTrue)
1683                 .help("Set server address")
1684                 .help_heading(Some("NETWORKING")),
1685         )
1686         .arg(
1687             Arg::new("speed")
1688                 .long("speed")
1689                 .short('s')
1690                 .value_name("SPEED")
1691                 .value_parser(["fast", "slow"])
1692                 .help("How fast?")
1693                 .action(ArgAction::Set),
1694         );
1695 
1696     utils::assert_output(cmd, "test --help", MULTIPLE_CUSTOM_HELP_SECTIONS, false);
1697 }
1698 
1699 static CUSTOM_HELP_SECTION_HIDDEN_ARGS: &str = "\
1700 does stuff
1701 
1702 Usage: test [OPTIONS] --song <song> --song-volume <volume>
1703 
1704 Options:
1705   -h, --help     Print help (see more with '--help')
1706   -V, --version  Print version
1707 
1708 OVERRIDE SPECIAL:
1709   -b, --song <song>  Change which song is played for birthdays
1710 
1711 SPECIAL:
1712   -v, --song-volume <volume>  Change the volume of the birthday song
1713 ";
1714 
1715 #[test]
custom_help_headers_hide_args()1716 fn custom_help_headers_hide_args() {
1717     let cmd = Command::new("blorp")
1718         .author("Will M.")
1719         .about("does stuff")
1720         .version("1.4")
1721         .next_help_heading(Some("NETWORKING"))
1722         .arg(
1723             Arg::new("no-proxy")
1724                 .short('n')
1725                 .long("no-proxy")
1726                 .help("Do not use system proxy settings")
1727                 .hide_short_help(true),
1728         )
1729         .next_help_heading(Some("SPECIAL"))
1730         .arg(
1731             arg!(-b --song <song> "Change which song is played for birthdays")
1732                 .required(true)
1733                 .help_heading(Some("OVERRIDE SPECIAL")),
1734         )
1735         .arg(
1736             arg!(
1737                 -v --"song-volume" <volume> "Change the volume of the birthday song"
1738             )
1739             .required(true),
1740         )
1741         .next_help_heading(None)
1742         .arg(
1743             Arg::new("server-addr")
1744                 .short('a')
1745                 .long("server-addr")
1746                 .help("Set server address")
1747                 .help_heading(Some("NETWORKING"))
1748                 .hide_short_help(true),
1749         );
1750 
1751     utils::assert_output(cmd, "test -h", CUSTOM_HELP_SECTION_HIDDEN_ARGS, false);
1752 }
1753 
1754 static ISSUE_897: &str = "\
1755 Long about foo
1756 
1757 Usage: ctest foo
1758 
1759 Options:
1760   -h, --help
1761           Print help (see a summary with '-h')
1762 
1763   -V, --version
1764           Print version
1765 ";
1766 
1767 #[test]
show_long_about_issue_897()1768 fn show_long_about_issue_897() {
1769     let cmd = Command::new("ctest").version("0.1").subcommand(
1770         Command::new("foo")
1771             .version("0.1")
1772             .about("About foo")
1773             .long_about("Long about foo"),
1774     );
1775     utils::assert_output(cmd, "ctest foo --help", ISSUE_897, false);
1776 }
1777 
1778 static ISSUE_897_SHORT: &str = "\
1779 About foo
1780 
1781 Usage: ctest foo
1782 
1783 Options:
1784   -h, --help     Print help (see more with '--help')
1785   -V, --version  Print version
1786 ";
1787 
1788 #[test]
show_short_about_issue_897()1789 fn show_short_about_issue_897() {
1790     let cmd = Command::new("ctest").version("0.1").subcommand(
1791         Command::new("foo")
1792             .version("0.1")
1793             .about("About foo")
1794             .long_about("Long about foo"),
1795     );
1796     utils::assert_output(cmd, "ctest foo -h", ISSUE_897_SHORT, false);
1797 }
1798 
1799 #[test]
issue_1364_no_short_options()1800 fn issue_1364_no_short_options() {
1801     static ISSUE_1364: &str = "\
1802 Usage: demo [OPTIONS] [FILES]...
1803 
1804 Arguments:
1805   [FILES]...
1806 
1807 Options:
1808   -f
1809   -h, --help  Print help (see more with '--help')
1810 ";
1811 
1812     let cmd = Command::new("demo")
1813         .arg(Arg::new("foo").short('f').action(ArgAction::SetTrue))
1814         .arg(
1815             Arg::new("baz")
1816                 .short('z')
1817                 .value_name("BAZ")
1818                 .hide_short_help(true),
1819         )
1820         .arg(
1821             Arg::new("files")
1822                 .value_name("FILES")
1823                 .action(ArgAction::Set)
1824                 .num_args(1..),
1825         );
1826 
1827     utils::assert_output(cmd, "demo -h", ISSUE_1364, false);
1828 }
1829 
1830 #[rustfmt::skip]
1831 #[test]
issue_1487()1832 fn issue_1487() {
1833 static ISSUE_1487: &str = "\
1834 Usage: ctest <arg1|arg2>
1835 
1836 Arguments:
1837   [arg1]
1838   [arg2]
1839 
1840 Options:
1841   -h, --help  Print help
1842 ";
1843 
1844     let cmd = Command::new("test")
1845     .arg(Arg::new("arg1")
1846         .group("group1"))
1847     .arg(Arg::new("arg2")
1848         .group("group1"))
1849     .group(ArgGroup::new("group1")
1850         .args(["arg1", "arg2"])
1851         .required(true));
1852     utils::assert_output(cmd, "ctest -h", ISSUE_1487, false);
1853 }
1854 
1855 #[cfg(debug_assertions)]
1856 #[test]
1857 #[should_panic = "Command::help_expected is enabled for the Command"]
help_required_but_not_given()1858 fn help_required_but_not_given() {
1859     Command::new("myapp")
1860         .help_expected(true)
1861         .arg(Arg::new("foo"))
1862         .try_get_matches_from(empty_args())
1863         .unwrap();
1864 }
1865 
1866 #[cfg(debug_assertions)]
1867 #[test]
1868 #[should_panic = "Command::help_expected is enabled for the Command"]
help_required_but_not_given_settings_after_args()1869 fn help_required_but_not_given_settings_after_args() {
1870     Command::new("myapp")
1871         .arg(Arg::new("foo"))
1872         .help_expected(true)
1873         .try_get_matches_from(empty_args())
1874         .unwrap();
1875 }
1876 
1877 #[cfg(debug_assertions)]
1878 #[test]
1879 #[should_panic = "Command::help_expected is enabled for the Command"]
help_required_but_not_given_for_one_of_two_arguments()1880 fn help_required_but_not_given_for_one_of_two_arguments() {
1881     Command::new("myapp")
1882         .help_expected(true)
1883         .arg(Arg::new("foo"))
1884         .arg(Arg::new("bar").help("It does bar stuff"))
1885         .try_get_matches_from(empty_args())
1886         .unwrap();
1887 }
1888 
1889 #[test]
1890 #[should_panic = "List of such arguments: delete"]
help_required_globally()1891 fn help_required_globally() {
1892     Command::new("myapp")
1893         .help_expected(true)
1894         .arg(Arg::new("foo").help("It does foo stuff"))
1895         .subcommand(
1896             Command::new("bar")
1897                 .arg(Arg::new("create").help("creates bar"))
1898                 .arg(Arg::new("delete")),
1899         )
1900         .try_get_matches_from(empty_args())
1901         .unwrap();
1902 }
1903 
1904 #[cfg(debug_assertions)]
1905 #[test]
1906 #[should_panic = "Command::help_expected is enabled for the Command"]
help_required_globally_but_not_given_for_subcommand()1907 fn help_required_globally_but_not_given_for_subcommand() {
1908     Command::new("myapp")
1909         .help_expected(true)
1910         .arg(Arg::new("foo").help("It does foo stuff"))
1911         .subcommand(
1912             Command::new("bar")
1913                 .arg(Arg::new("create").help("creates bar"))
1914                 .arg(Arg::new("delete")),
1915         )
1916         .try_get_matches_from(empty_args())
1917         .unwrap();
1918 }
1919 
1920 #[test]
help_required_and_given_for_subcommand()1921 fn help_required_and_given_for_subcommand() {
1922     Command::new("myapp")
1923         .help_expected(true)
1924         .arg(Arg::new("foo").help("It does foo stuff"))
1925         .subcommand(
1926             Command::new("bar")
1927                 .arg(Arg::new("create").help("creates bar"))
1928                 .arg(Arg::new("delete").help("deletes bar")),
1929         )
1930         .try_get_matches_from(empty_args())
1931         .unwrap();
1932 }
1933 
1934 #[test]
help_required_and_given()1935 fn help_required_and_given() {
1936     Command::new("myapp")
1937         .help_expected(true)
1938         .arg(Arg::new("foo").help("It does foo stuff"))
1939         .try_get_matches_from(empty_args())
1940         .unwrap();
1941 }
1942 
1943 #[test]
help_required_and_no_args()1944 fn help_required_and_no_args() {
1945     Command::new("myapp")
1946         .help_expected(true)
1947         .try_get_matches_from(empty_args())
1948         .unwrap();
1949 }
1950 
1951 #[test]
issue_1642_long_help_spacing()1952 fn issue_1642_long_help_spacing() {
1953     static ISSUE_1642: &str = "\
1954 Usage: prog [OPTIONS]
1955 
1956 Options:
1957       --config
1958           The config file used by the myprog must be in JSON format
1959           with only valid keys and may not contain other nonsense
1960           that cannot be read by this program. Obviously I'm going on
1961           and on, so I'll stop now.
1962 
1963   -h, --help
1964           Print help (see a summary with '-h')
1965 ";
1966 
1967     let cmd = Command::new("prog").arg(
1968         Arg::new("cfg")
1969             .long("config")
1970             .action(ArgAction::SetTrue)
1971             .long_help(
1972                 "The config file used by the myprog must be in JSON format
1973 with only valid keys and may not contain other nonsense
1974 that cannot be read by this program. Obviously I'm going on
1975 and on, so I'll stop now.",
1976             ),
1977     );
1978     utils::assert_output(cmd, "prog --help", ISSUE_1642, false);
1979 }
1980 
1981 const AFTER_HELP_NO_ARGS: &str = "\
1982 Usage: myapp
1983 
1984 This is after help.
1985 ";
1986 
1987 #[test]
after_help_no_args()1988 fn after_help_no_args() {
1989     let mut cmd = Command::new("myapp")
1990         .version("1.0")
1991         .disable_help_flag(true)
1992         .disable_version_flag(true)
1993         .after_help("This is after help.");
1994 
1995     let help = cmd.render_help().to_string();
1996 
1997     assert_eq!(help, AFTER_HELP_NO_ARGS);
1998 }
1999 
2000 #[test]
help_subcmd_help()2001 fn help_subcmd_help() {
2002     static HELP_SUBCMD_HELP: &str = "\
2003 Print this message or the help of the given subcommand(s)
2004 
2005 Usage: myapp help [COMMAND]...
2006 
2007 Arguments:
2008   [COMMAND]...  Print help for the subcommand(s)
2009 ";
2010 
2011     let cmd = Command::new("myapp")
2012         .subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
2013 
2014     utils::assert_output(cmd.clone(), "myapp help help", HELP_SUBCMD_HELP, false);
2015 }
2016 
2017 #[test]
subcmd_help_subcmd_help()2018 fn subcmd_help_subcmd_help() {
2019     static SUBCMD_HELP_SUBCMD_HELP: &str = "\
2020 Print this message or the help of the given subcommand(s)
2021 
2022 Usage: myapp subcmd help [COMMAND]...
2023 
2024 Arguments:
2025   [COMMAND]...  Print help for the subcommand(s)
2026 ";
2027 
2028     let cmd = Command::new("myapp")
2029         .subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
2030 
2031     utils::assert_output(
2032         cmd.clone(),
2033         "myapp subcmd help help",
2034         SUBCMD_HELP_SUBCMD_HELP,
2035         false,
2036     );
2037 }
2038 
2039 #[test]
global_args_should_show_on_toplevel_help_message()2040 fn global_args_should_show_on_toplevel_help_message() {
2041     static HELP: &str = "\
2042 Usage: myapp [OPTIONS] [COMMAND]
2043 
2044 Commands:
2045   subcmd\x20\x20
2046   help    Print this message or the help of the given subcommand(s)
2047 
2048 Options:
2049   -g, --some-global <someglobal>\x20\x20
2050   -h, --help                      Print help
2051 ";
2052 
2053     let cmd = Command::new("myapp")
2054         .arg(
2055             Arg::new("someglobal")
2056                 .short('g')
2057                 .long("some-global")
2058                 .global(true),
2059         )
2060         .subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
2061 
2062     utils::assert_output(cmd, "myapp help", HELP, false);
2063 }
2064 
2065 #[test]
global_args_should_not_show_on_help_message_for_help_help()2066 fn global_args_should_not_show_on_help_message_for_help_help() {
2067     static HELP_HELP: &str = "\
2068 Print this message or the help of the given subcommand(s)
2069 
2070 Usage: myapp help [COMMAND]...
2071 
2072 Arguments:
2073   [COMMAND]...  Print help for the subcommand(s)
2074 ";
2075 
2076     let cmd = Command::new("myapp")
2077         .arg(
2078             Arg::new("someglobal")
2079                 .short('g')
2080                 .long("some-global")
2081                 .global(true),
2082         )
2083         .subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
2084 
2085     utils::assert_output(cmd, "myapp help help", HELP_HELP, false);
2086 }
2087 
2088 #[test]
global_args_should_show_on_help_message_for_subcommand()2089 fn global_args_should_show_on_help_message_for_subcommand() {
2090     static HELP_SUBCMD: &str = "\
2091 Usage: myapp subcmd [OPTIONS] [COMMAND]
2092 
2093 Commands:
2094   multi\x20\x20
2095   help   Print this message or the help of the given subcommand(s)
2096 
2097 Options:
2098   -g, --some-global <someglobal>\x20\x20
2099   -h, --help                      Print help
2100 ";
2101 
2102     let cmd = Command::new("myapp")
2103         .arg(
2104             Arg::new("someglobal")
2105                 .short('g')
2106                 .long("some-global")
2107                 .global(true),
2108         )
2109         .subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
2110 
2111     utils::assert_output(cmd, "myapp help subcmd", HELP_SUBCMD, false);
2112 }
2113 
2114 #[test]
global_args_should_show_on_help_message_for_nested_subcommand()2115 fn global_args_should_show_on_help_message_for_nested_subcommand() {
2116     static HELP_SUB_SUBCMD: &str = "\
2117 Usage: myapp subcmd multi [OPTIONS]
2118 
2119 Options:
2120   -g, --some-global <someglobal>\x20\x20
2121   -h, --help                      Print help
2122   -V, --version                   Print version
2123 ";
2124 
2125     let cmd = Command::new("myapp")
2126         .arg(
2127             Arg::new("someglobal")
2128                 .short('g')
2129                 .long("some-global")
2130                 .global(true),
2131         )
2132         .subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
2133 
2134     utils::assert_output(cmd, "myapp help subcmd multi", HELP_SUB_SUBCMD, false);
2135 }
2136 
2137 #[test]
option_usage_order()2138 fn option_usage_order() {
2139     static OPTION_USAGE_ORDER: &str = "\
2140 Usage: order [OPTIONS]
2141 
2142 Options:
2143   -a
2144   -B
2145   -b
2146   -s
2147       --select_file
2148       --select_folder
2149   -x
2150   -h, --help           Print help
2151 ";
2152 
2153     let cmd = Command::new("order").args([
2154         Arg::new("a").short('a').action(ArgAction::SetTrue),
2155         Arg::new("B").short('B').action(ArgAction::SetTrue),
2156         Arg::new("b").short('b').action(ArgAction::SetTrue),
2157         Arg::new("save").short('s').action(ArgAction::SetTrue),
2158         Arg::new("select_file")
2159             .long("select_file")
2160             .action(ArgAction::SetTrue),
2161         Arg::new("select_folder")
2162             .long("select_folder")
2163             .action(ArgAction::SetTrue),
2164         Arg::new("x").short('x').action(ArgAction::SetTrue),
2165     ]);
2166 
2167     utils::assert_output(cmd, "order --help", OPTION_USAGE_ORDER, false);
2168 }
2169 
2170 #[test]
prefer_about_over_long_about_in_subcommands_list()2171 fn prefer_about_over_long_about_in_subcommands_list() {
2172     static ABOUT_IN_COMMANDS_LIST: &str = "\
2173 Usage: about-in-subcommands-list [COMMAND]
2174 
2175 Commands:
2176   sub   short about sub
2177   help  Print this message or the help of the given subcommand(s)
2178 
2179 Options:
2180   -h, --help  Print help
2181 ";
2182 
2183     let cmd = Command::new("about-in-subcommands-list").subcommand(
2184         Command::new("sub")
2185             .long_about("long about sub")
2186             .about("short about sub"),
2187     );
2188 
2189     utils::assert_output(
2190         cmd,
2191         "about-in-subcommands-list --help",
2192         ABOUT_IN_COMMANDS_LIST,
2193         false,
2194     );
2195 }
2196 
2197 #[test]
issue_1794_usage()2198 fn issue_1794_usage() {
2199     static USAGE_WITH_GROUP: &str = "\
2200 Usage: deno <pos1|--option1> [pos2]
2201 
2202 Arguments:
2203   [pos1]
2204   [pos2]
2205 
2206 Options:
2207       --option1
2208   -h, --help     Print help
2209 ";
2210 
2211     let cmd = clap::Command::new("hello")
2212         .bin_name("deno")
2213         .arg(
2214             Arg::new("option1")
2215                 .long("option1")
2216                 .action(ArgAction::SetTrue),
2217         )
2218         .arg(Arg::new("pos1").action(ArgAction::Set))
2219         .group(
2220             ArgGroup::new("arg1")
2221                 .args(["pos1", "option1"])
2222                 .required(true),
2223         )
2224         .arg(Arg::new("pos2").action(ArgAction::Set));
2225 
2226     utils::assert_output(cmd, "deno --help", USAGE_WITH_GROUP, false);
2227 }
2228 
2229 static CUSTOM_HEADING_POS: &str = "\
2230 Usage: test [gear] [speed]
2231 
2232 Arguments:
2233   [gear]  Which gear
2234 
2235 Options:
2236   -h, --help     Print help
2237   -V, --version  Print version
2238 
2239 NETWORKING:
2240   [speed]  How fast
2241 ";
2242 
2243 #[test]
custom_heading_pos()2244 fn custom_heading_pos() {
2245     let cmd = Command::new("test")
2246         .version("1.4")
2247         .arg(Arg::new("gear").help("Which gear"))
2248         .next_help_heading(Some("NETWORKING"))
2249         .arg(Arg::new("speed").help("How fast"));
2250 
2251     utils::assert_output(cmd, "test --help", CUSTOM_HEADING_POS, false);
2252 }
2253 
2254 static ONLY_CUSTOM_HEADING_OPTS_NO_ARGS: &str = "\
2255 Usage: test [OPTIONS]
2256 
2257 NETWORKING:
2258   -s, --speed <SPEED>  How fast
2259 ";
2260 
2261 #[test]
only_custom_heading_opts_no_args()2262 fn only_custom_heading_opts_no_args() {
2263     let cmd = Command::new("test")
2264         .version("1.4")
2265         .disable_version_flag(true)
2266         .disable_help_flag(true)
2267         .arg(arg!(--help).action(ArgAction::Help).hide(true))
2268         .next_help_heading(Some("NETWORKING"))
2269         .arg(arg!(-s --speed <SPEED> "How fast"));
2270 
2271     utils::assert_output(cmd, "test --help", ONLY_CUSTOM_HEADING_OPTS_NO_ARGS, false);
2272 }
2273 
2274 static ONLY_CUSTOM_HEADING_POS_NO_ARGS: &str = "\
2275 Usage: test [speed]
2276 
2277 NETWORKING:
2278   [speed]  How fast
2279 ";
2280 
2281 #[test]
only_custom_heading_pos_no_args()2282 fn only_custom_heading_pos_no_args() {
2283     let cmd = Command::new("test")
2284         .version("1.4")
2285         .disable_version_flag(true)
2286         .disable_help_flag(true)
2287         .arg(arg!(--help).action(ArgAction::Help).hide(true))
2288         .next_help_heading(Some("NETWORKING"))
2289         .arg(Arg::new("speed").help("How fast"));
2290 
2291     utils::assert_output(cmd, "test --help", ONLY_CUSTOM_HEADING_POS_NO_ARGS, false);
2292 }
2293 
2294 #[test]
issue_2508_number_of_values_with_single_value_name()2295 fn issue_2508_number_of_values_with_single_value_name() {
2296     let cmd = Command::new("my_app")
2297         .arg(Arg::new("some_arg").long("some_arg").num_args(2))
2298         .arg(
2299             Arg::new("some_arg_issue")
2300                 .long("some_arg_issue")
2301                 .num_args(2)
2302                 .value_name("ARG"),
2303         );
2304     utils::assert_output(
2305         cmd,
2306         "my_app --help",
2307         "\
2308 Usage: my_app [OPTIONS]
2309 
2310 Options:
2311       --some_arg <some_arg> <some_arg>
2312       --some_arg_issue <ARG> <ARG>
2313   -h, --help                            Print help
2314 ",
2315         false,
2316     );
2317 }
2318 
2319 #[test]
missing_positional_final_required()2320 fn missing_positional_final_required() {
2321     let cmd = Command::new("test")
2322         .allow_missing_positional(true)
2323         .arg(Arg::new("arg1"))
2324         .arg(Arg::new("arg2").required(true));
2325     utils::assert_output(
2326         cmd,
2327         "test --help",
2328         "\
2329 Usage: test [arg1] <arg2>
2330 
2331 Arguments:
2332   [arg1]
2333   <arg2>
2334 
2335 Options:
2336   -h, --help  Print help
2337 ",
2338         false,
2339     );
2340 }
2341 
2342 #[test]
missing_positional_final_multiple()2343 fn missing_positional_final_multiple() {
2344     let cmd = Command::new("test")
2345         .allow_missing_positional(true)
2346         .arg(Arg::new("foo"))
2347         .arg(Arg::new("bar"))
2348         .arg(Arg::new("baz").action(ArgAction::Set).num_args(1..));
2349     utils::assert_output(
2350         cmd,
2351         "test --help",
2352         "\
2353 Usage: test [foo] [bar] [baz]...
2354 
2355 Arguments:
2356   [foo]
2357   [bar]
2358   [baz]...
2359 
2360 Options:
2361   -h, --help  Print help
2362 ",
2363         false,
2364     );
2365 }
2366 
2367 #[test]
positional_multiple_values_is_dotted()2368 fn positional_multiple_values_is_dotted() {
2369     let cmd = Command::new("test").arg(
2370         Arg::new("foo")
2371             .required(true)
2372             .action(ArgAction::Set)
2373             .num_args(1..),
2374     );
2375     utils::assert_output(
2376         cmd,
2377         "test --help",
2378         "\
2379 Usage: test <foo>...
2380 
2381 Arguments:
2382   <foo>...
2383 
2384 Options:
2385   -h, --help  Print help
2386 ",
2387         false,
2388     );
2389 
2390     let cmd = Command::new("test").arg(
2391         Arg::new("foo")
2392             .required(true)
2393             .action(ArgAction::Set)
2394             .value_name("BAR")
2395             .num_args(1..),
2396     );
2397     utils::assert_output(
2398         cmd,
2399         "test --help",
2400         "\
2401 Usage: test <BAR>...
2402 
2403 Arguments:
2404   <BAR>...
2405 
2406 Options:
2407   -h, --help  Print help
2408 ",
2409         false,
2410     );
2411 }
2412 
2413 #[test]
positional_multiple_occurrences_is_dotted()2414 fn positional_multiple_occurrences_is_dotted() {
2415     let cmd = Command::new("test").arg(
2416         Arg::new("foo")
2417             .required(true)
2418             .action(ArgAction::Set)
2419             .num_args(1..)
2420             .action(ArgAction::Append),
2421     );
2422     utils::assert_output(
2423         cmd,
2424         "test --help",
2425         "\
2426 Usage: test <foo>...
2427 
2428 Arguments:
2429   <foo>...
2430 
2431 Options:
2432   -h, --help  Print help
2433 ",
2434         false,
2435     );
2436 
2437     let cmd = Command::new("test").arg(
2438         Arg::new("foo")
2439             .required(true)
2440             .action(ArgAction::Set)
2441             .value_name("BAR")
2442             .num_args(1..)
2443             .action(ArgAction::Append),
2444     );
2445     utils::assert_output(
2446         cmd,
2447         "test --help",
2448         "\
2449 Usage: test <BAR>...
2450 
2451 Arguments:
2452   <BAR>...
2453 
2454 Options:
2455   -h, --help  Print help
2456 ",
2457         false,
2458     );
2459 }
2460 
2461 #[test]
too_few_value_names_is_dotted()2462 fn too_few_value_names_is_dotted() {
2463     let cmd = Command::new("test").arg(
2464         Arg::new("foo")
2465             .long("foo")
2466             .required(true)
2467             .action(ArgAction::Set)
2468             .num_args(3)
2469             .value_names(["one", "two"]),
2470     );
2471     utils::assert_output(
2472         cmd,
2473         "test --help",
2474         "\
2475 Usage: test --foo <one> <two>...
2476 
2477 Options:
2478       --foo <one> <two>...
2479   -h, --help                Print help
2480 ",
2481         false,
2482     );
2483 }
2484 
2485 #[test]
2486 #[should_panic = "Argument foo: Too many value names (2) compared to `num_args` (1)"]
too_many_value_names_panics()2487 fn too_many_value_names_panics() {
2488     Command::new("test")
2489         .arg(
2490             Arg::new("foo")
2491                 .long("foo")
2492                 .required(true)
2493                 .action(ArgAction::Set)
2494                 .num_args(1)
2495                 .value_names(["one", "two"]),
2496         )
2497         .debug_assert()
2498 }
2499 
2500 #[test]
disabled_help_flag()2501 fn disabled_help_flag() {
2502     let res = Command::new("foo")
2503         .subcommand(Command::new("sub"))
2504         .disable_help_flag(true)
2505         .try_get_matches_from("foo a".split(' '));
2506     assert!(res.is_err());
2507     let err = res.unwrap_err();
2508     assert_eq!(err.kind(), ErrorKind::InvalidSubcommand);
2509 }
2510 
2511 #[test]
disabled_help_flag_and_subcommand()2512 fn disabled_help_flag_and_subcommand() {
2513     let res = Command::new("foo")
2514         .subcommand(Command::new("sub"))
2515         .disable_help_flag(true)
2516         .disable_help_subcommand(true)
2517         .try_get_matches_from("foo help".split(' '));
2518     assert!(res.is_err());
2519     let err = res.unwrap_err();
2520     assert_eq!(err.kind(), ErrorKind::InvalidSubcommand);
2521     assert!(
2522         err.to_string().ends_with('\n'),
2523         "Errors should have a trailing newline, got {:?}",
2524         err.to_string()
2525     );
2526 }
2527 
2528 #[test]
override_help_subcommand()2529 fn override_help_subcommand() {
2530     let cmd = Command::new("bar")
2531         .subcommand(Command::new("help").arg(Arg::new("arg").action(ArgAction::Set)))
2532         .subcommand(Command::new("not_help").arg(Arg::new("arg").action(ArgAction::Set)))
2533         .disable_help_subcommand(true);
2534     let matches = cmd.try_get_matches_from(["bar", "help", "foo"]).unwrap();
2535     assert_eq!(
2536         matches
2537             .subcommand_matches("help")
2538             .unwrap()
2539             .get_one::<String>("arg")
2540             .map(|v| v.as_str()),
2541         Some("foo")
2542     );
2543 }
2544 
2545 #[test]
override_help_flag_using_long()2546 fn override_help_flag_using_long() {
2547     let cmd = Command::new("foo")
2548         .subcommand(Command::new("help").long_flag("help"))
2549         .disable_help_flag(true)
2550         .disable_help_subcommand(true);
2551     let matches = cmd.try_get_matches_from(["foo", "--help"]).unwrap();
2552     assert!(matches.subcommand_matches("help").is_some());
2553 }
2554 
2555 #[test]
override_help_flag_using_short()2556 fn override_help_flag_using_short() {
2557     let cmd = Command::new("foo")
2558         .disable_help_flag(true)
2559         .disable_help_subcommand(true)
2560         .subcommand(Command::new("help").short_flag('h'));
2561     let matches = cmd.try_get_matches_from(["foo", "-h"]).unwrap();
2562     assert!(matches.subcommand_matches("help").is_some());
2563 }
2564 
2565 #[test]
subcommand_help_doesnt_have_useless_help_flag()2566 fn subcommand_help_doesnt_have_useless_help_flag() {
2567     // The main care-about is that the docs and behavior match.  Since the `help` subcommand
2568     // currently ignores the `--help` flag, the output shouldn't have it.
2569     let cmd = Command::new("example").subcommand(Command::new("test").about("Subcommand"));
2570 
2571     utils::assert_output(
2572         cmd,
2573         "example help help",
2574         "\
2575 Print this message or the help of the given subcommand(s)
2576 
2577 Usage: example help [COMMAND]...
2578 
2579 Arguments:
2580   [COMMAND]...  Print help for the subcommand(s)
2581 ",
2582         false,
2583     );
2584 }
2585 
2586 #[test]
disable_help_flag_affects_help_subcommand()2587 fn disable_help_flag_affects_help_subcommand() {
2588     let mut cmd = Command::new("test_app")
2589         .disable_help_flag(true)
2590         .subcommand(Command::new("test").about("Subcommand"));
2591     cmd.build();
2592 
2593     let args = cmd
2594         .find_subcommand("help")
2595         .unwrap()
2596         .get_arguments()
2597         .map(|a| a.get_id().as_str())
2598         .collect::<Vec<_>>();
2599     assert!(
2600         !args.contains(&"help"),
2601         "`help` should not be present: {:?}",
2602         args
2603     );
2604 }
2605 
2606 #[test]
dont_propagate_version_to_help_subcommand()2607 fn dont_propagate_version_to_help_subcommand() {
2608     let cmd = clap::Command::new("example")
2609         .version("1.0")
2610         .propagate_version(true)
2611         .subcommand(clap::Command::new("subcommand"));
2612 
2613     utils::assert_output(
2614         cmd.clone(),
2615         "example help help",
2616         "\
2617 Print this message or the help of the given subcommand(s)
2618 
2619 Usage: example help [COMMAND]...
2620 
2621 Arguments:
2622   [COMMAND]...  Print help for the subcommand(s)
2623 ",
2624         false,
2625     );
2626 
2627     cmd.debug_assert();
2628 }
2629 
2630 #[test]
help_without_short()2631 fn help_without_short() {
2632     let mut cmd = clap::Command::new("test")
2633         .arg(arg!(-h --hex <NUM>).required(true))
2634         .arg(arg!(--help).action(ArgAction::Help))
2635         .disable_help_flag(true);
2636 
2637     cmd.build();
2638     let help = cmd.get_arguments().find(|a| a.get_id() == "help").unwrap();
2639     assert_eq!(help.get_short(), None);
2640 
2641     let m = cmd.try_get_matches_from(["test", "-h", "0x100"]).unwrap();
2642     assert_eq!(
2643         m.get_one::<String>("hex").map(|v| v.as_str()),
2644         Some("0x100")
2645     );
2646 }
2647 
2648 #[test]
parent_cmd_req_in_usage_with_help_flag()2649 fn parent_cmd_req_in_usage_with_help_flag() {
2650     static EXPECTED: &str = "\
2651 some
2652 
2653 Usage: parent <TARGET> <ARGS> test
2654 
2655 Options:
2656   -h, --help  Print help
2657 ";
2658     let cmd = Command::new("parent")
2659         .version("0.1")
2660         .arg(Arg::new("TARGET").required(true).help("some"))
2661         .arg(
2662             Arg::new("ARGS")
2663                 .action(ArgAction::Set)
2664                 .required(true)
2665                 .help("some"),
2666         )
2667         .subcommand(Command::new("test").about("some"));
2668     utils::assert_output(cmd, "parent test --help", EXPECTED, false);
2669 }
2670 
2671 #[test]
parent_cmd_req_in_usage_with_help_subcommand()2672 fn parent_cmd_req_in_usage_with_help_subcommand() {
2673     static EXPECTED: &str = "\
2674 some
2675 
2676 Usage: parent <TARGET> <ARGS> test
2677 
2678 Options:
2679   -h, --help  Print help
2680 ";
2681     let cmd = Command::new("parent")
2682         .version("0.1")
2683         .arg(Arg::new("TARGET").required(true).help("some"))
2684         .arg(
2685             Arg::new("ARGS")
2686                 .action(ArgAction::Set)
2687                 .required(true)
2688                 .help("some"),
2689         )
2690         .subcommand(Command::new("test").about("some"));
2691     utils::assert_output(cmd, "parent help test", EXPECTED, false);
2692 }
2693 
2694 #[test]
parent_cmd_req_in_usage_with_render_help()2695 fn parent_cmd_req_in_usage_with_render_help() {
2696     static EXPECTED: &str = "\
2697 some
2698 
2699 Usage: parent <TARGET> <ARGS> test
2700 
2701 Options:
2702   -h, --help  Print help
2703 ";
2704     let mut cmd = Command::new("parent")
2705         .version("0.1")
2706         .arg(Arg::new("TARGET").required(true).help("some"))
2707         .arg(
2708             Arg::new("ARGS")
2709                 .action(ArgAction::Set)
2710                 .required(true)
2711                 .help("some"),
2712         )
2713         .subcommand(Command::new("test").about("some"));
2714     cmd.build();
2715     let subcmd = cmd.find_subcommand_mut("test").unwrap();
2716 
2717     let help = subcmd.render_help().to_string();
2718     utils::assert_eq(EXPECTED, help);
2719 }
2720 
2721 #[test]
parent_cmd_req_ignored_when_negates_reqs()2722 fn parent_cmd_req_ignored_when_negates_reqs() {
2723     static MULTI_SC_HELP: &str = "\
2724 Usage: ctest subcmd
2725 
2726 Options:
2727   -h, --help  Print help
2728 ";
2729 
2730     let cmd = Command::new("ctest")
2731         .arg(arg!(<input>))
2732         .subcommand_negates_reqs(true)
2733         .subcommand(Command::new("subcmd"));
2734     utils::assert_output(cmd, "ctest subcmd --help", MULTI_SC_HELP, false);
2735 }
2736 
2737 #[test]
parent_cmd_req_ignored_when_conflicts()2738 fn parent_cmd_req_ignored_when_conflicts() {
2739     static MULTI_SC_HELP: &str = "\
2740 Usage: ctest subcmd
2741 
2742 Options:
2743   -h, --help  Print help
2744 ";
2745 
2746     let cmd = Command::new("ctest")
2747         .arg(arg!(<input>))
2748         .args_conflicts_with_subcommands(true)
2749         .subcommand(Command::new("subcmd"));
2750     utils::assert_output(cmd, "ctest subcmd --help", MULTI_SC_HELP, false);
2751 }
2752 
2753 #[test]
no_wrap_help()2754 fn no_wrap_help() {
2755     let cmd = Command::new("ctest")
2756         .term_width(0)
2757         .override_help(MULTI_SC_HELP);
2758     utils::assert_output(cmd, "ctest --help", MULTI_SC_HELP, false);
2759 }
2760 
2761 #[test]
display_name_default()2762 fn display_name_default() {
2763     let mut cmd = Command::new("app").bin_name("app.exe");
2764     cmd.build();
2765     assert_eq!(cmd.get_display_name(), None);
2766 }
2767 
2768 #[test]
display_name_explicit()2769 fn display_name_explicit() {
2770     let mut cmd = Command::new("app")
2771         .bin_name("app.exe")
2772         .display_name("app.display");
2773     cmd.build();
2774     assert_eq!(cmd.get_display_name(), Some("app.display"));
2775 }
2776 
2777 #[test]
display_name_subcommand_default()2778 fn display_name_subcommand_default() {
2779     let mut cmd = Command::new("parent").subcommand(Command::new("child").bin_name("child.exe"));
2780     cmd.build();
2781     assert_eq!(
2782         cmd.find_subcommand("child").unwrap().get_display_name(),
2783         Some("parent-child")
2784     );
2785 }
2786 
2787 #[test]
display_name_subcommand_explicit()2788 fn display_name_subcommand_explicit() {
2789     let mut cmd = Command::new("parent").subcommand(
2790         Command::new("child")
2791             .bin_name("child.exe")
2792             .display_name("child.display"),
2793     );
2794     cmd.build();
2795     assert_eq!(
2796         cmd.find_subcommand("child").unwrap().get_display_name(),
2797         Some("child.display")
2798     );
2799 }
2800