• 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]
hidden_possible_vals()680 fn hidden_possible_vals() {
681     static POS_VALS_HELP: &str = "\
682 Usage: ctest [pos]
683 
684 Arguments:
685   [pos]
686 
687 Options:
688   -h, --help  Print help
689 ";
690     let app = Command::new("ctest").arg(
691         Arg::new("pos")
692             .hide_possible_values(true)
693             .value_parser([
694                 PossibleValue::new("fast"),
695                 PossibleValue::new("slow").help("not as fast"),
696             ])
697             .action(ArgAction::Set),
698     );
699     utils::assert_output(app, "ctest --help", POS_VALS_HELP, false);
700 }
701 
702 #[test]
703 #[cfg(feature = "wrap_help")]
issue_626_panic()704 fn issue_626_panic() {
705     static ISSUE_626_PANIC: &str = "\
706 Usage: ctest [OPTIONS]
707 
708 Options:
709   -c, --cafe <FILE>
710           La culture du café est très développée
711           dans de nombreux pays à climat chaud
712           d\'Amérique, d\'Afrique et d\'Asie, dans des
713           plantations qui sont cultivées pour les
714           marchés d\'exportation. Le café est souvent
715           une contribution majeure aux exportations
716           des régions productrices.
717   -h, --help
718           Print help
719   -V, --version
720           Print version
721 ";
722 
723     let cmd = Command::new("ctest")
724         .version("0.1")
725         .term_width(52)
726         .arg(Arg::new("cafe")
727            .short('c')
728            .long("cafe")
729            .value_name("FILE")
730            .help("La culture du café est très développée dans de nombreux pays à climat chaud d'Amérique, \
731            d'Afrique et d'Asie, dans des plantations qui sont cultivées pour les marchés d'exportation. \
732            Le café est souvent une contribution majeure aux exportations des régions productrices.")
733            .action(ArgAction::Set));
734     utils::assert_output(cmd, "ctest --help", ISSUE_626_PANIC, false);
735 }
736 
737 #[test]
738 #[cfg(feature = "wrap_help")]
issue_626_variable_panic()739 fn issue_626_variable_panic() {
740     for i in 10..320 {
741         let _ = Command::new("ctest")
742             .version("0.1")
743             .term_width(i)
744             .arg(Arg::new("cafe")
745                .short('c')
746                .long("cafe")
747                .value_name("FILE")
748                .help("La culture du café est très développée dans de nombreux pays à climat chaud d'Amérique, \
749                d'Afrique et d'Asie, dans des plantations qui sont cultivées pour les marchés d'exportation. \
750                Le café est souvent une contribution majeure aux exportations des régions productrices.")
751                .action(ArgAction::Set))
752             .try_get_matches_from(vec!["ctest", "--help"]);
753     }
754 }
755 
756 #[test]
757 #[cfg(feature = "wrap_help")]
final_word_wrapping()758 fn final_word_wrapping() {
759     static FINAL_WORD_WRAPPING: &str = "\
760 Usage: ctest
761 
762 Options:
763   -h, --help
764           Print help
765   -V, --version
766           Print version
767 ";
768 
769     let cmd = Command::new("ctest").version("0.1").term_width(24);
770     utils::assert_output(cmd, "ctest --help", FINAL_WORD_WRAPPING, false);
771 }
772 
773 #[test]
774 #[cfg(feature = "wrap_help")]
wrapping_newline_chars()775 fn wrapping_newline_chars() {
776     static WRAPPING_NEWLINE_CHARS: &str = "\
777 Usage: ctest [mode]
778 
779 Arguments:
780   [mode]  x, max, maximum   20 characters, contains symbols.
781           l, long           Copy-friendly, 14 characters,
782           contains symbols.
783           m, med, medium    Copy-friendly, 8 characters,
784           contains symbols.
785 
786 Options:
787   -h, --help     Print help
788   -V, --version  Print version
789 ";
790 
791     let cmd = Command::new("ctest")
792         .version("0.1")
793         .term_width(60)
794         .arg(Arg::new("mode").help(
795             "x, max, maximum   20 characters, contains symbols.\n\
796              l, long           Copy-friendly, 14 characters, contains symbols.\n\
797              m, med, medium    Copy-friendly, 8 characters, contains symbols.\n",
798         ));
799     utils::assert_output(cmd, "ctest --help", WRAPPING_NEWLINE_CHARS, false);
800 }
801 
802 #[test]
803 #[cfg(feature = "wrap_help")]
wrapping_newline_variables()804 fn wrapping_newline_variables() {
805     static WRAPPING_NEWLINE_CHARS: &str = "\
806 Usage: ctest [mode]
807 
808 Arguments:
809   [mode]  x, max, maximum   20 characters, contains symbols.
810           l, long           Copy-friendly, 14 characters,
811           contains symbols.
812           m, med, medium    Copy-friendly, 8 characters,
813           contains symbols.
814 
815 Options:
816   -h, --help     Print help
817   -V, --version  Print version
818 ";
819 
820     let cmd = Command::new("ctest")
821         .version("0.1")
822         .term_width(60)
823         .arg(Arg::new("mode").help(
824             "x, max, maximum   20 characters, contains symbols.{n}\
825              l, long           Copy-friendly, 14 characters, contains symbols.{n}\
826              m, med, medium    Copy-friendly, 8 characters, contains symbols.{n}",
827         ));
828     utils::assert_output(cmd, "ctest --help", WRAPPING_NEWLINE_CHARS, false);
829 }
830 
831 #[test]
832 #[cfg(feature = "wrap_help")]
dont_wrap_urls()833 fn dont_wrap_urls() {
834     let cmd = Command::new("Example")
835         .term_width(30)
836         .subcommand(Command::new("update").arg(
837             Arg::new("force-non-host")
838                 .help("Install toolchains that require an emulator. See https://github.com/rust-lang/rustup/wiki/Non-host-toolchains")
839                 .long("force-non-host")
840                 .action(ArgAction::SetTrue))
841     );
842 
843     const EXPECTED: &str = "\
844 Usage: Example update [OPTIONS]
845 
846 Options:
847       --force-non-host
848           Install toolchains
849           that require an
850           emulator. See
851           https://github.com/rust-lang/rustup/wiki/Non-host-toolchains
852   -h, --help
853           Print help
854 ";
855     utils::assert_output(cmd, "Example update --help", EXPECTED, false);
856 }
857 
858 static OLD_NEWLINE_CHARS: &str = "\
859 Usage: ctest [OPTIONS]
860 
861 Options:
862   -m             Some help with some wrapping
863                  (Defaults to something)
864   -h, --help     Print help
865   -V, --version  Print version
866 ";
867 
868 #[test]
old_newline_chars()869 fn old_newline_chars() {
870     let cmd = Command::new("ctest").version("0.1").arg(
871         Arg::new("mode")
872             .short('m')
873             .action(ArgAction::SetTrue)
874             .help("Some help with some wrapping\n(Defaults to something)"),
875     );
876     utils::assert_output(cmd, "ctest --help", OLD_NEWLINE_CHARS, false);
877 }
878 
879 #[test]
old_newline_variables()880 fn old_newline_variables() {
881     let cmd = Command::new("ctest").version("0.1").arg(
882         Arg::new("mode")
883             .short('m')
884             .action(ArgAction::SetTrue)
885             .help("Some help with some wrapping{n}(Defaults to something)"),
886     );
887     utils::assert_output(cmd, "ctest --help", OLD_NEWLINE_CHARS, false);
888 }
889 
890 #[test]
891 #[cfg(feature = "wrap_help")]
issue_688_hide_pos_vals()892 fn issue_688_hide_pos_vals() {
893     static ISSUE_688: &str = "\
894 Usage: ctest [OPTIONS]
895 
896 Options:
897       --filter <filter>  Sets the filter, or sampling method, to use for interpolation when resizing the particle
898                          images. The default is Linear (Bilinear). [possible values: Nearest, Linear, Cubic, Gaussian,
899                          Lanczos3]
900   -h, --help             Print help
901   -V, --version          Print version
902 ";
903 
904     let filter_values = ["Nearest", "Linear", "Cubic", "Gaussian", "Lanczos3"];
905 
906     let app1 = Command::new("ctest")
907         .version("0.1")
908 			.term_width(120)
909 			.hide_possible_values(true)
910 			.arg(Arg::new("filter")
911 				.help("Sets the filter, or sampling method, to use for interpolation when resizing the particle \
912             images. The default is Linear (Bilinear). [possible values: Nearest, Linear, Cubic, Gaussian, Lanczos3]")
913 				.long("filter")
914 				.value_parser(filter_values)
915 				.action(ArgAction::Set));
916     utils::assert_output(app1, "ctest --help", ISSUE_688, false);
917 
918     let app2 = Command::new("ctest")
919         .version("0.1")
920 			.term_width(120)
921 			.arg(Arg::new("filter")
922 				.help("Sets the filter, or sampling method, to use for interpolation when resizing the particle \
923             images. The default is Linear (Bilinear).")
924 				.long("filter")
925 				.value_parser(filter_values)
926 				.action(ArgAction::Set));
927     utils::assert_output(app2, "ctest --help", ISSUE_688, false);
928 
929     let app3 = Command::new("ctest")
930         .version("0.1")
931 			.term_width(120)
932 			.arg(Arg::new("filter")
933 				.help("Sets the filter, or sampling method, to use for interpolation when resizing the particle \
934             images. The default is Linear (Bilinear). [possible values: Nearest, Linear, Cubic, Gaussian, Lanczos3]")
935 				.long("filter")
936 				.action(ArgAction::Set));
937     utils::assert_output(app3, "ctest --help", ISSUE_688, false);
938 }
939 
940 #[test]
issue_702_multiple_values()941 fn issue_702_multiple_values() {
942     static ISSUE_702: &str = "\
943 bar
944 
945 Usage: myapp [OPTIONS] [arg1] [arg2]...
946 
947 Arguments:
948   [arg1]     some option
949   [arg2]...  some option
950 
951 Options:
952   -s, --some <some>       some option
953   -o, --other <other>     some other option
954   -l, --label <label>...  a label
955   -h, --help              Print help
956   -V, --version           Print version
957 ";
958 
959     let cmd = Command::new("myapp")
960         .version("1.0")
961         .author("foo")
962         .about("bar")
963         .arg(Arg::new("arg1").help("some option"))
964         .arg(
965             Arg::new("arg2")
966                 .action(ArgAction::Set)
967                 .num_args(1..)
968                 .help("some option"),
969         )
970         .arg(
971             Arg::new("some")
972                 .help("some option")
973                 .short('s')
974                 .long("some")
975                 .action(ArgAction::Set),
976         )
977         .arg(
978             Arg::new("other")
979                 .help("some other option")
980                 .short('o')
981                 .long("other")
982                 .action(ArgAction::Set),
983         )
984         .arg(
985             Arg::new("label")
986                 .help("a label")
987                 .short('l')
988                 .long("label")
989                 .num_args(1..)
990                 .action(ArgAction::Set),
991         );
992     utils::assert_output(cmd, "myapp --help", ISSUE_702, false);
993 }
994 
995 #[test]
long_about()996 fn long_about() {
997     static LONG_ABOUT: &str = "\
998 something really really long, with
999 multiple lines of text
1000 that should be displayed
1001 
1002 Usage: myapp [arg1]
1003 
1004 Arguments:
1005   [arg1]
1006           some option
1007 
1008 Options:
1009   -h, --help
1010           Print help (see a summary with '-h')
1011 
1012   -V, --version
1013           Print version
1014 ";
1015 
1016     let cmd = Command::new("myapp")
1017         .version("1.0")
1018         .author("foo")
1019         .about("bar")
1020         .long_about(
1021             "something really really long, with\nmultiple lines of text\nthat should be displayed",
1022         )
1023         .arg(Arg::new("arg1").help("some option"));
1024     utils::assert_output(cmd, "myapp --help", LONG_ABOUT, false);
1025 }
1026 
1027 #[test]
ripgrep_usage()1028 fn ripgrep_usage() {
1029     static RIPGREP_USAGE: &str = "\
1030 Usage: rg [OPTIONS] <pattern> [<path> ...]
1031        rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
1032        rg [OPTIONS] --files [<path> ...]
1033        rg [OPTIONS] --type-list
1034 
1035 Options:
1036   -h, --help     Print help
1037   -V, --version  Print version
1038 ";
1039 
1040     let cmd = Command::new("ripgrep").version("0.5").override_usage(
1041         "rg [OPTIONS] <pattern> [<path> ...]
1042        rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
1043        rg [OPTIONS] --files [<path> ...]
1044        rg [OPTIONS] --type-list",
1045     );
1046 
1047     utils::assert_output(cmd, "rg --help", RIPGREP_USAGE, false);
1048 }
1049 
1050 #[test]
ripgrep_usage_using_templates()1051 fn ripgrep_usage_using_templates() {
1052     static RIPGREP_USAGE: &str = "\
1053 ripgrep 0.5
1054 
1055 Usage: rg [OPTIONS] <pattern> [<path> ...]
1056        rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
1057        rg [OPTIONS] --files [<path> ...]
1058        rg [OPTIONS] --type-list
1059 
1060 Options:
1061   -h, --help     Print help
1062   -V, --version  Print version
1063 ";
1064 
1065     #[cfg(not(feature = "unstable-v5"))]
1066     let cmd = Command::new("ripgrep")
1067         .version("0.5")
1068         .override_usage(
1069             "\
1070        rg [OPTIONS] <pattern> [<path> ...]
1071        rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
1072        rg [OPTIONS] --files [<path> ...]
1073        rg [OPTIONS] --type-list",
1074         )
1075         .help_template(
1076             "\
1077 {bin} {version}
1078 
1079 Usage: {usage}
1080 
1081 Options:
1082 {options}",
1083         );
1084 
1085     #[cfg(feature = "unstable-v5")]
1086     let cmd = Command::new("ripgrep")
1087         .version("0.5")
1088         .override_usage(
1089             "\
1090        rg [OPTIONS] <pattern> [<path> ...]
1091        rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
1092        rg [OPTIONS] --files [<path> ...]
1093        rg [OPTIONS] --type-list",
1094         )
1095         .help_template(
1096             "\
1097 {name} {version}
1098 
1099 Usage: {usage}
1100 
1101 Options:
1102 {options}",
1103         );
1104 
1105     utils::assert_output(cmd, "rg --help", RIPGREP_USAGE, false);
1106 }
1107 
1108 #[test]
sc_negates_reqs()1109 fn sc_negates_reqs() {
1110     static SC_NEGATES_REQS: &str = "\
1111 Usage: prog --opt <FILE> [PATH]
1112        prog [PATH] <COMMAND>
1113 
1114 Commands:
1115   test
1116   help  Print this message or the help of the given subcommand(s)
1117 
1118 Arguments:
1119   [PATH]  help
1120 
1121 Options:
1122   -o, --opt <FILE>  tests options
1123   -h, --help        Print help
1124   -V, --version     Print version
1125 ";
1126 
1127     let cmd = Command::new("prog")
1128         .version("1.0")
1129         .subcommand_negates_reqs(true)
1130         .arg(arg!(-o --opt <FILE> "tests options").required(true))
1131         .arg(Arg::new("PATH").help("help"))
1132         .subcommand(Command::new("test"));
1133     utils::assert_output(cmd, "prog --help", SC_NEGATES_REQS, false);
1134 }
1135 
1136 #[test]
hide_args()1137 fn hide_args() {
1138     static HIDDEN_ARGS: &str = "\
1139 Usage: prog [OPTIONS]
1140 
1141 Options:
1142   -f, --flag        testing flags
1143   -o, --opt <FILE>  tests options
1144   -h, --help        Print help
1145   -V, --version     Print version
1146 ";
1147 
1148     let cmd = Command::new("prog")
1149         .version("1.0")
1150         .arg(arg!(-f --flag "testing flags"))
1151         .arg(arg!(-o --opt <FILE> "tests options"))
1152         .arg(Arg::new("pos").hide(true));
1153     utils::assert_output(cmd, "prog --help", HIDDEN_ARGS, false);
1154 }
1155 
1156 #[test]
args_negate_sc()1157 fn args_negate_sc() {
1158     static ARGS_NEGATE_SC: &str = "\
1159 Usage: prog [OPTIONS] [PATH]
1160        prog <COMMAND>
1161 
1162 Commands:
1163   test
1164   help  Print this message or the help of the given subcommand(s)
1165 
1166 Arguments:
1167   [PATH]  help
1168 
1169 Options:
1170   -f, --flag        testing flags
1171   -o, --opt <FILE>  tests options
1172   -h, --help        Print help
1173   -V, --version     Print version
1174 ";
1175 
1176     let cmd = Command::new("prog")
1177         .version("1.0")
1178         .args_conflicts_with_subcommands(true)
1179         .arg(arg!(-f --flag "testing flags"))
1180         .arg(arg!(-o --opt <FILE> "tests options"))
1181         .arg(Arg::new("PATH").help("help"))
1182         .subcommand(Command::new("test"));
1183     utils::assert_output(cmd, "prog --help", ARGS_NEGATE_SC, false);
1184 }
1185 
1186 #[test]
issue_1046_hide_scs()1187 fn issue_1046_hide_scs() {
1188     static ISSUE_1046_HIDDEN_SCS: &str = "\
1189 Usage: prog [OPTIONS] [PATH]
1190 
1191 Arguments:
1192   [PATH]  some
1193 
1194 Options:
1195   -f, --flag        testing flags
1196   -o, --opt <FILE>  tests options
1197   -h, --help        Print help
1198   -V, --version     Print version
1199 ";
1200 
1201     let cmd = Command::new("prog")
1202         .version("1.0")
1203         .arg(arg!(-f --flag "testing flags"))
1204         .arg(arg!(-o --opt <FILE> "tests options"))
1205         .arg(Arg::new("PATH").help("some"))
1206         .subcommand(Command::new("test").hide(true));
1207     utils::assert_output(cmd, "prog --help", ISSUE_1046_HIDDEN_SCS, false);
1208 }
1209 
1210 #[test]
1211 #[cfg(feature = "wrap_help")]
issue_777_wrap_all_things()1212 fn issue_777_wrap_all_things() {
1213     static ISSUE_777: &str = "A cmd with a crazy very long long
1214 long name hahaha 1.0
1215 Some Very Long Name and crazy long
1216 email <email@server.com>
1217 Show how the about text is not
1218 wrapped
1219 
1220 Usage: ctest
1221 
1222 Options:
1223   -h, --help     Print help
1224   -V, --version  Print version
1225 ";
1226 
1227     let cmd = Command::new("A cmd with a crazy very long long long name hahaha")
1228         .version("1.0")
1229         .author("Some Very Long Name and crazy long email <email@server.com>")
1230         .about("Show how the about text is not wrapped")
1231         .help_template(utils::FULL_TEMPLATE)
1232         .term_width(35);
1233     utils::assert_output(cmd, "ctest --help", ISSUE_777, false);
1234 }
1235 
1236 static OVERRIDE_HELP_SHORT: &str = "\
1237 Usage: test
1238 
1239 Options:
1240   -H, --help     Print help
1241   -V, --version  Print version
1242 ";
1243 
1244 #[test]
override_help_short()1245 fn override_help_short() {
1246     let cmd = Command::new("test")
1247         .version("0.1")
1248         .arg(arg!(-H --help "Print help").action(ArgAction::Help))
1249         .disable_help_flag(true);
1250 
1251     utils::assert_output(cmd.clone(), "test --help", OVERRIDE_HELP_SHORT, false);
1252     utils::assert_output(cmd, "test -H", OVERRIDE_HELP_SHORT, false);
1253 }
1254 
1255 static OVERRIDE_HELP_LONG: &str = "\
1256 Usage: test [OPTIONS]
1257 
1258 Options:
1259   -h, --hell     Print help
1260   -V, --version  Print version
1261 ";
1262 
1263 #[test]
override_help_long()1264 fn override_help_long() {
1265     let cmd = Command::new("test")
1266         .version("0.1")
1267         .arg(arg!(-h --hell "Print help").action(ArgAction::Help))
1268         .disable_help_flag(true);
1269 
1270     utils::assert_output(cmd.clone(), "test --hell", OVERRIDE_HELP_LONG, false);
1271     utils::assert_output(cmd, "test -h", OVERRIDE_HELP_LONG, false);
1272 }
1273 
1274 static OVERRIDE_HELP_ABOUT: &str = "\
1275 Usage: test
1276 
1277 Options:
1278   -h, --help     Print custom help information
1279   -V, --version  Print version
1280 ";
1281 
1282 #[test]
override_help_about()1283 fn override_help_about() {
1284     let cmd = Command::new("test")
1285         .version("0.1")
1286         .arg(arg!(-h --help "Print custom help information").action(ArgAction::Help))
1287         .disable_help_flag(true);
1288 
1289     utils::assert_output(cmd.clone(), "test --help", OVERRIDE_HELP_ABOUT, false);
1290     utils::assert_output(cmd, "test -h", OVERRIDE_HELP_ABOUT, false);
1291 }
1292 
1293 #[test]
1294 #[cfg(debug_assertions)]
1295 #[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()1296 fn arg_id_conflict_with_help() {
1297     Command::new("conflict")
1298         .arg(Arg::new("help").short('?').action(ArgAction::SetTrue))
1299         .build();
1300 }
1301 
1302 #[test]
1303 #[cfg(debug_assertions)]
1304 #[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()1305 fn arg_short_conflict_with_help() {
1306     Command::new("conflict")
1307         .arg(Arg::new("home").short('h').action(ArgAction::SetTrue))
1308         .build();
1309 }
1310 
1311 #[test]
1312 #[cfg(debug_assertions)]
1313 #[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()1314 fn arg_long_conflict_with_help() {
1315     Command::new("conflict")
1316         .arg(
1317             Arg::new("custom-help")
1318                 .long("help")
1319                 .action(ArgAction::SetTrue),
1320         )
1321         .build();
1322 }
1323 
1324 #[test]
last_arg_mult_usage()1325 fn last_arg_mult_usage() {
1326     static LAST_ARG: &str = "\
1327 Usage: last <TARGET> [CORPUS] [-- <ARGS>...]
1328 
1329 Arguments:
1330   <TARGET>   some
1331   [CORPUS]   some
1332   [ARGS]...  some
1333 
1334 Options:
1335   -h, --help     Print help
1336   -V, --version  Print version
1337 ";
1338 
1339     let cmd = Command::new("last")
1340         .version("0.1")
1341         .arg(Arg::new("TARGET").required(true).help("some"))
1342         .arg(Arg::new("CORPUS").help("some"))
1343         .arg(
1344             Arg::new("ARGS")
1345                 .action(ArgAction::Set)
1346                 .num_args(1..)
1347                 .last(true)
1348                 .help("some"),
1349         );
1350     utils::assert_output(cmd, "last --help", LAST_ARG, false);
1351 }
1352 
1353 #[test]
last_arg_mult_usage_req()1354 fn last_arg_mult_usage_req() {
1355     static LAST_ARG_REQ: &str = "\
1356 Usage: last <TARGET> [CORPUS] -- <ARGS>...
1357 
1358 Arguments:
1359   <TARGET>   some
1360   [CORPUS]   some
1361   <ARGS>...  some
1362 
1363 Options:
1364   -h, --help     Print help
1365   -V, --version  Print version
1366 ";
1367 
1368     let cmd = Command::new("last")
1369         .version("0.1")
1370         .arg(Arg::new("TARGET").required(true).help("some"))
1371         .arg(Arg::new("CORPUS").help("some"))
1372         .arg(
1373             Arg::new("ARGS")
1374                 .action(ArgAction::Set)
1375                 .num_args(1..)
1376                 .last(true)
1377                 .required(true)
1378                 .help("some"),
1379         );
1380     utils::assert_output(cmd, "last --help", LAST_ARG_REQ, false);
1381 }
1382 
1383 #[test]
last_arg_mult_usage_req_with_sc()1384 fn last_arg_mult_usage_req_with_sc() {
1385     static LAST_ARG_REQ_SC: &str = "\
1386 Usage: last <TARGET> [CORPUS] -- <ARGS>...
1387        last [TARGET] [CORPUS] <COMMAND>
1388 
1389 Commands:
1390   test  some
1391   help  Print this message or the help of the given subcommand(s)
1392 
1393 Arguments:
1394   <TARGET>   some
1395   [CORPUS]   some
1396   <ARGS>...  some
1397 
1398 Options:
1399   -h, --help     Print help
1400   -V, --version  Print version
1401 ";
1402 
1403     let cmd = Command::new("last")
1404         .version("0.1")
1405         .subcommand_negates_reqs(true)
1406         .arg(Arg::new("TARGET").required(true).help("some"))
1407         .arg(Arg::new("CORPUS").help("some"))
1408         .arg(
1409             Arg::new("ARGS")
1410                 .action(ArgAction::Set)
1411                 .num_args(1..)
1412                 .last(true)
1413                 .required(true)
1414                 .help("some"),
1415         )
1416         .subcommand(Command::new("test").about("some"));
1417     utils::assert_output(cmd, "last --help", LAST_ARG_REQ_SC, false);
1418 }
1419 
1420 #[test]
last_arg_mult_usage_with_sc()1421 fn last_arg_mult_usage_with_sc() {
1422     static LAST_ARG_SC: &str = "\
1423 Usage: last <TARGET> [CORPUS] [-- <ARGS>...]
1424        last <COMMAND>
1425 
1426 Commands:
1427   test  some
1428   help  Print this message or the help of the given subcommand(s)
1429 
1430 Arguments:
1431   <TARGET>   some
1432   [CORPUS]   some
1433   [ARGS]...  some
1434 
1435 Options:
1436   -h, --help     Print help
1437   -V, --version  Print version
1438 ";
1439 
1440     let cmd = Command::new("last")
1441         .version("0.1")
1442         .args_conflicts_with_subcommands(true)
1443         .arg(Arg::new("TARGET").required(true).help("some"))
1444         .arg(Arg::new("CORPUS").help("some"))
1445         .arg(
1446             Arg::new("ARGS")
1447                 .action(ArgAction::Set)
1448                 .num_args(1..)
1449                 .last(true)
1450                 .help("some"),
1451         )
1452         .subcommand(Command::new("test").about("some"));
1453     utils::assert_output(cmd, "last --help", LAST_ARG_SC, false);
1454 }
1455 
1456 static HIDE_DEFAULT_VAL: &str = "\
1457 Usage: default [OPTIONS]
1458 
1459 Options:
1460       --arg <argument>  Pass an argument to the program. [default: default-argument]
1461   -h, --help            Print help
1462   -V, --version         Print version
1463 ";
1464 
1465 #[test]
hide_default_val()1466 fn hide_default_val() {
1467     let app1 = Command::new("default").version("0.1").term_width(120).arg(
1468         Arg::new("argument")
1469             .help("Pass an argument to the program. [default: default-argument]")
1470             .long("arg")
1471             .default_value("default-argument")
1472             .hide_default_value(true),
1473     );
1474     utils::assert_output(app1, "default --help", HIDE_DEFAULT_VAL, false);
1475 
1476     let app2 = Command::new("default").version("0.1").term_width(120).arg(
1477         Arg::new("argument")
1478             .help("Pass an argument to the program.")
1479             .long("arg")
1480             .default_value("default-argument"),
1481     );
1482     utils::assert_output(app2, "default --help", HIDE_DEFAULT_VAL, false);
1483 }
1484 
1485 #[test]
1486 #[cfg(feature = "wrap_help")]
escaped_whitespace_values()1487 fn escaped_whitespace_values() {
1488     static ESCAPED_DEFAULT_VAL: &str = "\
1489 Usage: default [OPTIONS]
1490 
1491 Options:
1492       --arg <argument>  Pass an argument to the program. [default: \"\\n\"] [possible values: normal, \" \", \"\\n\", \"\\t\",
1493                         other]
1494   -h, --help            Print help
1495   -V, --version         Print version
1496 ";
1497 
1498     let app1 = Command::new("default").version("0.1").term_width(120).arg(
1499         Arg::new("argument")
1500             .help("Pass an argument to the program.")
1501             .long("arg")
1502             .default_value("\n")
1503             .value_parser(["normal", " ", "\n", "\t", "other"]),
1504     );
1505     utils::assert_output(app1, "default --help", ESCAPED_DEFAULT_VAL, false);
1506 }
1507 
issue_1112_setup() -> Command1508 fn issue_1112_setup() -> Command {
1509     Command::new("test")
1510         .version("1.3")
1511         .disable_help_flag(true)
1512         .arg(
1513             Arg::new("help1")
1514                 .long("help")
1515                 .short('h')
1516                 .help("some help")
1517                 .action(ArgAction::SetTrue),
1518         )
1519         .subcommand(
1520             Command::new("foo").arg(
1521                 Arg::new("help1")
1522                     .long("help")
1523                     .short('h')
1524                     .help("some help")
1525                     .action(ArgAction::SetTrue),
1526             ),
1527         )
1528 }
1529 
1530 #[test]
prefer_user_help_long_1112()1531 fn prefer_user_help_long_1112() {
1532     let m = issue_1112_setup().try_get_matches_from(vec!["test", "--help"]);
1533 
1534     assert!(m.is_ok(), "{}", m.unwrap_err());
1535     let m = m.unwrap();
1536     assert!(*m.get_one::<bool>("help1").expect("defaulted by clap"));
1537 }
1538 
1539 #[test]
prefer_user_help_short_1112()1540 fn prefer_user_help_short_1112() {
1541     let m = issue_1112_setup().try_get_matches_from(vec!["test", "-h"]);
1542 
1543     assert!(m.is_ok(), "{}", m.unwrap_err());
1544     let m = m.unwrap();
1545     assert!(*m.get_one::<bool>("help1").expect("defaulted by clap"));
1546 }
1547 
1548 #[test]
prefer_user_subcmd_help_long_1112()1549 fn prefer_user_subcmd_help_long_1112() {
1550     let m = issue_1112_setup().try_get_matches_from(vec!["test", "foo", "--help"]);
1551 
1552     assert!(m.is_ok(), "{}", m.unwrap_err());
1553     let m = m.unwrap();
1554     assert!(*m
1555         .subcommand_matches("foo")
1556         .unwrap()
1557         .get_one::<bool>("help1")
1558         .expect("defaulted by clap"));
1559 }
1560 
1561 #[test]
prefer_user_subcmd_help_short_1112()1562 fn prefer_user_subcmd_help_short_1112() {
1563     let m = issue_1112_setup().try_get_matches_from(vec!["test", "foo", "-h"]);
1564 
1565     assert!(m.is_ok(), "{}", m.unwrap_err());
1566     let m = m.unwrap();
1567     assert!(m
1568         .subcommand_matches("foo")
1569         .unwrap()
1570         .get_one::<bool>("help1")
1571         .expect("defaulted by clap"));
1572 }
1573 
1574 #[test]
issue_1052_require_delim_help()1575 fn issue_1052_require_delim_help() {
1576     static REQUIRE_DELIM_HELP: &str = "\
1577 tests stuff
1578 
1579 Usage: test --fake <some> <val>
1580 
1581 Options:
1582   -f, --fake <some> <val>  some help
1583   -h, --help               Print help
1584   -V, --version            Print version
1585 ";
1586 
1587     let cmd = Command::new("test")
1588         .author("Kevin K.")
1589         .about("tests stuff")
1590         .version("1.3")
1591         .arg(
1592             arg!(-f --fake <s> "some help")
1593                 .required(true)
1594                 .value_names(["some", "val"])
1595                 .action(ArgAction::Set)
1596                 .value_delimiter(':'),
1597         );
1598 
1599     utils::assert_output(cmd, "test --help", REQUIRE_DELIM_HELP, false);
1600 }
1601 
1602 #[test]
custom_headers_headers()1603 fn custom_headers_headers() {
1604     static CUSTOM_HELP_SECTION: &str = "\
1605 does stuff
1606 
1607 Usage: test [OPTIONS] --fake <some> <val>
1608 
1609 Options:
1610   -f, --fake <some> <val>  some help
1611   -h, --help               Print help
1612   -V, --version            Print version
1613 
1614 NETWORKING:
1615   -n, --no-proxy  Do not use system proxy settings
1616       --port
1617 ";
1618 
1619     let cmd = Command::new("blorp")
1620         .author("Will M.")
1621         .about("does stuff")
1622         .version("1.4")
1623         .arg(
1624             arg!(-f --fake <s> "some help")
1625                 .required(true)
1626                 .value_names(["some", "val"])
1627                 .action(ArgAction::Set)
1628                 .value_delimiter(':'),
1629         )
1630         .next_help_heading(Some("NETWORKING"))
1631         .arg(
1632             Arg::new("no-proxy")
1633                 .short('n')
1634                 .long("no-proxy")
1635                 .action(ArgAction::SetTrue)
1636                 .help("Do not use system proxy settings"),
1637         )
1638         .args([Arg::new("port").long("port").action(ArgAction::SetTrue)]);
1639 
1640     utils::assert_output(cmd, "test --help", CUSTOM_HELP_SECTION, false);
1641 }
1642 
1643 static MULTIPLE_CUSTOM_HELP_SECTIONS: &str = "\
1644 does stuff
1645 
1646 Usage: test [OPTIONS] --fake <some> <val> --birthday-song <song> --birthday-song-volume <volume>
1647 
1648 Options:
1649   -f, --fake <some> <val>  some help
1650       --style <style>      Choose musical style to play the song
1651   -s, --speed <SPEED>      How fast? [possible values: fast, slow]
1652   -h, --help               Print help
1653   -V, --version            Print version
1654 
1655 NETWORKING:
1656   -n, --no-proxy     Do not use system proxy settings
1657   -a, --server-addr  Set server address
1658 
1659 OVERRIDE SPECIAL:
1660   -b, --birthday-song <song>  Change which song is played for birthdays
1661 
1662 SPECIAL:
1663   -v, --birthday-song-volume <volume>  Change the volume of the birthday song
1664 ";
1665 
1666 #[test]
multiple_custom_help_headers()1667 fn multiple_custom_help_headers() {
1668     let cmd = Command::new("blorp")
1669         .author("Will M.")
1670         .about("does stuff")
1671         .version("1.4")
1672         .arg(
1673             arg!(-f --fake <s> "some help")
1674                 .required(true)
1675                 .value_names(["some", "val"])
1676                 .action(ArgAction::Set)
1677                 .value_delimiter(':'),
1678         )
1679         .next_help_heading(Some("NETWORKING"))
1680         .arg(
1681             Arg::new("no-proxy")
1682                 .short('n')
1683                 .long("no-proxy")
1684                 .action(ArgAction::SetTrue)
1685                 .help("Do not use system proxy settings"),
1686         )
1687         .next_help_heading(Some("SPECIAL"))
1688         .arg(
1689             arg!(-b --"birthday-song" <song> "Change which song is played for birthdays")
1690                 .required(true)
1691                 .help_heading(Some("OVERRIDE SPECIAL")),
1692         )
1693         .arg(arg!(--style <style> "Choose musical style to play the song").help_heading(None))
1694         .arg(
1695             arg!(
1696                 -v --"birthday-song-volume" <volume> "Change the volume of the birthday song"
1697             )
1698             .required(true),
1699         )
1700         .next_help_heading(None)
1701         .arg(
1702             Arg::new("server-addr")
1703                 .short('a')
1704                 .long("server-addr")
1705                 .action(ArgAction::SetTrue)
1706                 .help("Set server address")
1707                 .help_heading(Some("NETWORKING")),
1708         )
1709         .arg(
1710             Arg::new("speed")
1711                 .long("speed")
1712                 .short('s')
1713                 .value_name("SPEED")
1714                 .value_parser(["fast", "slow"])
1715                 .help("How fast?")
1716                 .action(ArgAction::Set),
1717         );
1718 
1719     utils::assert_output(cmd, "test --help", MULTIPLE_CUSTOM_HELP_SECTIONS, false);
1720 }
1721 
1722 static CUSTOM_HELP_SECTION_HIDDEN_ARGS: &str = "\
1723 does stuff
1724 
1725 Usage: test [OPTIONS] --song <song> --song-volume <volume>
1726 
1727 Options:
1728   -h, --help     Print help (see more with '--help')
1729   -V, --version  Print version
1730 
1731 OVERRIDE SPECIAL:
1732   -b, --song <song>  Change which song is played for birthdays
1733 
1734 SPECIAL:
1735   -v, --song-volume <volume>  Change the volume of the birthday song
1736 ";
1737 
1738 #[test]
custom_help_headers_hide_args()1739 fn custom_help_headers_hide_args() {
1740     let cmd = Command::new("blorp")
1741         .author("Will M.")
1742         .about("does stuff")
1743         .version("1.4")
1744         .next_help_heading(Some("NETWORKING"))
1745         .arg(
1746             Arg::new("no-proxy")
1747                 .short('n')
1748                 .long("no-proxy")
1749                 .help("Do not use system proxy settings")
1750                 .hide_short_help(true),
1751         )
1752         .next_help_heading(Some("SPECIAL"))
1753         .arg(
1754             arg!(-b --song <song> "Change which song is played for birthdays")
1755                 .required(true)
1756                 .help_heading(Some("OVERRIDE SPECIAL")),
1757         )
1758         .arg(
1759             arg!(
1760                 -v --"song-volume" <volume> "Change the volume of the birthday song"
1761             )
1762             .required(true),
1763         )
1764         .next_help_heading(None)
1765         .arg(
1766             Arg::new("server-addr")
1767                 .short('a')
1768                 .long("server-addr")
1769                 .help("Set server address")
1770                 .help_heading(Some("NETWORKING"))
1771                 .hide_short_help(true),
1772         );
1773 
1774     utils::assert_output(cmd, "test -h", CUSTOM_HELP_SECTION_HIDDEN_ARGS, false);
1775 }
1776 
1777 static ISSUE_897: &str = "\
1778 Long about foo
1779 
1780 Usage: ctest foo
1781 
1782 Options:
1783   -h, --help
1784           Print help (see a summary with '-h')
1785 
1786   -V, --version
1787           Print version
1788 ";
1789 
1790 #[test]
show_long_about_issue_897()1791 fn show_long_about_issue_897() {
1792     let cmd = Command::new("ctest").version("0.1").subcommand(
1793         Command::new("foo")
1794             .version("0.1")
1795             .about("About foo")
1796             .long_about("Long about foo"),
1797     );
1798     utils::assert_output(cmd, "ctest foo --help", ISSUE_897, false);
1799 }
1800 
1801 static ISSUE_897_SHORT: &str = "\
1802 About foo
1803 
1804 Usage: ctest foo
1805 
1806 Options:
1807   -h, --help     Print help (see more with '--help')
1808   -V, --version  Print version
1809 ";
1810 
1811 #[test]
show_short_about_issue_897()1812 fn show_short_about_issue_897() {
1813     let cmd = Command::new("ctest").version("0.1").subcommand(
1814         Command::new("foo")
1815             .version("0.1")
1816             .about("About foo")
1817             .long_about("Long about foo"),
1818     );
1819     utils::assert_output(cmd, "ctest foo -h", ISSUE_897_SHORT, false);
1820 }
1821 
1822 #[test]
issue_1364_no_short_options()1823 fn issue_1364_no_short_options() {
1824     static ISSUE_1364: &str = "\
1825 Usage: demo [OPTIONS] [FILES]...
1826 
1827 Arguments:
1828   [FILES]...
1829 
1830 Options:
1831   -f
1832   -h, --help  Print help (see more with '--help')
1833 ";
1834 
1835     let cmd = Command::new("demo")
1836         .arg(Arg::new("foo").short('f').action(ArgAction::SetTrue))
1837         .arg(
1838             Arg::new("baz")
1839                 .short('z')
1840                 .value_name("BAZ")
1841                 .hide_short_help(true),
1842         )
1843         .arg(
1844             Arg::new("files")
1845                 .value_name("FILES")
1846                 .action(ArgAction::Set)
1847                 .num_args(1..),
1848         );
1849 
1850     utils::assert_output(cmd, "demo -h", ISSUE_1364, false);
1851 }
1852 
1853 #[rustfmt::skip]
1854 #[test]
issue_1487()1855 fn issue_1487() {
1856 static ISSUE_1487: &str = "\
1857 Usage: ctest <arg1|arg2>
1858 
1859 Arguments:
1860   [arg1]
1861   [arg2]
1862 
1863 Options:
1864   -h, --help  Print help
1865 ";
1866 
1867     let cmd = Command::new("test")
1868     .arg(Arg::new("arg1")
1869         .group("group1"))
1870     .arg(Arg::new("arg2")
1871         .group("group1"))
1872     .group(ArgGroup::new("group1")
1873         .args(["arg1", "arg2"])
1874         .required(true));
1875     utils::assert_output(cmd, "ctest -h", ISSUE_1487, false);
1876 }
1877 
1878 #[cfg(debug_assertions)]
1879 #[test]
1880 #[should_panic = "Command::help_expected is enabled for the Command"]
help_required_but_not_given()1881 fn help_required_but_not_given() {
1882     Command::new("myapp")
1883         .help_expected(true)
1884         .arg(Arg::new("foo"))
1885         .try_get_matches_from(empty_args())
1886         .unwrap();
1887 }
1888 
1889 #[cfg(debug_assertions)]
1890 #[test]
1891 #[should_panic = "Command::help_expected is enabled for the Command"]
help_required_but_not_given_settings_after_args()1892 fn help_required_but_not_given_settings_after_args() {
1893     Command::new("myapp")
1894         .arg(Arg::new("foo"))
1895         .help_expected(true)
1896         .try_get_matches_from(empty_args())
1897         .unwrap();
1898 }
1899 
1900 #[cfg(debug_assertions)]
1901 #[test]
1902 #[should_panic = "Command::help_expected is enabled for the Command"]
help_required_but_not_given_for_one_of_two_arguments()1903 fn help_required_but_not_given_for_one_of_two_arguments() {
1904     Command::new("myapp")
1905         .help_expected(true)
1906         .arg(Arg::new("foo"))
1907         .arg(Arg::new("bar").help("It does bar stuff"))
1908         .try_get_matches_from(empty_args())
1909         .unwrap();
1910 }
1911 
1912 #[test]
1913 #[should_panic = "List of such arguments: delete"]
help_required_globally()1914 fn help_required_globally() {
1915     Command::new("myapp")
1916         .help_expected(true)
1917         .arg(Arg::new("foo").help("It does foo stuff"))
1918         .subcommand(
1919             Command::new("bar")
1920                 .arg(Arg::new("create").help("creates bar"))
1921                 .arg(Arg::new("delete")),
1922         )
1923         .try_get_matches_from(empty_args())
1924         .unwrap();
1925 }
1926 
1927 #[cfg(debug_assertions)]
1928 #[test]
1929 #[should_panic = "Command::help_expected is enabled for the Command"]
help_required_globally_but_not_given_for_subcommand()1930 fn help_required_globally_but_not_given_for_subcommand() {
1931     Command::new("myapp")
1932         .help_expected(true)
1933         .arg(Arg::new("foo").help("It does foo stuff"))
1934         .subcommand(
1935             Command::new("bar")
1936                 .arg(Arg::new("create").help("creates bar"))
1937                 .arg(Arg::new("delete")),
1938         )
1939         .try_get_matches_from(empty_args())
1940         .unwrap();
1941 }
1942 
1943 #[test]
help_required_and_given_for_subcommand()1944 fn help_required_and_given_for_subcommand() {
1945     Command::new("myapp")
1946         .help_expected(true)
1947         .arg(Arg::new("foo").help("It does foo stuff"))
1948         .subcommand(
1949             Command::new("bar")
1950                 .arg(Arg::new("create").help("creates bar"))
1951                 .arg(Arg::new("delete").help("deletes bar")),
1952         )
1953         .try_get_matches_from(empty_args())
1954         .unwrap();
1955 }
1956 
1957 #[test]
help_required_and_given()1958 fn help_required_and_given() {
1959     Command::new("myapp")
1960         .help_expected(true)
1961         .arg(Arg::new("foo").help("It does foo stuff"))
1962         .try_get_matches_from(empty_args())
1963         .unwrap();
1964 }
1965 
1966 #[test]
help_required_and_no_args()1967 fn help_required_and_no_args() {
1968     Command::new("myapp")
1969         .help_expected(true)
1970         .try_get_matches_from(empty_args())
1971         .unwrap();
1972 }
1973 
1974 #[test]
issue_1642_long_help_spacing()1975 fn issue_1642_long_help_spacing() {
1976     static ISSUE_1642: &str = "\
1977 Usage: prog [OPTIONS]
1978 
1979 Options:
1980       --config
1981           The config file used by the myprog must be in JSON format
1982           with only valid keys and may not contain other nonsense
1983           that cannot be read by this program. Obviously I'm going on
1984           and on, so I'll stop now.
1985 
1986   -h, --help
1987           Print help (see a summary with '-h')
1988 ";
1989 
1990     let cmd = Command::new("prog").arg(
1991         Arg::new("cfg")
1992             .long("config")
1993             .action(ArgAction::SetTrue)
1994             .long_help(
1995                 "The config file used by the myprog must be in JSON format
1996 with only valid keys and may not contain other nonsense
1997 that cannot be read by this program. Obviously I'm going on
1998 and on, so I'll stop now.",
1999             ),
2000     );
2001     utils::assert_output(cmd, "prog --help", ISSUE_1642, false);
2002 }
2003 
2004 const AFTER_HELP_NO_ARGS: &str = "\
2005 Usage: myapp
2006 
2007 This is after help.
2008 ";
2009 
2010 #[test]
after_help_no_args()2011 fn after_help_no_args() {
2012     let mut cmd = Command::new("myapp")
2013         .version("1.0")
2014         .disable_help_flag(true)
2015         .disable_version_flag(true)
2016         .after_help("This is after help.");
2017 
2018     let help = cmd.render_help().to_string();
2019 
2020     assert_eq!(help, AFTER_HELP_NO_ARGS);
2021 }
2022 
2023 #[test]
help_subcmd_help()2024 fn help_subcmd_help() {
2025     static HELP_SUBCMD_HELP: &str = "\
2026 Print this message or the help of the given subcommand(s)
2027 
2028 Usage: myapp help [COMMAND]...
2029 
2030 Arguments:
2031   [COMMAND]...  Print help for the subcommand(s)
2032 ";
2033 
2034     let cmd = Command::new("myapp")
2035         .subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
2036 
2037     utils::assert_output(cmd.clone(), "myapp help help", HELP_SUBCMD_HELP, false);
2038 }
2039 
2040 #[test]
subcmd_help_subcmd_help()2041 fn subcmd_help_subcmd_help() {
2042     static SUBCMD_HELP_SUBCMD_HELP: &str = "\
2043 Print this message or the help of the given subcommand(s)
2044 
2045 Usage: myapp subcmd help [COMMAND]...
2046 
2047 Arguments:
2048   [COMMAND]...  Print help for the subcommand(s)
2049 ";
2050 
2051     let cmd = Command::new("myapp")
2052         .subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
2053 
2054     utils::assert_output(
2055         cmd.clone(),
2056         "myapp subcmd help help",
2057         SUBCMD_HELP_SUBCMD_HELP,
2058         false,
2059     );
2060 }
2061 
2062 #[test]
global_args_should_show_on_toplevel_help_message()2063 fn global_args_should_show_on_toplevel_help_message() {
2064     static HELP: &str = "\
2065 Usage: myapp [OPTIONS] [COMMAND]
2066 
2067 Commands:
2068   subcmd\x20\x20
2069   help    Print this message or the help of the given subcommand(s)
2070 
2071 Options:
2072   -g, --some-global <someglobal>\x20\x20
2073   -h, --help                      Print help
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, false);
2086 }
2087 
2088 #[test]
global_args_should_not_show_on_help_message_for_help_help()2089 fn global_args_should_not_show_on_help_message_for_help_help() {
2090     static HELP_HELP: &str = "\
2091 Print this message or the help of the given subcommand(s)
2092 
2093 Usage: myapp help [COMMAND]...
2094 
2095 Arguments:
2096   [COMMAND]...  Print help for the subcommand(s)
2097 ";
2098 
2099     let cmd = Command::new("myapp")
2100         .arg(
2101             Arg::new("someglobal")
2102                 .short('g')
2103                 .long("some-global")
2104                 .global(true),
2105         )
2106         .subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
2107 
2108     utils::assert_output(cmd, "myapp help help", HELP_HELP, false);
2109 }
2110 
2111 #[test]
global_args_should_show_on_help_message_for_subcommand()2112 fn global_args_should_show_on_help_message_for_subcommand() {
2113     static HELP_SUBCMD: &str = "\
2114 Usage: myapp subcmd [OPTIONS] [COMMAND]
2115 
2116 Commands:
2117   multi\x20\x20
2118   help   Print this message or the help of the given subcommand(s)
2119 
2120 Options:
2121   -g, --some-global <someglobal>\x20\x20
2122   -h, --help                      Print help
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", HELP_SUBCMD, false);
2135 }
2136 
2137 #[test]
global_args_should_show_on_help_message_for_nested_subcommand()2138 fn global_args_should_show_on_help_message_for_nested_subcommand() {
2139     static HELP_SUB_SUBCMD: &str = "\
2140 Usage: myapp subcmd multi [OPTIONS]
2141 
2142 Options:
2143   -g, --some-global <someglobal>\x20\x20
2144   -h, --help                      Print help
2145   -V, --version                   Print version
2146 ";
2147 
2148     let cmd = Command::new("myapp")
2149         .arg(
2150             Arg::new("someglobal")
2151                 .short('g')
2152                 .long("some-global")
2153                 .global(true),
2154         )
2155         .subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
2156 
2157     utils::assert_output(cmd, "myapp help subcmd multi", HELP_SUB_SUBCMD, false);
2158 }
2159 
2160 #[test]
option_usage_order()2161 fn option_usage_order() {
2162     static OPTION_USAGE_ORDER: &str = "\
2163 Usage: order [OPTIONS]
2164 
2165 Options:
2166   -a
2167   -B
2168   -b
2169   -s
2170       --select_file
2171       --select_folder
2172   -x
2173   -h, --help           Print help
2174 ";
2175 
2176     let cmd = Command::new("order").args([
2177         Arg::new("a").short('a').action(ArgAction::SetTrue),
2178         Arg::new("B").short('B').action(ArgAction::SetTrue),
2179         Arg::new("b").short('b').action(ArgAction::SetTrue),
2180         Arg::new("save").short('s').action(ArgAction::SetTrue),
2181         Arg::new("select_file")
2182             .long("select_file")
2183             .action(ArgAction::SetTrue),
2184         Arg::new("select_folder")
2185             .long("select_folder")
2186             .action(ArgAction::SetTrue),
2187         Arg::new("x").short('x').action(ArgAction::SetTrue),
2188     ]);
2189 
2190     utils::assert_output(cmd, "order --help", OPTION_USAGE_ORDER, false);
2191 }
2192 
2193 #[test]
prefer_about_over_long_about_in_subcommands_list()2194 fn prefer_about_over_long_about_in_subcommands_list() {
2195     static ABOUT_IN_COMMANDS_LIST: &str = "\
2196 Usage: about-in-subcommands-list [COMMAND]
2197 
2198 Commands:
2199   sub   short about sub
2200   help  Print this message or the help of the given subcommand(s)
2201 
2202 Options:
2203   -h, --help  Print help
2204 ";
2205 
2206     let cmd = Command::new("about-in-subcommands-list").subcommand(
2207         Command::new("sub")
2208             .long_about("long about sub")
2209             .about("short about sub"),
2210     );
2211 
2212     utils::assert_output(
2213         cmd,
2214         "about-in-subcommands-list --help",
2215         ABOUT_IN_COMMANDS_LIST,
2216         false,
2217     );
2218 }
2219 
2220 #[test]
issue_1794_usage()2221 fn issue_1794_usage() {
2222     static USAGE_WITH_GROUP: &str = "\
2223 Usage: deno <pos1|--option1> [pos2]
2224 
2225 Arguments:
2226   [pos1]
2227   [pos2]
2228 
2229 Options:
2230       --option1
2231   -h, --help     Print help
2232 ";
2233 
2234     let cmd = clap::Command::new("hello")
2235         .bin_name("deno")
2236         .arg(
2237             Arg::new("option1")
2238                 .long("option1")
2239                 .action(ArgAction::SetTrue),
2240         )
2241         .arg(Arg::new("pos1").action(ArgAction::Set))
2242         .group(
2243             ArgGroup::new("arg1")
2244                 .args(["pos1", "option1"])
2245                 .required(true),
2246         )
2247         .arg(Arg::new("pos2").action(ArgAction::Set));
2248 
2249     utils::assert_output(cmd, "deno --help", USAGE_WITH_GROUP, false);
2250 }
2251 
2252 static CUSTOM_HEADING_POS: &str = "\
2253 Usage: test [gear] [speed]
2254 
2255 Arguments:
2256   [gear]  Which gear
2257 
2258 Options:
2259   -h, --help     Print help
2260   -V, --version  Print version
2261 
2262 NETWORKING:
2263   [speed]  How fast
2264 ";
2265 
2266 #[test]
custom_heading_pos()2267 fn custom_heading_pos() {
2268     let cmd = Command::new("test")
2269         .version("1.4")
2270         .arg(Arg::new("gear").help("Which gear"))
2271         .next_help_heading(Some("NETWORKING"))
2272         .arg(Arg::new("speed").help("How fast"));
2273 
2274     utils::assert_output(cmd, "test --help", CUSTOM_HEADING_POS, false);
2275 }
2276 
2277 static ONLY_CUSTOM_HEADING_OPTS_NO_ARGS: &str = "\
2278 Usage: test [OPTIONS]
2279 
2280 NETWORKING:
2281   -s, --speed <SPEED>  How fast
2282 ";
2283 
2284 #[test]
only_custom_heading_opts_no_args()2285 fn only_custom_heading_opts_no_args() {
2286     let cmd = Command::new("test")
2287         .version("1.4")
2288         .disable_version_flag(true)
2289         .disable_help_flag(true)
2290         .arg(arg!(--help).action(ArgAction::Help).hide(true))
2291         .next_help_heading(Some("NETWORKING"))
2292         .arg(arg!(-s --speed <SPEED> "How fast"));
2293 
2294     utils::assert_output(cmd, "test --help", ONLY_CUSTOM_HEADING_OPTS_NO_ARGS, false);
2295 }
2296 
2297 static ONLY_CUSTOM_HEADING_POS_NO_ARGS: &str = "\
2298 Usage: test [speed]
2299 
2300 NETWORKING:
2301   [speed]  How fast
2302 ";
2303 
2304 #[test]
only_custom_heading_pos_no_args()2305 fn only_custom_heading_pos_no_args() {
2306     let cmd = Command::new("test")
2307         .version("1.4")
2308         .disable_version_flag(true)
2309         .disable_help_flag(true)
2310         .arg(arg!(--help).action(ArgAction::Help).hide(true))
2311         .next_help_heading(Some("NETWORKING"))
2312         .arg(Arg::new("speed").help("How fast"));
2313 
2314     utils::assert_output(cmd, "test --help", ONLY_CUSTOM_HEADING_POS_NO_ARGS, false);
2315 }
2316 
2317 #[test]
issue_2508_number_of_values_with_single_value_name()2318 fn issue_2508_number_of_values_with_single_value_name() {
2319     let cmd = Command::new("my_app")
2320         .arg(Arg::new("some_arg").long("some_arg").num_args(2))
2321         .arg(
2322             Arg::new("some_arg_issue")
2323                 .long("some_arg_issue")
2324                 .num_args(2)
2325                 .value_name("ARG"),
2326         );
2327     utils::assert_output(
2328         cmd,
2329         "my_app --help",
2330         "\
2331 Usage: my_app [OPTIONS]
2332 
2333 Options:
2334       --some_arg <some_arg> <some_arg>
2335       --some_arg_issue <ARG> <ARG>
2336   -h, --help                            Print help
2337 ",
2338         false,
2339     );
2340 }
2341 
2342 #[test]
missing_positional_final_required()2343 fn missing_positional_final_required() {
2344     let cmd = Command::new("test")
2345         .allow_missing_positional(true)
2346         .arg(Arg::new("arg1"))
2347         .arg(Arg::new("arg2").required(true));
2348     utils::assert_output(
2349         cmd,
2350         "test --help",
2351         "\
2352 Usage: test [arg1] <arg2>
2353 
2354 Arguments:
2355   [arg1]
2356   <arg2>
2357 
2358 Options:
2359   -h, --help  Print help
2360 ",
2361         false,
2362     );
2363 }
2364 
2365 #[test]
missing_positional_final_multiple()2366 fn missing_positional_final_multiple() {
2367     let cmd = Command::new("test")
2368         .allow_missing_positional(true)
2369         .arg(Arg::new("foo"))
2370         .arg(Arg::new("bar"))
2371         .arg(Arg::new("baz").action(ArgAction::Set).num_args(1..));
2372     utils::assert_output(
2373         cmd,
2374         "test --help",
2375         "\
2376 Usage: test [foo] [bar] [baz]...
2377 
2378 Arguments:
2379   [foo]
2380   [bar]
2381   [baz]...
2382 
2383 Options:
2384   -h, --help  Print help
2385 ",
2386         false,
2387     );
2388 }
2389 
2390 #[test]
positional_multiple_values_is_dotted()2391 fn positional_multiple_values_is_dotted() {
2392     let cmd = Command::new("test").arg(
2393         Arg::new("foo")
2394             .required(true)
2395             .action(ArgAction::Set)
2396             .num_args(1..),
2397     );
2398     utils::assert_output(
2399         cmd,
2400         "test --help",
2401         "\
2402 Usage: test <foo>...
2403 
2404 Arguments:
2405   <foo>...
2406 
2407 Options:
2408   -h, --help  Print help
2409 ",
2410         false,
2411     );
2412 
2413     let cmd = Command::new("test").arg(
2414         Arg::new("foo")
2415             .required(true)
2416             .action(ArgAction::Set)
2417             .value_name("BAR")
2418             .num_args(1..),
2419     );
2420     utils::assert_output(
2421         cmd,
2422         "test --help",
2423         "\
2424 Usage: test <BAR>...
2425 
2426 Arguments:
2427   <BAR>...
2428 
2429 Options:
2430   -h, --help  Print help
2431 ",
2432         false,
2433     );
2434 }
2435 
2436 #[test]
positional_multiple_occurrences_is_dotted()2437 fn positional_multiple_occurrences_is_dotted() {
2438     let cmd = Command::new("test").arg(
2439         Arg::new("foo")
2440             .required(true)
2441             .action(ArgAction::Set)
2442             .num_args(1..)
2443             .action(ArgAction::Append),
2444     );
2445     utils::assert_output(
2446         cmd,
2447         "test --help",
2448         "\
2449 Usage: test <foo>...
2450 
2451 Arguments:
2452   <foo>...
2453 
2454 Options:
2455   -h, --help  Print help
2456 ",
2457         false,
2458     );
2459 
2460     let cmd = Command::new("test").arg(
2461         Arg::new("foo")
2462             .required(true)
2463             .action(ArgAction::Set)
2464             .value_name("BAR")
2465             .num_args(1..)
2466             .action(ArgAction::Append),
2467     );
2468     utils::assert_output(
2469         cmd,
2470         "test --help",
2471         "\
2472 Usage: test <BAR>...
2473 
2474 Arguments:
2475   <BAR>...
2476 
2477 Options:
2478   -h, --help  Print help
2479 ",
2480         false,
2481     );
2482 }
2483 
2484 #[test]
too_few_value_names_is_dotted()2485 fn too_few_value_names_is_dotted() {
2486     let cmd = Command::new("test").arg(
2487         Arg::new("foo")
2488             .long("foo")
2489             .required(true)
2490             .action(ArgAction::Set)
2491             .num_args(3)
2492             .value_names(["one", "two"]),
2493     );
2494     utils::assert_output(
2495         cmd,
2496         "test --help",
2497         "\
2498 Usage: test --foo <one> <two>...
2499 
2500 Options:
2501       --foo <one> <two>...
2502   -h, --help                Print help
2503 ",
2504         false,
2505     );
2506 }
2507 
2508 #[test]
2509 #[should_panic = "Argument foo: Too many value names (2) compared to `num_args` (1)"]
too_many_value_names_panics()2510 fn too_many_value_names_panics() {
2511     Command::new("test")
2512         .arg(
2513             Arg::new("foo")
2514                 .long("foo")
2515                 .required(true)
2516                 .action(ArgAction::Set)
2517                 .num_args(1)
2518                 .value_names(["one", "two"]),
2519         )
2520         .debug_assert()
2521 }
2522 
2523 #[test]
disabled_help_flag()2524 fn disabled_help_flag() {
2525     let res = Command::new("foo")
2526         .subcommand(Command::new("sub"))
2527         .disable_help_flag(true)
2528         .try_get_matches_from("foo a".split(' '));
2529     assert!(res.is_err());
2530     let err = res.unwrap_err();
2531     assert_eq!(err.kind(), ErrorKind::InvalidSubcommand);
2532 }
2533 
2534 #[test]
disabled_help_flag_and_subcommand()2535 fn disabled_help_flag_and_subcommand() {
2536     let res = Command::new("foo")
2537         .subcommand(Command::new("sub"))
2538         .disable_help_flag(true)
2539         .disable_help_subcommand(true)
2540         .try_get_matches_from("foo help".split(' '));
2541     assert!(res.is_err());
2542     let err = res.unwrap_err();
2543     assert_eq!(err.kind(), ErrorKind::InvalidSubcommand);
2544     assert!(
2545         err.to_string().ends_with('\n'),
2546         "Errors should have a trailing newline, got {:?}",
2547         err.to_string()
2548     );
2549 }
2550 
2551 #[test]
override_help_subcommand()2552 fn override_help_subcommand() {
2553     let cmd = Command::new("bar")
2554         .subcommand(Command::new("help").arg(Arg::new("arg").action(ArgAction::Set)))
2555         .subcommand(Command::new("not_help").arg(Arg::new("arg").action(ArgAction::Set)))
2556         .disable_help_subcommand(true);
2557     let matches = cmd.try_get_matches_from(["bar", "help", "foo"]).unwrap();
2558     assert_eq!(
2559         matches
2560             .subcommand_matches("help")
2561             .unwrap()
2562             .get_one::<String>("arg")
2563             .map(|v| v.as_str()),
2564         Some("foo")
2565     );
2566 }
2567 
2568 #[test]
override_help_flag_using_long()2569 fn override_help_flag_using_long() {
2570     let cmd = Command::new("foo")
2571         .subcommand(Command::new("help").long_flag("help"))
2572         .disable_help_flag(true)
2573         .disable_help_subcommand(true);
2574     let matches = cmd.try_get_matches_from(["foo", "--help"]).unwrap();
2575     assert!(matches.subcommand_matches("help").is_some());
2576 }
2577 
2578 #[test]
override_help_flag_using_short()2579 fn override_help_flag_using_short() {
2580     let cmd = Command::new("foo")
2581         .disable_help_flag(true)
2582         .disable_help_subcommand(true)
2583         .subcommand(Command::new("help").short_flag('h'));
2584     let matches = cmd.try_get_matches_from(["foo", "-h"]).unwrap();
2585     assert!(matches.subcommand_matches("help").is_some());
2586 }
2587 
2588 #[test]
subcommand_help_doesnt_have_useless_help_flag()2589 fn subcommand_help_doesnt_have_useless_help_flag() {
2590     // The main care-about is that the docs and behavior match.  Since the `help` subcommand
2591     // currently ignores the `--help` flag, the output shouldn't have it.
2592     let cmd = Command::new("example").subcommand(Command::new("test").about("Subcommand"));
2593 
2594     utils::assert_output(
2595         cmd,
2596         "example help help",
2597         "\
2598 Print this message or the help of the given subcommand(s)
2599 
2600 Usage: example help [COMMAND]...
2601 
2602 Arguments:
2603   [COMMAND]...  Print help for the subcommand(s)
2604 ",
2605         false,
2606     );
2607 }
2608 
2609 #[test]
disable_help_flag_affects_help_subcommand()2610 fn disable_help_flag_affects_help_subcommand() {
2611     let mut cmd = Command::new("test_app")
2612         .disable_help_flag(true)
2613         .subcommand(Command::new("test").about("Subcommand"));
2614     cmd.build();
2615 
2616     let args = cmd
2617         .find_subcommand("help")
2618         .unwrap()
2619         .get_arguments()
2620         .map(|a| a.get_id().as_str())
2621         .collect::<Vec<_>>();
2622     assert!(
2623         !args.contains(&"help"),
2624         "`help` should not be present: {:?}",
2625         args
2626     );
2627 }
2628 
2629 #[test]
dont_propagate_version_to_help_subcommand()2630 fn dont_propagate_version_to_help_subcommand() {
2631     let cmd = clap::Command::new("example")
2632         .version("1.0")
2633         .propagate_version(true)
2634         .subcommand(clap::Command::new("subcommand"));
2635 
2636     utils::assert_output(
2637         cmd.clone(),
2638         "example help help",
2639         "\
2640 Print this message or the help of the given subcommand(s)
2641 
2642 Usage: example help [COMMAND]...
2643 
2644 Arguments:
2645   [COMMAND]...  Print help for the subcommand(s)
2646 ",
2647         false,
2648     );
2649 
2650     cmd.debug_assert();
2651 }
2652 
2653 #[test]
help_without_short()2654 fn help_without_short() {
2655     let mut cmd = clap::Command::new("test")
2656         .arg(arg!(-h --hex <NUM>).required(true))
2657         .arg(arg!(--help).action(ArgAction::Help))
2658         .disable_help_flag(true);
2659 
2660     cmd.build();
2661     let help = cmd.get_arguments().find(|a| a.get_id() == "help").unwrap();
2662     assert_eq!(help.get_short(), None);
2663 
2664     let m = cmd.try_get_matches_from(["test", "-h", "0x100"]).unwrap();
2665     assert_eq!(
2666         m.get_one::<String>("hex").map(|v| v.as_str()),
2667         Some("0x100")
2668     );
2669 }
2670 
2671 #[test]
parent_cmd_req_in_usage_with_help_flag()2672 fn parent_cmd_req_in_usage_with_help_flag() {
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 test --help", EXPECTED, false);
2692 }
2693 
2694 #[test]
parent_cmd_req_in_usage_with_help_subcommand()2695 fn parent_cmd_req_in_usage_with_help_subcommand() {
2696     static EXPECTED: &str = "\
2697 some
2698 
2699 Usage: parent <TARGET> <ARGS> test
2700 
2701 Options:
2702   -h, --help  Print help
2703 ";
2704     let 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     utils::assert_output(cmd, "parent help test", EXPECTED, false);
2715 }
2716 
2717 #[test]
parent_cmd_req_in_usage_with_render_help()2718 fn parent_cmd_req_in_usage_with_render_help() {
2719     static EXPECTED: &str = "\
2720 some
2721 
2722 Usage: parent <TARGET> <ARGS> test
2723 
2724 Options:
2725   -h, --help  Print help
2726 ";
2727     let mut cmd = Command::new("parent")
2728         .version("0.1")
2729         .arg(Arg::new("TARGET").required(true).help("some"))
2730         .arg(
2731             Arg::new("ARGS")
2732                 .action(ArgAction::Set)
2733                 .required(true)
2734                 .help("some"),
2735         )
2736         .subcommand(Command::new("test").about("some"));
2737     cmd.build();
2738     let subcmd = cmd.find_subcommand_mut("test").unwrap();
2739 
2740     let help = subcmd.render_help().to_string();
2741     utils::assert_eq(EXPECTED, help);
2742 }
2743 
2744 #[test]
parent_cmd_req_ignored_when_negates_reqs()2745 fn parent_cmd_req_ignored_when_negates_reqs() {
2746     static MULTI_SC_HELP: &str = "\
2747 Usage: ctest subcmd
2748 
2749 Options:
2750   -h, --help  Print help
2751 ";
2752 
2753     let cmd = Command::new("ctest")
2754         .arg(arg!(<input>))
2755         .subcommand_negates_reqs(true)
2756         .subcommand(Command::new("subcmd"));
2757     utils::assert_output(cmd, "ctest subcmd --help", MULTI_SC_HELP, false);
2758 }
2759 
2760 #[test]
parent_cmd_req_ignored_when_conflicts()2761 fn parent_cmd_req_ignored_when_conflicts() {
2762     static MULTI_SC_HELP: &str = "\
2763 Usage: ctest subcmd
2764 
2765 Options:
2766   -h, --help  Print help
2767 ";
2768 
2769     let cmd = Command::new("ctest")
2770         .arg(arg!(<input>))
2771         .args_conflicts_with_subcommands(true)
2772         .subcommand(Command::new("subcmd"));
2773     utils::assert_output(cmd, "ctest subcmd --help", MULTI_SC_HELP, false);
2774 }
2775 
2776 #[test]
no_wrap_help()2777 fn no_wrap_help() {
2778     let cmd = Command::new("ctest")
2779         .term_width(0)
2780         .override_help(MULTI_SC_HELP);
2781     utils::assert_output(cmd, "ctest --help", MULTI_SC_HELP, false);
2782 }
2783 
2784 #[test]
display_name_default()2785 fn display_name_default() {
2786     let mut cmd = Command::new("app").bin_name("app.exe");
2787     cmd.build();
2788     assert_eq!(cmd.get_display_name(), None);
2789 }
2790 
2791 #[test]
display_name_explicit()2792 fn display_name_explicit() {
2793     let mut cmd = Command::new("app")
2794         .bin_name("app.exe")
2795         .display_name("app.display");
2796     cmd.build();
2797     assert_eq!(cmd.get_display_name(), Some("app.display"));
2798 }
2799 
2800 #[test]
display_name_subcommand_default()2801 fn display_name_subcommand_default() {
2802     let mut cmd = Command::new("parent").subcommand(Command::new("child").bin_name("child.exe"));
2803     cmd.build();
2804     assert_eq!(
2805         cmd.find_subcommand("child").unwrap().get_display_name(),
2806         Some("parent-child")
2807     );
2808 }
2809 
2810 #[test]
display_name_subcommand_explicit()2811 fn display_name_subcommand_explicit() {
2812     let mut cmd = Command::new("parent").subcommand(
2813         Command::new("child")
2814             .bin_name("child.exe")
2815             .display_name("child.display"),
2816     );
2817     cmd.build();
2818     assert_eq!(
2819         cmd.find_subcommand("child").unwrap().get_display_name(),
2820         Some("child.display")
2821     );
2822 }
2823