PageRenderTime 67ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/help.rs

https://github.com/kbknapp/clap-rs
Rust | 2161 lines | 1983 code | 177 blank | 1 comment | 1 complexity | dcf329491b91bff5b1e5e73c51fa20c8 MD5 | raw file
Possible License(s): MIT

Large files files are truncated, but you can click here to view the full file

  1. mod utils;
  2. use clap::{clap_app, App, AppSettings, Arg, ArgGroup, ArgSettings, ErrorKind};
  3. static REQUIRE_DELIM_HELP: &str = "test 1.3
  4. Kevin K.
  5. tests stuff
  6. USAGE:
  7. test --fake <some>:<val>
  8. FLAGS:
  9. -h, --help Prints help information
  10. -V, --version Prints version information
  11. OPTIONS:
  12. -f, --fake <some>:<val> some help";
  13. static HELP: &str = "clap-test v1.4.8
  14. Kevin K. <kbknapp@gmail.com>
  15. tests clap library
  16. USAGE:
  17. clap-test [FLAGS] [OPTIONS] [ARGS] [SUBCOMMAND]
  18. ARGS:
  19. <positional> tests positionals
  20. <positional2> tests positionals with exclusions
  21. <positional3>... tests specific values [possible values: vi, emacs]
  22. FLAGS:
  23. -f, --flag tests flags
  24. -F tests flags with exclusions
  25. -h, --help Prints help information
  26. -V, --version Prints version information
  27. OPTIONS:
  28. -O, --Option <option3> specific vals [possible values: fast, slow]
  29. --long-option-2 <option2> tests long options with exclusions
  30. --maxvals3 <maxvals>... Tests 3 max vals
  31. --minvals2 <minvals>... Tests 2 min vals
  32. --multvals <one> <two> Tests multiple values, not mult occs
  33. --multvalsmo <one> <two> Tests multiple values, and mult occs
  34. -o, --option <opt>... tests options
  35. SUBCOMMANDS:
  36. help Prints this message or the help of the given subcommand(s)
  37. subcmd tests subcommands";
  38. static SC_NEGATES_REQS: &str = "prog 1.0
  39. USAGE:
  40. prog --opt <FILE> [PATH]
  41. prog [PATH] <SUBCOMMAND>
  42. ARGS:
  43. <PATH> help
  44. FLAGS:
  45. -h, --help Prints help information
  46. -V, --version Prints version information
  47. OPTIONS:
  48. -o, --opt <FILE> tests options
  49. SUBCOMMANDS:
  50. help Prints this message or the help of the given subcommand(s)
  51. test";
  52. static ARGS_NEGATE_SC: &str = "prog 1.0
  53. USAGE:
  54. prog [FLAGS] [OPTIONS] [PATH]
  55. prog <SUBCOMMAND>
  56. ARGS:
  57. <PATH> help
  58. FLAGS:
  59. -f, --flag testing flags
  60. -h, --help Prints help information
  61. -V, --version Prints version information
  62. OPTIONS:
  63. -o, --opt <FILE> tests options
  64. SUBCOMMANDS:
  65. help Prints this message or the help of the given subcommand(s)
  66. test";
  67. static AFTER_HELP: &str = "some text that comes before the help
  68. clap-test v1.4.8
  69. tests clap library
  70. USAGE:
  71. clap-test
  72. FLAGS:
  73. -h, --help Prints help information
  74. -V, --version Prints version information
  75. some text that comes after the help";
  76. static AFTER_LONG_HELP: &str = "some longer text that comes before the help
  77. clap-test v1.4.8
  78. tests clap library
  79. USAGE:
  80. clap-test
  81. FLAGS:
  82. -h, --help
  83. Prints help information
  84. -V, --version
  85. Prints version information
  86. some longer text that comes after the help";
  87. static HIDDEN_ARGS: &str = "prog 1.0
  88. USAGE:
  89. prog [FLAGS] [OPTIONS]
  90. FLAGS:
  91. -f, --flag testing flags
  92. -h, --help Prints help information
  93. -V, --version Prints version information
  94. OPTIONS:
  95. -o, --opt <FILE> tests options";
  96. static SC_HELP: &str = "clap-test-subcmd 0.1
  97. Kevin K. <kbknapp@gmail.com>
  98. tests subcommands
  99. USAGE:
  100. clap-test subcmd [FLAGS] [OPTIONS] [--] [scpositional]
  101. ARGS:
  102. <scpositional> tests positionals
  103. FLAGS:
  104. -f, --flag tests flags
  105. -h, --help Prints help information
  106. -V, --version Prints version information
  107. OPTIONS:
  108. -o, --option <scoption>... tests options
  109. -s, --subcmdarg <subcmdarg> tests other args";
  110. static ISSUE_1046_HIDDEN_SCS: &str = "prog 1.0
  111. USAGE:
  112. prog [FLAGS] [OPTIONS] [PATH]
  113. ARGS:
  114. <PATH> some
  115. FLAGS:
  116. -f, --flag testing flags
  117. -h, --help Prints help information
  118. -V, --version Prints version information
  119. OPTIONS:
  120. -o, --opt <FILE> tests options";
  121. // Using number_of_values(1) with multiple(true) misaligns help message
  122. static ISSUE_760: &str = "ctest 0.1
  123. USAGE:
  124. ctest [OPTIONS]
  125. FLAGS:
  126. -h, --help Prints help information
  127. -V, --version Prints version information
  128. OPTIONS:
  129. -O, --opt <opt> tests options
  130. -o, --option <option>... tests options";
  131. static RIPGREP_USAGE: &str = "ripgrep 0.5
  132. USAGE:
  133. rg [OPTIONS] <pattern> [<path> ...]
  134. rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
  135. rg [OPTIONS] --files [<path> ...]
  136. rg [OPTIONS] --type-list
  137. FLAGS:
  138. -h, --help Prints help information
  139. -V, --version Prints version information";
  140. static MULTI_SC_HELP: &str = "ctest-subcmd-multi 0.1
  141. Kevin K. <kbknapp@gmail.com>
  142. tests subcommands
  143. USAGE:
  144. ctest subcmd multi [FLAGS] [OPTIONS]
  145. FLAGS:
  146. -f, --flag tests flags
  147. -h, --help Prints help information
  148. -V, --version Prints version information
  149. OPTIONS:
  150. -o, --option <scoption>... tests options";
  151. static ISSUE_626_CUTOFF: &str = "ctest 0.1
  152. USAGE:
  153. ctest [OPTIONS]
  154. FLAGS:
  155. -h, --help Prints help information
  156. -V, --version Prints version information
  157. OPTIONS:
  158. -c, --cafe <FILE> A coffeehouse, coffee shop, or café is an
  159. establishment which primarily serves hot
  160. coffee, related coffee beverages (e.g., café
  161. latte, cappuccino, espresso), tea, and other
  162. hot beverages. Some coffeehouses also serve
  163. cold beverages such as iced coffee and iced
  164. tea. Many cafés also serve some type of food,
  165. such as light snacks, muffins, or pastries.";
  166. static ISSUE_626_PANIC: &str = "ctest 0.1
  167. USAGE:
  168. ctest [OPTIONS]
  169. FLAGS:
  170. -h, --help Prints help information
  171. -V, --version Prints version information
  172. OPTIONS:
  173. -c, --cafe <FILE>
  174. La culture du café est très développée
  175. dans de nombreux pays à climat chaud
  176. d\'Amérique, d\'Afrique et d\'Asie, dans
  177. des plantations qui sont cultivées pour
  178. les marchés d\'exportation. Le café est
  179. souvent une contribution majeure aux
  180. exportations des régions productrices.";
  181. static HIDE_POS_VALS: &str = "ctest 0.1
  182. USAGE:
  183. ctest [OPTIONS]
  184. FLAGS:
  185. -h, --help Prints help information
  186. -V, --version Prints version information
  187. OPTIONS:
  188. -c, --cafe <FILE> A coffeehouse, coffee shop, or café.
  189. -p, --pos <VAL> Some vals [possible values: fast, slow]";
  190. static FINAL_WORD_WRAPPING: &str = "ctest 0.1
  191. USAGE:
  192. ctest
  193. FLAGS:
  194. -h, --help
  195. Prints help
  196. information
  197. -V, --version
  198. Prints
  199. version
  200. information";
  201. static OLD_NEWLINE_CHARS: &str = "ctest 0.1
  202. USAGE:
  203. ctest [FLAGS]
  204. FLAGS:
  205. -h, --help Prints help information
  206. -m Some help with some wrapping
  207. (Defaults to something)
  208. -V, --version Prints version information";
  209. static WRAPPING_NEWLINE_CHARS: &str = "ctest 0.1
  210. USAGE:
  211. ctest [mode]
  212. ARGS:
  213. <mode> x, max, maximum 20 characters, contains
  214. symbols.
  215. l, long Copy-friendly, 14
  216. characters, contains symbols.
  217. m, med, medium Copy-friendly, 8
  218. characters, contains symbols.
  219. FLAGS:
  220. -h, --help Prints help information
  221. -V, --version Prints version information";
  222. static ISSUE_688: &str = "ctest 0.1
  223. USAGE:
  224. ctest [OPTIONS]
  225. FLAGS:
  226. -h, --help Prints help information
  227. -V, --version Prints version information
  228. OPTIONS:
  229. --filter <filter> Sets the filter, or sampling method, to use for interpolation when resizing the particle
  230. images. The default is Linear (Bilinear). [possible values: Nearest, Linear, Cubic,
  231. Gaussian, Lanczos3]";
  232. static ISSUE_702: &str = "myapp 1.0
  233. foo
  234. bar
  235. USAGE:
  236. myapp [OPTIONS] [--] [ARGS]
  237. ARGS:
  238. <arg1> some option
  239. <arg2>... some option
  240. FLAGS:
  241. -h, --help Prints help information
  242. -V, --version Prints version information
  243. OPTIONS:
  244. -l, --label <label>... a label
  245. -o, --other <other> some other option
  246. -s, --some <some> some option";
  247. static ISSUE_777: &str = "A app with a crazy very long long
  248. long name hahaha 1.0
  249. Some Very Long Name and crazy long
  250. email <email@server.com>
  251. Show how the about text is not
  252. wrapped
  253. USAGE:
  254. ctest
  255. FLAGS:
  256. -h, --help
  257. Prints help information
  258. -V, --version
  259. Prints version
  260. information";
  261. static ISSUE_1642: &str = "prog
  262. USAGE:
  263. prog [FLAGS]
  264. FLAGS:
  265. --config
  266. The config file used by the myprog must be in JSON format
  267. with only valid keys and may not contain other nonsense
  268. that cannot be read by this program. Obviously I'm going on
  269. and on, so I'll stop now.
  270. -h, --help
  271. Prints help information
  272. -V, --version
  273. Prints version information";
  274. static CUSTOM_VERSION_AND_HELP: &str = "customize 0.1
  275. Nobody <odysseus@example.com>
  276. You can customize the version and help text
  277. USAGE:
  278. customize
  279. FLAGS:
  280. -H, --help Print help information
  281. -v, --version Print version information";
  282. static HELP_CONFLICT: &str = "conflict
  283. USAGE:
  284. conflict [FLAGS]
  285. FLAGS:
  286. --help Prints help information
  287. -h
  288. -V, --version Prints version information";
  289. static LAST_ARG: &str = "last 0.1
  290. USAGE:
  291. last <TARGET> [CORPUS] [-- <ARGS>...]
  292. ARGS:
  293. <TARGET> some
  294. <CORPUS> some
  295. <ARGS>... some
  296. FLAGS:
  297. -h, --help Prints help information
  298. -V, --version Prints version information";
  299. static LAST_ARG_SC: &str = "last 0.1
  300. USAGE:
  301. last <TARGET> [CORPUS] [-- <ARGS>...]
  302. last <SUBCOMMAND>
  303. ARGS:
  304. <TARGET> some
  305. <CORPUS> some
  306. <ARGS>... some
  307. FLAGS:
  308. -h, --help Prints help information
  309. -V, --version Prints version information
  310. SUBCOMMANDS:
  311. help Prints this message or the help of the given subcommand(s)
  312. test some";
  313. static LAST_ARG_REQ: &str = "last 0.1
  314. USAGE:
  315. last <TARGET> [CORPUS] -- <ARGS>...
  316. ARGS:
  317. <TARGET> some
  318. <CORPUS> some
  319. <ARGS>... some
  320. FLAGS:
  321. -h, --help Prints help information
  322. -V, --version Prints version information";
  323. static LAST_ARG_REQ_SC: &str = "last 0.1
  324. USAGE:
  325. last <TARGET> [CORPUS] -- <ARGS>...
  326. last <SUBCOMMAND>
  327. ARGS:
  328. <TARGET> some
  329. <CORPUS> some
  330. <ARGS>... some
  331. FLAGS:
  332. -h, --help Prints help information
  333. -V, --version Prints version information
  334. SUBCOMMANDS:
  335. help Prints this message or the help of the given subcommand(s)
  336. test some";
  337. static HIDE_DEFAULT_VAL: &str = "default 0.1
  338. USAGE:
  339. default [OPTIONS]
  340. FLAGS:
  341. -h, --help Prints help information
  342. -V, --version Prints version information
  343. OPTIONS:
  344. --arg <argument> Pass an argument to the program. [default: default-argument]";
  345. static ESCAPED_DEFAULT_VAL: &str = "default 0.1
  346. USAGE:
  347. default [OPTIONS]
  348. FLAGS:
  349. -h, --help Prints help information
  350. -V, --version Prints version information
  351. OPTIONS:
  352. --arg <argument> Pass an argument to the program. [default: \"\\n\"] [possible values: normal, \" \", \"\\n\", \"\\t\",
  353. other]";
  354. static LAST_ARG_USAGE: &str = "flamegraph 0.1
  355. USAGE:
  356. flamegraph [FLAGS] [OPTIONS] [BINFILE] [-- <ARGS>...]
  357. ARGS:
  358. <BINFILE> The path of the binary to be profiled. for a binary.
  359. <ARGS>... Any arguments you wish to pass to the being profiled.
  360. FLAGS:
  361. -h, --help Prints help information
  362. -v, --verbose Prints out more stuff.
  363. -V, --version Prints version information
  364. OPTIONS:
  365. -f, --frequency <HERTZ> The sampling frequency.
  366. -t, --timeout <SECONDS> Timeout in seconds.";
  367. static LAST_ARG_REQ_MULT: &str = "example 1.0
  368. USAGE:
  369. example <FIRST>... [--] <SECOND>...
  370. ARGS:
  371. <FIRST>... First
  372. <SECOND>... Second
  373. FLAGS:
  374. -h, --help Prints help information
  375. -V, --version Prints version information";
  376. static DEFAULT_HELP: &str = "ctest 1.0
  377. USAGE:
  378. ctest
  379. FLAGS:
  380. -h, --help Prints help information
  381. -V, --version Prints version information";
  382. static LONG_ABOUT: &str = "myapp 1.0
  383. foo
  384. something really really long, with
  385. multiple lines of text
  386. that should be displayed
  387. USAGE:
  388. myapp [arg1]
  389. ARGS:
  390. <arg1>
  391. some option
  392. FLAGS:
  393. -h, --help
  394. Prints help information
  395. -V, --version
  396. Prints version information";
  397. static HIDE_ENV_VALS: &str = "ctest 0.1
  398. USAGE:
  399. ctest [OPTIONS]
  400. FLAGS:
  401. -h, --help Prints help information
  402. -V, --version Prints version information
  403. OPTIONS:
  404. -c, --cafe <FILE> A coffeehouse, coffee shop, or café. [env: ENVVAR]
  405. -p, --pos <VAL> Some vals [possible values: fast, slow]";
  406. static SHOW_ENV_VALS: &str = "ctest 0.1
  407. USAGE:
  408. ctest [OPTIONS]
  409. FLAGS:
  410. -h, --help Prints help information
  411. -V, --version Prints version information
  412. OPTIONS:
  413. -c, --cafe <FILE> A coffeehouse, coffee shop, or café. [env: ENVVAR=MYVAL]
  414. -p, --pos <VAL> Some vals [possible values: fast, slow]";
  415. static CUSTOM_HELP_SECTION: &str = "blorp 1.4
  416. Will M.
  417. does stuff
  418. USAGE:
  419. test --fake <some>:<val>
  420. FLAGS:
  421. -h, --help Prints help information
  422. -V, --version Prints version information
  423. OPTIONS:
  424. -f, --fake <some>:<val> some help
  425. NETWORKING:
  426. -n, --no-proxy Do not use system proxy settings";
  427. static ISSUE_1487: &str = "test
  428. USAGE:
  429. ctest <arg1|arg2>
  430. ARGS:
  431. <arg1>
  432. <arg2>
  433. FLAGS:
  434. -h, --help Prints help information
  435. -V, --version Prints version information";
  436. static ISSUE_1364: &str = "demo
  437. USAGE:
  438. demo [FLAGS] [OPTIONS] [FILES]...
  439. ARGS:
  440. <FILES>...
  441. FLAGS:
  442. -f
  443. -h, --help Prints help information
  444. -V, --version Prints version information";
  445. fn setup() -> App<'static> {
  446. App::new("test")
  447. .author("Kevin K.")
  448. .about("tests stuff")
  449. .version("1.3")
  450. }
  451. fn empty_args() -> impl IntoIterator<Item = String> {
  452. std::iter::empty()
  453. }
  454. #[test]
  455. fn help_short() {
  456. let m = setup().try_get_matches_from(vec!["myprog", "-h"]);
  457. assert!(m.is_err());
  458. assert_eq!(m.unwrap_err().kind, ErrorKind::DisplayHelp);
  459. }
  460. #[test]
  461. fn help_long() {
  462. let m = setup().try_get_matches_from(vec!["myprog", "--help"]);
  463. assert!(m.is_err());
  464. assert_eq!(m.unwrap_err().kind, ErrorKind::DisplayHelp);
  465. }
  466. #[test]
  467. fn help_no_subcommand() {
  468. let m = setup().try_get_matches_from(vec!["myprog", "help"]);
  469. assert!(m.is_err());
  470. assert_eq!(m.unwrap_err().kind, ErrorKind::UnknownArgument);
  471. }
  472. #[test]
  473. fn help_subcommand() {
  474. let m = setup()
  475. .subcommand(
  476. App::new("test")
  477. .about("tests things")
  478. .arg("-v --verbose 'with verbosity'"),
  479. )
  480. .try_get_matches_from(vec!["myprog", "help"]);
  481. assert!(m.is_err());
  482. assert_eq!(m.unwrap_err().kind, ErrorKind::DisplayHelp);
  483. }
  484. #[test]
  485. fn req_last_arg_usage() {
  486. let app = clap_app!(example =>
  487. (version: "1.0")
  488. (@arg FIRST: ... * "First")
  489. (@arg SECOND: ... * +last "Second")
  490. );
  491. assert!(utils::compare_output(
  492. app,
  493. "example --help",
  494. LAST_ARG_REQ_MULT,
  495. false
  496. ));
  497. }
  498. #[test]
  499. fn args_with_last_usage() {
  500. let app = App::new("flamegraph")
  501. .version("0.1")
  502. .setting(AppSettings::TrailingVarArg)
  503. .arg(
  504. Arg::new("verbose")
  505. .about("Prints out more stuff.")
  506. .short('v')
  507. .long("verbose")
  508. .setting(ArgSettings::MultipleOccurrences),
  509. )
  510. .arg(
  511. Arg::new("timeout")
  512. .about("Timeout in seconds.")
  513. .short('t')
  514. .long("timeout")
  515. .value_name("SECONDS"),
  516. )
  517. .arg(
  518. Arg::new("frequency")
  519. .about("The sampling frequency.")
  520. .short('f')
  521. .long("frequency")
  522. .value_name("HERTZ"),
  523. )
  524. .arg(
  525. Arg::new("binary path")
  526. .about("The path of the binary to be profiled. for a binary.")
  527. .value_name("BINFILE"),
  528. )
  529. .arg(
  530. Arg::new("pass through args")
  531. .about("Any arguments you wish to pass to the being profiled.")
  532. .settings(&[
  533. ArgSettings::MultipleValues,
  534. ArgSettings::MultipleOccurrences,
  535. ArgSettings::Last,
  536. ])
  537. .value_name("ARGS"),
  538. );
  539. assert!(utils::compare_output(
  540. app,
  541. "flamegraph --help",
  542. LAST_ARG_USAGE,
  543. false
  544. ));
  545. }
  546. #[test]
  547. fn subcommand_short_help() {
  548. let m = utils::complex_app().try_get_matches_from(vec!["clap-test", "subcmd", "-h"]);
  549. assert!(m.is_err());
  550. assert_eq!(m.unwrap_err().kind, ErrorKind::DisplayHelp);
  551. }
  552. #[test]
  553. fn subcommand_long_help() {
  554. let m = utils::complex_app().try_get_matches_from(vec!["clap-test", "subcmd", "--help"]);
  555. assert!(m.is_err());
  556. assert_eq!(m.unwrap_err().kind, ErrorKind::DisplayHelp);
  557. }
  558. #[test]
  559. fn subcommand_help_rev() {
  560. let m = utils::complex_app().try_get_matches_from(vec!["clap-test", "help", "subcmd"]);
  561. assert!(m.is_err());
  562. assert_eq!(m.unwrap_err().kind, ErrorKind::DisplayHelp);
  563. }
  564. #[test]
  565. fn complex_help_output() {
  566. assert!(utils::compare_output(
  567. utils::complex_app(),
  568. "clap-test --help",
  569. HELP,
  570. false
  571. ));
  572. }
  573. #[test]
  574. fn after_and_before_help_output() {
  575. let app = App::new("clap-test")
  576. .version("v1.4.8")
  577. .about("tests clap library")
  578. .before_help("some text that comes before the help")
  579. .after_help("some text that comes after the help");
  580. assert!(utils::compare_output(
  581. app.clone(),
  582. "clap-test -h",
  583. AFTER_HELP,
  584. false
  585. ));
  586. assert!(utils::compare_output(
  587. app,
  588. "clap-test --help",
  589. AFTER_HELP,
  590. false
  591. ));
  592. }
  593. #[test]
  594. fn after_and_before_long_help_output() {
  595. let app = App::new("clap-test")
  596. .version("v1.4.8")
  597. .about("tests clap library")
  598. .before_help("some text that comes before the help")
  599. .after_help("some text that comes after the help")
  600. .before_long_help("some longer text that comes before the help")
  601. .after_long_help("some longer text that comes after the help");
  602. assert!(utils::compare_output(
  603. app.clone(),
  604. "clap-test --help",
  605. AFTER_LONG_HELP,
  606. false
  607. ));
  608. assert!(utils::compare_output(
  609. app,
  610. "clap-test -h",
  611. AFTER_HELP,
  612. false
  613. ));
  614. }
  615. #[test]
  616. fn multi_level_sc_help() {
  617. let app = App::new("ctest").subcommand(
  618. App::new("subcmd").subcommand(
  619. App::new("multi")
  620. .about("tests subcommands")
  621. .author("Kevin K. <kbknapp@gmail.com>")
  622. .version("0.1")
  623. .arg("-f, --flag 'tests flags'")
  624. .arg("-o, --option [scoption]... 'tests options'"),
  625. ),
  626. );
  627. assert!(utils::compare_output(
  628. app,
  629. "ctest help subcmd multi",
  630. MULTI_SC_HELP,
  631. false
  632. ));
  633. }
  634. #[test]
  635. fn no_wrap_help() {
  636. let app = App::new("ctest").term_width(0).override_help(MULTI_SC_HELP);
  637. assert!(utils::compare_output(
  638. app,
  639. "ctest --help",
  640. MULTI_SC_HELP,
  641. false
  642. ));
  643. }
  644. #[test]
  645. fn no_wrap_default_help() {
  646. let app = App::new("ctest").version("1.0").term_width(0);
  647. assert!(utils::compare_output(
  648. app,
  649. "ctest --help",
  650. DEFAULT_HELP,
  651. false
  652. ));
  653. }
  654. #[test]
  655. fn complex_subcommand_help_output() {
  656. let a = utils::complex_app();
  657. assert!(utils::compare_output(
  658. a,
  659. "clap-test subcmd --help",
  660. SC_HELP,
  661. false
  662. ));
  663. }
  664. #[test]
  665. fn issue_626_unicode_cutoff() {
  666. let app = App::new("ctest").version("0.1").term_width(70).arg(
  667. Arg::new("cafe")
  668. .short('c')
  669. .long("cafe")
  670. .value_name("FILE")
  671. .about(
  672. "A coffeehouse, coffee shop, or café is an establishment \
  673. which primarily serves hot coffee, related coffee beverages \
  674. (e.g., café latte, cappuccino, espresso), tea, and other hot \
  675. beverages. Some coffeehouses also serve cold beverages such as \
  676. iced coffee and iced tea. Many cafés also serve some type of \
  677. food, such as light snacks, muffins, or pastries.",
  678. )
  679. .takes_value(true),
  680. );
  681. assert!(utils::compare_output(
  682. app,
  683. "ctest --help",
  684. ISSUE_626_CUTOFF,
  685. false
  686. ));
  687. }
  688. #[test]
  689. fn hide_possible_vals() {
  690. let app = App::new("ctest")
  691. .version("0.1")
  692. .arg(
  693. Arg::new("pos")
  694. .short('p')
  695. .long("pos")
  696. .value_name("VAL")
  697. .possible_values(&["fast", "slow"])
  698. .about("Some vals")
  699. .takes_value(true),
  700. )
  701. .arg(
  702. Arg::new("cafe")
  703. .short('c')
  704. .long("cafe")
  705. .value_name("FILE")
  706. .hide_possible_values(true)
  707. .possible_values(&["fast", "slow"])
  708. .about("A coffeehouse, coffee shop, or café.")
  709. .takes_value(true),
  710. );
  711. assert!(utils::compare_output(
  712. app,
  713. "ctest --help",
  714. HIDE_POS_VALS,
  715. false
  716. ));
  717. }
  718. #[test]
  719. fn issue_626_panic() {
  720. let app = App::new("ctest")
  721. .version("0.1")
  722. .term_width(52)
  723. .arg(Arg::new("cafe")
  724. .short('c')
  725. .long("cafe")
  726. .value_name("FILE")
  727. .about("La culture du café est très développée dans de nombreux pays à climat chaud d'Amérique, \
  728. d'Afrique et d'Asie, dans des plantations qui sont cultivées pour les marchés d'exportation. \
  729. Le café est souvent une contribution majeure aux exportations des régions productrices.")
  730. .takes_value(true));
  731. assert!(utils::compare_output(
  732. app,
  733. "ctest --help",
  734. ISSUE_626_PANIC,
  735. false
  736. ));
  737. }
  738. #[test]
  739. fn issue_626_variable_panic() {
  740. for i in 10..320 {
  741. let _ = App::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. .about("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. .takes_value(true))
  752. .try_get_matches_from(vec!["ctest", "--help"]);
  753. }
  754. }
  755. #[test]
  756. fn final_word_wrapping() {
  757. let app = App::new("ctest").version("0.1").term_width(24);
  758. assert!(utils::compare_output(
  759. app,
  760. "ctest --help",
  761. FINAL_WORD_WRAPPING,
  762. false
  763. ));
  764. }
  765. #[test]
  766. fn wrapping_newline_chars() {
  767. let app = App::new("ctest")
  768. .version("0.1")
  769. .term_width(60)
  770. .arg(Arg::new("mode").about(
  771. "x, max, maximum 20 characters, contains symbols.\n\
  772. l, long Copy-friendly, 14 characters, contains symbols.\n\
  773. m, med, medium Copy-friendly, 8 characters, contains symbols.\n",
  774. ));
  775. assert!(utils::compare_output(
  776. app,
  777. "ctest --help",
  778. WRAPPING_NEWLINE_CHARS,
  779. false
  780. ));
  781. }
  782. #[test]
  783. fn old_newline_chars() {
  784. let app = App::new("ctest").version("0.1").arg(
  785. Arg::new("mode")
  786. .short('m')
  787. .about("Some help with some wrapping\n(Defaults to something)"),
  788. );
  789. assert!(utils::compare_output(
  790. app,
  791. "ctest --help",
  792. OLD_NEWLINE_CHARS,
  793. false
  794. ));
  795. }
  796. #[test]
  797. fn issue_688_hidden_pos_vals() {
  798. let filter_values = ["Nearest", "Linear", "Cubic", "Gaussian", "Lanczos3"];
  799. let app1 = App::new("ctest")
  800. .version("0.1")
  801. .term_width(120)
  802. .setting(AppSettings::HidePossibleValuesInHelp)
  803. .arg(Arg::new("filter")
  804. .about("Sets the filter, or sampling method, to use for interpolation when resizing the particle \
  805. images. The default is Linear (Bilinear). [possible values: Nearest, Linear, Cubic, Gaussian, Lanczos3]")
  806. .long("filter")
  807. .possible_values(&filter_values)
  808. .takes_value(true));
  809. assert!(utils::compare_output(
  810. app1,
  811. "ctest --help",
  812. ISSUE_688,
  813. false
  814. ));
  815. let app2 = App::new("ctest")
  816. .version("0.1")
  817. .term_width(120)
  818. .arg(Arg::new("filter")
  819. .about("Sets the filter, or sampling method, to use for interpolation when resizing the particle \
  820. images. The default is Linear (Bilinear).")
  821. .long("filter")
  822. .possible_values(&filter_values)
  823. .takes_value(true));
  824. assert!(utils::compare_output(
  825. app2,
  826. "ctest --help",
  827. ISSUE_688,
  828. false
  829. ));
  830. let app3 = App::new("ctest")
  831. .version("0.1")
  832. .term_width(120)
  833. .arg(Arg::new("filter")
  834. .about("Sets the filter, or sampling method, to use for interpolation when resizing the particle \
  835. images. The default is Linear (Bilinear). [possible values: Nearest, Linear, Cubic, Gaussian, Lanczos3]")
  836. .long("filter")
  837. .takes_value(true));
  838. assert!(utils::compare_output(
  839. app3,
  840. "ctest --help",
  841. ISSUE_688,
  842. false
  843. ));
  844. }
  845. #[test]
  846. fn issue_702_multiple_values() {
  847. let app = App::new("myapp")
  848. .version("1.0")
  849. .author("foo")
  850. .about("bar")
  851. .arg(Arg::new("arg1").about("some option"))
  852. .arg(Arg::new("arg2").multiple(true).about("some option"))
  853. .arg(
  854. Arg::new("some")
  855. .about("some option")
  856. .short('s')
  857. .long("some")
  858. .takes_value(true),
  859. )
  860. .arg(
  861. Arg::new("other")
  862. .about("some other option")
  863. .short('o')
  864. .long("other")
  865. .takes_value(true),
  866. )
  867. .arg(
  868. Arg::new("label")
  869. .about("a label")
  870. .short('l')
  871. .long("label")
  872. .multiple(true)
  873. .takes_value(true),
  874. );
  875. assert!(utils::compare_output(app, "myapp --help", ISSUE_702, false));
  876. }
  877. #[test]
  878. fn long_about() {
  879. let app = App::new("myapp")
  880. .version("1.0")
  881. .author("foo")
  882. .about("bar")
  883. .long_about(
  884. "something really really long, with\nmultiple lines of text\nthat should be displayed",
  885. )
  886. .arg(Arg::new("arg1").about("some option"));
  887. assert!(utils::compare_output(
  888. app,
  889. "myapp --help",
  890. LONG_ABOUT,
  891. false
  892. ));
  893. }
  894. #[test]
  895. fn issue_760() {
  896. let app = App::new("ctest")
  897. .version("0.1")
  898. .arg(
  899. Arg::new("option")
  900. .about("tests options")
  901. .short('o')
  902. .long("option")
  903. .takes_value(true)
  904. .multiple(true)
  905. .number_of_values(1),
  906. )
  907. .arg(
  908. Arg::new("opt")
  909. .about("tests options")
  910. .short('O')
  911. .long("opt")
  912. .takes_value(true),
  913. );
  914. assert!(utils::compare_output(app, "ctest --help", ISSUE_760, false));
  915. }
  916. #[test]
  917. fn ripgrep_usage() {
  918. let app = App::new("ripgrep").version("0.5").override_usage(
  919. "rg [OPTIONS] <pattern> [<path> ...]
  920. rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
  921. rg [OPTIONS] --files [<path> ...]
  922. rg [OPTIONS] --type-list",
  923. );
  924. assert!(utils::compare_output(
  925. app,
  926. "rg --help",
  927. RIPGREP_USAGE,
  928. false
  929. ));
  930. }
  931. #[test]
  932. fn ripgrep_usage_using_templates() {
  933. let app = App::new("ripgrep")
  934. .version("0.5")
  935. .override_usage(
  936. "
  937. rg [OPTIONS] <pattern> [<path> ...]
  938. rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
  939. rg [OPTIONS] --files [<path> ...]
  940. rg [OPTIONS] --type-list",
  941. )
  942. .help_template(
  943. "\
  944. {bin} {version}
  945. USAGE:{usage}
  946. FLAGS:
  947. {flags}",
  948. );
  949. assert!(utils::compare_output(
  950. app,
  951. "rg --help",
  952. RIPGREP_USAGE,
  953. false
  954. ));
  955. }
  956. #[test]
  957. fn sc_negates_reqs() {
  958. let app = App::new("prog")
  959. .version("1.0")
  960. .setting(AppSettings::SubcommandsNegateReqs)
  961. .arg("-o, --opt <FILE> 'tests options'")
  962. .arg(Arg::new("PATH").about("help"))
  963. .subcommand(App::new("test"));
  964. assert!(utils::compare_output(
  965. app,
  966. "prog --help",
  967. SC_NEGATES_REQS,
  968. false
  969. ));
  970. }
  971. #[test]
  972. fn hidden_args() {
  973. let app = App::new("prog")
  974. .version("1.0")
  975. .arg("-f, --flag 'testing flags'")
  976. .arg("-o, --opt [FILE] 'tests options'")
  977. .arg(Arg::new("pos").hidden(true));
  978. assert!(utils::compare_output(
  979. app,
  980. "prog --help",
  981. HIDDEN_ARGS,
  982. false
  983. ));
  984. }
  985. #[test]
  986. fn args_negate_sc() {
  987. let app = App::new("prog")
  988. .version("1.0")
  989. .setting(AppSettings::ArgsNegateSubcommands)
  990. .arg("-f, --flag 'testing flags'")
  991. .arg("-o, --opt [FILE] 'tests options'")
  992. .arg(Arg::new("PATH").about("help"))
  993. .subcommand(App::new("test"));
  994. assert!(utils::compare_output(
  995. app,
  996. "prog --help",
  997. ARGS_NEGATE_SC,
  998. false
  999. ));
  1000. }
  1001. #[test]
  1002. fn issue_1046_hidden_scs() {
  1003. let app = App::new("prog")
  1004. .version("1.0")
  1005. .arg("-f, --flag 'testing flags'")
  1006. .arg("-o, --opt [FILE] 'tests options'")
  1007. .arg(Arg::new("PATH").about("some"))
  1008. .subcommand(App::new("test").setting(AppSettings::Hidden));
  1009. assert!(utils::compare_output(
  1010. app,
  1011. "prog --help",
  1012. ISSUE_1046_HIDDEN_SCS,
  1013. false
  1014. ));
  1015. }
  1016. #[test]
  1017. fn issue_777_wrap_all_things() {
  1018. let app = App::new("A app with a crazy very long long long name hahaha")
  1019. .version("1.0")
  1020. .author("Some Very Long Name and crazy long email <email@server.com>")
  1021. .about("Show how the about text is not wrapped")
  1022. .term_width(35);
  1023. assert!(utils::compare_output(app, "ctest --help", ISSUE_777, false));
  1024. }
  1025. #[test]
  1026. fn customize_version_and_help() {
  1027. let app = App::new("customize")
  1028. .version("0.1")
  1029. .author("Nobody <odysseus@example.com>")
  1030. .about("You can customize the version and help text")
  1031. .mut_arg("help", |h| {
  1032. h.short('H').long("help").about("Print help information")
  1033. })
  1034. .mut_arg("version", |v| {
  1035. v.short('v')
  1036. .long("version")
  1037. .about("Print version information")
  1038. });
  1039. assert!(utils::compare_output(
  1040. app,
  1041. "customize --help",
  1042. CUSTOM_VERSION_AND_HELP,
  1043. false
  1044. ));
  1045. }
  1046. #[test]
  1047. fn arg_short_conflict_with_help() {
  1048. let app = App::new("conflict").arg(Arg::new("home").short('h'));
  1049. assert!(utils::compare_output(
  1050. app,
  1051. "conflict --help",
  1052. HELP_CONFLICT,
  1053. false
  1054. ));
  1055. }
  1056. #[cfg(debug_assertions)]
  1057. #[test]
  1058. #[should_panic = "Short option names must be unique for each argument, but '-h' is in use by both 'home' and 'help'"]
  1059. fn arg_short_conflict_with_help_mut_arg() {
  1060. let _ = App::new("conflict")
  1061. .arg(Arg::new("home").short('h'))
  1062. .mut_arg("help", |h| h.short('h'))
  1063. .try_get_matches_from(vec![""]);
  1064. }
  1065. #[test]
  1066. fn last_arg_mult_usage() {
  1067. let app = App::new("last")
  1068. .version("0.1")
  1069. .arg(Arg::new("TARGET").required(true).about("some"))
  1070. .arg(Arg::new("CORPUS").about("some"))
  1071. .arg(Arg::new("ARGS").multiple(true).last(true).about("some"));
  1072. assert!(utils::compare_output(app, "last --help", LAST_ARG, false));
  1073. }
  1074. #[test]
  1075. fn last_arg_mult_usage_req() {
  1076. let app = App::new("last")
  1077. .version("0.1")
  1078. .arg(Arg::new("TARGET").required(true).about("some"))
  1079. .arg(Arg::new("CORPUS").about("some"))
  1080. .arg(
  1081. Arg::new("ARGS")
  1082. .multiple(true)
  1083. .last(true)
  1084. .required(true)
  1085. .about("some"),
  1086. );
  1087. assert!(utils::compare_output(
  1088. app,
  1089. "last --help",
  1090. LAST_ARG_REQ,
  1091. false
  1092. ));
  1093. }
  1094. #[test]
  1095. fn last_arg_mult_usage_req_with_sc() {
  1096. let app = App::new("last")
  1097. .version("0.1")
  1098. .setting(AppSettings::SubcommandsNegateReqs)
  1099. .arg(Arg::new("TARGET").required(true).about("some"))
  1100. .arg(Arg::new("CORPUS").about("some"))
  1101. .arg(
  1102. Arg::new("ARGS")
  1103. .multiple(true)
  1104. .last(true)
  1105. .required(true)
  1106. .about("some"),
  1107. )
  1108. .subcommand(App::new("test").about("some"));
  1109. assert!(utils::compare_output(
  1110. app,
  1111. "last --help",
  1112. LAST_ARG_REQ_SC,
  1113. false
  1114. ));
  1115. }
  1116. #[test]
  1117. fn last_arg_mult_usage_with_sc() {
  1118. let app = App::new("last")
  1119. .version("0.1")
  1120. .setting(AppSettings::ArgsNegateSubcommands)
  1121. .arg(Arg::new("TARGET").required(true).about("some"))
  1122. .arg(Arg::new("CORPUS").about("some"))
  1123. .arg(Arg::new("ARGS").multiple(true).last(true).about("some"))
  1124. .subcommand(App::new("test").about("some"));
  1125. assert!(utils::compare_output(
  1126. app,
  1127. "last --help",
  1128. LAST_ARG_SC,
  1129. false
  1130. ));
  1131. }
  1132. #[test]
  1133. fn hidden_default_val() {
  1134. let app1 = App::new("default").version("0.1").term_width(120).arg(
  1135. Arg::new("argument")
  1136. .about("Pass an argument to the program. [default: default-argument]")
  1137. .long("arg")
  1138. .default_value("default-argument")
  1139. .hide_default_value(true),
  1140. );
  1141. assert!(utils::compare_output(
  1142. app1,
  1143. "default --help",
  1144. HIDE_DEFAULT_VAL,
  1145. false
  1146. ));
  1147. let app2 = App::new("default").version("0.1").term_width(120).arg(
  1148. Arg::new("argument")
  1149. .about("Pass an argument to the program.")
  1150. .long("arg")
  1151. .default_value("default-argument"),
  1152. );
  1153. assert!(utils::compare_output(
  1154. app2,
  1155. "default --help",
  1156. HIDE_DEFAULT_VAL,
  1157. false
  1158. ));
  1159. }
  1160. #[test]
  1161. fn escaped_whitespace_values() {
  1162. let app1 = App::new("default").version("0.1").term_width(120).arg(
  1163. Arg::new("argument")
  1164. .about("Pass an argument to the program.")
  1165. .long("arg")
  1166. .default_value("\n")
  1167. .possible_values(&["normal", " ", "\n", "\t", "other"]),
  1168. );
  1169. assert!(utils::compare_output(
  1170. app1,
  1171. "default --help",
  1172. ESCAPED_DEFAULT_VAL,
  1173. false
  1174. ));
  1175. }
  1176. fn issue_1112_setup() -> App<'static> {
  1177. App::new("test")
  1178. .author("Kevin K.")
  1179. .about("tests stuff")
  1180. .version("1.3")
  1181. .global_setting(AppSettings::NoAutoHelp)
  1182. .arg(Arg::from("-h, --help 'some help'"))
  1183. .subcommand(App::new("foo").arg(Arg::from("-h, --help 'some help'")))
  1184. }
  1185. #[test]
  1186. fn issue_1112_override_help_long() {
  1187. let m = issue_1112_setup().try_get_matches_from(vec!["test", "--help"]);
  1188. assert!(m.is_ok());
  1189. assert!(m.unwrap().is_present("help"));
  1190. }
  1191. #[test]
  1192. fn issue_1112_override_help_short() {
  1193. let m = issue_1112_setup().try_get_matches_from(vec!["test", "-h"]);
  1194. assert!(m.is_ok());
  1195. assert!(m.unwrap().is_present("help"));
  1196. }
  1197. #[test]
  1198. fn issue_1112_override_help_subcmd_long() {
  1199. let m = issue_1112_setup().try_get_matches_from(vec!["test", "foo", "--help"]);
  1200. assert!(m.is_ok());
  1201. assert!(m
  1202. .unwrap()
  1203. .subcommand_matches("foo")
  1204. .unwrap()
  1205. .is_present("help"));
  1206. }
  1207. #[test]
  1208. fn issue_1112_override_help_subcmd_short() {
  1209. let m = issue_1112_setup().try_get_matches_from(vec!["test", "foo", "-h"]);
  1210. assert!(m.is_ok());
  1211. assert!(m
  1212. .unwrap()
  1213. .subcommand_matches("foo")
  1214. .unwrap()
  1215. .is_present("help"));
  1216. }
  1217. #[test]
  1218. fn issue_1052_require_delim_help() {
  1219. let app = App::new("test")
  1220. .author("Kevin K.")
  1221. .about("tests stuff")
  1222. .version("1.3")
  1223. .arg(
  1224. Arg::from("-f, --fake <some> <val> 'some help'")
  1225. .require_delimiter(true)
  1226. .value_delimiter(":"),
  1227. );
  1228. assert!(utils::compare_output(
  1229. app,
  1230. "test --help",
  1231. REQUIRE_DELIM_HELP,
  1232. false
  1233. ));
  1234. }
  1235. #[test]
  1236. fn hide_env_vals() {
  1237. use std::env;
  1238. env::set_var("ENVVAR", "MYVAL");
  1239. let app = App::new("ctest")
  1240. .version("0.1")
  1241. .arg(
  1242. Arg::new("pos")
  1243. .short('p')
  1244. .long("pos")
  1245. .value_name("VAL")
  1246. .possible_values(&["fast", "slow"])
  1247. .about("Some vals")
  1248. .takes_value(true),
  1249. )
  1250. .arg(
  1251. Arg::new("cafe")
  1252. .short('c')
  1253. .long("cafe")
  1254. .value_name("FILE")
  1255. .hide_env_values(true)
  1256. .env("ENVVAR")
  1257. .about("A coffeehouse, coffee shop, or café.")
  1258. .takes_value(true),
  1259. );
  1260. assert!(utils::compare_output(
  1261. app,
  1262. "ctest --help",
  1263. HIDE_ENV_VALS,
  1264. false
  1265. ));
  1266. }
  1267. #[test]
  1268. fn show_env_vals() {
  1269. use std::env;
  1270. env::set_var("ENVVAR", "MYVAL");
  1271. let app = App::new("ctest")
  1272. .version("0.1")
  1273. .arg(
  1274. Arg::new("pos")
  1275. .short('p')
  1276. .long("pos")
  1277. .value_name("VAL")
  1278. .possible_values(&["fast", "slow"])
  1279. .about("Some vals")
  1280. .takes_value(true),
  1281. )
  1282. .arg(
  1283. Arg::new("cafe")
  1284. .short('c')
  1285. .long("cafe")
  1286. .value_name("FILE")
  1287. .hide_possible_values(true)
  1288. .env("ENVVAR")
  1289. .about("A coffeehouse, coffee shop, or café.")
  1290. .takes_value(true),
  1291. );
  1292. assert!(utils::compare_output(
  1293. app,
  1294. "ctest --help",
  1295. SHOW_ENV_VALS,
  1296. false
  1297. ));
  1298. }
  1299. #[test]
  1300. fn custom_headers_headers() {
  1301. let app = App::new("blorp")
  1302. .author("Will M.")
  1303. .about("does stuff")
  1304. .version("1.4")
  1305. .arg(
  1306. Arg::from("-f, --fake <some> <val> 'some help'")
  1307. .require_delimiter(true)
  1308. .value_delimiter(":"),
  1309. )
  1310. .help_heading("NETWORKING")
  1311. .arg(
  1312. Arg::new("no-proxy")
  1313. .short('n')
  1314. .long("no-proxy")
  1315. .about("Do not use system proxy settings"),
  1316. );
  1317. assert!(utils::compare_output(
  1318. app,
  1319. "test --help",
  1320. CUSTOM_HELP_SECTION,
  1321. false
  1322. ));
  1323. }
  1324. static MULTIPLE_CUSTOM_HELP_SECTIONS: &str = "blorp 1.4
  1325. Will M.
  1326. does stuff
  1327. USAGE:
  1328. test [OPTIONS] --fake <some>:<val> --birthday-song <song> --birthday-song-volume <volume>
  1329. FLAGS:
  1330. -h, --help Prints help information
  1331. -V, --version Prints version information
  1332. OPTIONS:
  1333. -f, --fake <some>:<val> some help
  1334. -s, --speed <SPEED> How fast? [possible values: fast, slow]
  1335. NETWORKING:
  1336. -n, --no-proxy Do not use system proxy settings
  1337. -a, --server-addr Set server address
  1338. SPECIAL:
  1339. -b, --birthday-song <song> Change which song is played for birthdays
  1340. -v, --birthday-song-volume <volume> Change the volume of the birthday song";
  1341. #[test]
  1342. fn multiple_custom_help_headers() {
  1343. let app = App::new("blorp")
  1344. .author("Will M.")
  1345. .about("does stuff")
  1346. .version("1.4")
  1347. .arg(
  1348. Arg::from("-f, --fake <some> <val> 'some help'")
  1349. .require_delimiter(true)
  1350. .value_delimiter(":"),
  1351. )
  1352. .help_heading("NETWORKING")
  1353. .arg(
  1354. Arg::new("no-proxy")
  1355. .short('n')
  1356. .long("no-proxy")
  1357. .about("Do not use system proxy settings"),
  1358. )
  1359. .help_heading("SPECIAL")
  1360. .arg(
  1361. Arg::from("-b, --birthday-song <song> 'Change which song is played for birthdays'")
  1362. .help_heading(Some("IGNORE THIS")),
  1363. )
  1364. .stop_custom_headings()
  1365. .arg(
  1366. Arg::from(
  1367. "-v --birthday-song-volume <volume> 'Change the volume of the birthday song'",
  1368. )
  1369. .help_heading(Some("SPECIAL")),
  1370. )
  1371. .arg(
  1372. Arg::new("server-addr")
  1373. .short('a')
  1374. .long("server-addr")
  1375. .about("Set server address")
  1376. .help_heading(Some("NETWORKING")),
  1377. )
  1378. .arg(
  1379. Arg::new("speed")
  1380. .long("speed")
  1381. .short('s')
  1382. .value_name("SPEED")
  1383. .possible_values(&["fast", "slow"])
  1384. .about("How fast?")
  1385. .takes_value(true),
  1386. );
  1387. assert!(utils::compare_output(
  1388. app,
  1389. "test --help",
  1390. MULTIPLE_CUSTOM_HELP_SECTIONS,
  1391. false
  1392. ));
  1393. }
  1394. static ISSUE_897: &str = "ctest-foo 0.1
  1395. Long about foo
  1396. USAGE:
  1397. ctest foo
  1398. FLAGS:
  1399. -h, --help
  1400. Prints help information
  1401. -V, --version
  1402. Prints version information";
  1403. #[test]
  1404. fn show_long_about_issue_897() {
  1405. let app = App::new("ctest").version("0.1").subcommand(
  1406. App::new("foo")
  1407. .version("0.1")
  1408. .about("About foo")
  1409. .long_about("Long about foo"),
  1410. );
  1411. assert!(utils::compare_output(
  1412. app,
  1413. "ctest foo --help",
  1414. ISSUE_897,
  1415. false
  1416. ));
  1417. }
  1418. static ISSUE_897_SHORT: &str = "ctest-foo 0.1
  1419. About foo
  1420. USAGE:
  1421. ctest foo
  1422. FLAGS:
  1423. -h, --help Prints help information
  1424. -V, --version Prints version information";
  1425. #[test]
  1426. fn show_short_about_issue_897() {
  1427. let app = App::new("ctest").version("0.1").subcommand(
  1428. App::new("foo")
  1429. .version("0.1")
  1430. .about("About foo")
  1431. .long_about("Long about foo"),
  1432. );
  1433. assert!(utils::compare_output(
  1434. app,
  1435. "ctest foo -h",
  1436. ISSUE_897_SHORT,
  1437. false
  1438. ));
  1439. }
  1440. #[test]
  1441. fn issue_1364_no_short_options() {
  1442. let app = App::new("demo")
  1443. .arg(Arg::new("foo").short('f'))
  1444. .arg(
  1445. Arg::new("baz")
  1446. .short('z')
  1447. .value_name("BAZ")
  1448. .hidden_short_help(true),
  1449. )
  1450. .arg(Arg::new("files").value_name("FILES").multiple(true));
  1451. assert!(utils::compare_output(app, "demo -h", ISSUE_1364, false));
  1452. }
  1453. #[rustfmt::skip]
  1454. #[test]
  1455. fn issue_1487() {
  1456. let app = App::new("test")
  1457. .arg(Arg::new("arg1")
  1458. .group("group1"))
  1459. .arg(Arg::new("arg2")
  1460. .group("group1"))
  1461. .group(ArgGroup::new("group1")
  1462. .args(&["arg1", "arg2"])
  1463. .required(true));
  1464. assert!(utils::compare_output(app, "ctest -h", ISSUE_1487, false));
  1465. }
  1466. #[cfg(debug_assertions)]
  1467. #[test]
  1468. #[should_panic = "AppSettings::HelpRequired is enabled for the App"]
  1469. fn help_required_but_not_given() {
  1470. App::new("myapp")
  1471. .setting(AppSettings::HelpRequired)
  1472. .arg(Arg::new("foo"))
  1473. .get_matches_from(empty_args());
  1474. }
  1475. #[cfg(debug_assertions)]
  1476. #[test]
  1477. #[should_panic = "AppSettings::HelpRequired is enabled for the App"]
  1478. fn help_required_but_not_given_settings_after_args() {
  1479. App::new("myapp")
  1480. .arg(Arg::new("foo"))
  1481. .setting(AppSettings::HelpRequired)
  1482. .get_matches_from(empty_args());
  1483. }
  1484. #[cfg(debug_assertions)]
  1485. #[test]
  1486. #[should_panic = "AppSettings::HelpRequired is enabled for the App"]
  1487. fn help_required_but_not_given_for_one_of_two_arguments() {
  1488. App::new("myapp")
  1489. .setting(AppSettings::HelpRequired)
  1490. .arg(Arg::new("foo"))
  1491. .arg(Arg::new("bar").about("It does bar stuff"))
  1492. .get_matches_from(empty_args());
  1493. }
  1494. #[test]
  1495. fn help_required_locally_but_not_given_for_subcommand() {
  1496. App::new("myapp")
  1497. .setting(AppSettings::HelpRequired)
  1498. .arg(Arg::new("foo").about("It does foo stuff"))
  1499. .subcommand(
  1500. App::new("bar")
  1501. .arg(Arg::new("create").about("creates bar"))
  1502. .arg(Arg::new("delete")),
  1503. )
  1504. .get_matches_from(empty_args());
  1505. }
  1506. #[cfg(debug_assertions)]
  1507. #[test]
  1508. #[should_panic = "AppSettings::HelpRequired is enabled for the App"]
  1509. fn help_required_globally_but_not_given_for_subcommand() {
  1510. App::new("myapp")
  1511. .global_setting(AppSettings::HelpRequired)
  1512. .arg(Arg::new("foo").about("It does foo stuff"))
  1513. .subcommand(
  1514. App::new("bar")
  1515. .arg(Arg::new("create").about("creates bar"))
  1516. .arg(Arg::new("delete")),
  1517. )
  1518. .get_matches_from(empty_args());
  1519. }
  1520. #[test]
  1521. fn help_required_and_given_for_subcommand() {
  1522. App::new("myapp")
  1523. .setting(AppSettings::HelpRequired)
  1524. .arg(Arg::new("foo").about("It does foo stuff"))
  1525. .subcommand(
  1526. App::new("bar")
  1527. .arg(Arg::new("create").about("creates bar"))
  1528. .arg(Arg::new("delete").about("deletes bar")),
  1529. )
  1530. .get_matches_from(empty_args());
  1531. }
  1532. #[test]
  1533. fn help_required_and_given() {
  1534. App::new("myapp")
  1535. .setting(AppSettings::HelpRequired)
  1536. .arg(Arg::new("foo").about("It does foo stuff"))
  1537. .get_matches_from(empty_args());
  1538. }
  1539. #[test]
  1540. fn help_required_and_no_args() {
  1541. App::new("myapp")
  1542. .setting(AppSettings::HelpRequired)
  1543. .get_matches_from(empty_args());
  1544. }
  1545. #[test]
  1546. fn issue_1642_long_help_spacing() {
  1547. let app = App::new("prog").arg(Arg::new("cfg").long("config").long_about(
  1548. "The config file used by the myprog must be in JSON format
  1549. with only valid keys and may not contain other nonsense
  1550. that cannot be read by this program. Obviously I'm going on
  1551. and on, so I'll stop now.",
  1552. ));
  1553. assert!(utils::compare_output(app, "prog --help", ISSUE_1642, false));
  1554. }
  1555. const AFTER_HELP_NO_ARGS: &str = "myapp 1.0
  1556. USAGE:
  1557. myapp
  1558. This is after help.
  1559. ";
  1560. #[test]
  1561. fn after_help_no_args() {
  1562. let mut app = App::new("myapp")
  1563. .version("1.0")
  1564. .setting(AppSettings::DisableHelpFlags)
  1565. .setting(AppSettings::DisableVersion)
  1566. .after_help("This is after help.");
  1567. let help = {
  1568. let mut output = Vec::new();
  1569. app.write_help(&mut output).unwrap();
  1570. String::from_utf8(output).unwrap()
  1571. };
  1572. assert_eq!(help, AFTER_HELP_NO_ARGS);
  1573. }
  1574. static HELP_ABOUT: &str = "myapp 1.0
  1575. USAGE:
  1576. myapp
  1577. FLAGS:
  1578. -h, --help Print custom help about text
  1579. -V, --version Prints version information";
  1580. static HELP_ABOUT_MULTI_SC: &str = "myapp-subcmd-multi 1.0
  1581. USAGE:
  1582. myapp subcmd multi
  1583. FLAGS:
  1584. -h, --help Print custom help about text
  1585. -V, --version Prints version information";
  1586. static HELP_ABOUT_MULTI_SC_OVERRIDE: &str = "myapp-subcmd-multi 1.0
  1587. USAGE:
  1588. myapp subcmd multi
  1589. FLAGS:
  1590. -h, --help Print custom help about text from multi
  1591. -V, --version Prints version information";
  1592. #[test]
  1593. fn help_about_short_flag() {
  1594. let app = App::new("myapp")
  1595. .version("1.0")
  1596. .help_about("Print custom help about text");
  1597. assert!(utils::compare_output(app, "myapp -h", HELP_ABOUT, false));
  1598. }
  1599. #[test]
  1600. fn help_about_long_flag() {
  1601. let app = App::new("myapp")
  1602. .version("1.0")
  1603. .help_about("Print custom help about text");
  1604. assert!(utils::compare_output(
  1605. app,
  1606. "myapp --help",
  1607. HELP_ABOUT,
  1608. false
  1609. ));
  1610. }
  1611. #[test]
  1612. fn help_about_multi_subcmd() {
  1613. let app = App::new("myapp")
  1614. .help_about("Print custom help about text")
  1615. .subcommand(App::new("subcmd").subcommand(App::new("multi").version("1.0")));
  1616. assert!(utils::compare_output(
  1617. app,
  1618. "myapp help subcmd multi",
  1619. HELP_ABOUT_MULTI_SC,
  1620. false
  1621. ));
  1622. }
  1623. #[test]
  1624. fn help_about_multi_subcmd_short_flag() {
  1625. let app = App::new("myapp")
  1626. .help_about("Print custom help about text")
  1627. .subcommand(App::new("subcmd").subcommand(App::new("multi").version("1.0")));
  1628. assert!(utils::compare_output(
  1629. app,
  1630. "myapp subcmd multi -h",
  1631. HELP_ABOUT_MULTI_SC,
  1632. false
  1633. ));
  1634. }
  1635. #[test]
  1636. fn help_about_multi_subcmd_long_flag() {
  1637. let app = App::new("myapp")
  1638. .help_about("Print custom help about text")
  1639. .subcommand(App::new("subcmd").subcommand(App::new("multi").version("1.0")));
  1640. assert!(utils::compare_output(
  1641. app,
  1642. "myapp subcmd multi --help",
  1643. HELP_ABOUT_MULTI_SC,
  1644. false
  1645. ));
  1646. }
  1647. #[test]
  1648. fn help_about_multi_subcmd_override() {
  1649. let app = App::new("myapp")
  1650. .help_about("Print custom help about text")
  1651. .subcommand(
  1652. App::new("subcmd").subcommand(
  1653. App::new("multi")
  1654. .version("1.0")
  1655. .help_about("Print custom help about text from multi"),
  1656. ),
  1657. );
  1658. assert!(utils::compare_output(
  1659. app,
  1660. "myapp help subcmd multi",
  1661. HELP_ABOUT_MULTI_SC_OVERRIDE,
  1662. false
  1663. ));
  1664. }
  1665. #[test]
  1666. fn help_about_multi_subcmd_override_short_flag() {
  1667. let app = App::new("myapp")
  1668. .help_about("Print custom help about text")
  1669. .subcommand(
  1670. App::new("subcmd").subcommand(
  1671. App::new("multi")

Large files files are truncated, but you can click here to view the full file