119625d8cSopenharmony_ciuse clap::{ArgAction, Args, CommandFactory, Parser, Subcommand};
219625d8cSopenharmony_ci
319625d8cSopenharmony_ci#[test]
419625d8cSopenharmony_cifn arg_help_heading_applied() {
519625d8cSopenharmony_ci    #[derive(Debug, Clone, Parser)]
619625d8cSopenharmony_ci    struct CliOptions {
719625d8cSopenharmony_ci        #[arg(long)]
819625d8cSopenharmony_ci        #[arg(help_heading = Some("HEADING A"))]
919625d8cSopenharmony_ci        should_be_in_section_a: u32,
1019625d8cSopenharmony_ci
1119625d8cSopenharmony_ci        #[arg(long)]
1219625d8cSopenharmony_ci        no_section: u32,
1319625d8cSopenharmony_ci    }
1419625d8cSopenharmony_ci
1519625d8cSopenharmony_ci    let cmd = CliOptions::command();
1619625d8cSopenharmony_ci
1719625d8cSopenharmony_ci    let should_be_in_section_a = cmd
1819625d8cSopenharmony_ci        .get_arguments()
1919625d8cSopenharmony_ci        .find(|a| a.get_id() == "should_be_in_section_a")
2019625d8cSopenharmony_ci        .unwrap();
2119625d8cSopenharmony_ci    assert_eq!(should_be_in_section_a.get_help_heading(), Some("HEADING A"));
2219625d8cSopenharmony_ci
2319625d8cSopenharmony_ci    let should_be_in_section_b = cmd
2419625d8cSopenharmony_ci        .get_arguments()
2519625d8cSopenharmony_ci        .find(|a| a.get_id() == "no_section")
2619625d8cSopenharmony_ci        .unwrap();
2719625d8cSopenharmony_ci    assert_eq!(should_be_in_section_b.get_help_heading(), None);
2819625d8cSopenharmony_ci}
2919625d8cSopenharmony_ci
3019625d8cSopenharmony_ci#[test]
3119625d8cSopenharmony_cifn app_help_heading_applied() {
3219625d8cSopenharmony_ci    #[derive(Debug, Clone, Parser)]
3319625d8cSopenharmony_ci    #[command(next_help_heading = "DEFAULT")]
3419625d8cSopenharmony_ci    struct CliOptions {
3519625d8cSopenharmony_ci        #[arg(long)]
3619625d8cSopenharmony_ci        #[arg(help_heading = Some("HEADING A"))]
3719625d8cSopenharmony_ci        should_be_in_section_a: u32,
3819625d8cSopenharmony_ci
3919625d8cSopenharmony_ci        #[arg(long)]
4019625d8cSopenharmony_ci        should_be_in_default_section: u32,
4119625d8cSopenharmony_ci    }
4219625d8cSopenharmony_ci
4319625d8cSopenharmony_ci    let cmd = CliOptions::command();
4419625d8cSopenharmony_ci
4519625d8cSopenharmony_ci    let should_be_in_section_a = cmd
4619625d8cSopenharmony_ci        .get_arguments()
4719625d8cSopenharmony_ci        .find(|a| a.get_id() == "should_be_in_section_a")
4819625d8cSopenharmony_ci        .unwrap();
4919625d8cSopenharmony_ci    assert_eq!(should_be_in_section_a.get_help_heading(), Some("HEADING A"));
5019625d8cSopenharmony_ci
5119625d8cSopenharmony_ci    let should_be_in_default_section = cmd
5219625d8cSopenharmony_ci        .get_arguments()
5319625d8cSopenharmony_ci        .find(|a| a.get_id() == "should_be_in_default_section")
5419625d8cSopenharmony_ci        .unwrap();
5519625d8cSopenharmony_ci    assert_eq!(
5619625d8cSopenharmony_ci        should_be_in_default_section.get_help_heading(),
5719625d8cSopenharmony_ci        Some("DEFAULT")
5819625d8cSopenharmony_ci    );
5919625d8cSopenharmony_ci}
6019625d8cSopenharmony_ci
6119625d8cSopenharmony_ci#[test]
6219625d8cSopenharmony_cifn app_help_heading_flattened() {
6319625d8cSopenharmony_ci    // Used to help track the cause in tests
6419625d8cSopenharmony_ci    #![allow(clippy::enum_variant_names)]
6519625d8cSopenharmony_ci
6619625d8cSopenharmony_ci    #[derive(Debug, Clone, Parser)]
6719625d8cSopenharmony_ci    struct CliOptions {
6819625d8cSopenharmony_ci        #[command(flatten)]
6919625d8cSopenharmony_ci        options_a: OptionsA,
7019625d8cSopenharmony_ci
7119625d8cSopenharmony_ci        #[command(flatten)]
7219625d8cSopenharmony_ci        options_b: OptionsB,
7319625d8cSopenharmony_ci
7419625d8cSopenharmony_ci        #[command(subcommand)]
7519625d8cSopenharmony_ci        sub_a: SubA,
7619625d8cSopenharmony_ci
7719625d8cSopenharmony_ci        #[arg(long)]
7819625d8cSopenharmony_ci        should_be_in_default_section: u32,
7919625d8cSopenharmony_ci    }
8019625d8cSopenharmony_ci
8119625d8cSopenharmony_ci    #[derive(Debug, Clone, Args)]
8219625d8cSopenharmony_ci    #[command(next_help_heading = "HEADING A")]
8319625d8cSopenharmony_ci    struct OptionsA {
8419625d8cSopenharmony_ci        #[arg(long)]
8519625d8cSopenharmony_ci        should_be_in_section_a: u32,
8619625d8cSopenharmony_ci    }
8719625d8cSopenharmony_ci
8819625d8cSopenharmony_ci    #[derive(Debug, Clone, Args)]
8919625d8cSopenharmony_ci    #[command(next_help_heading = "HEADING B")]
9019625d8cSopenharmony_ci    struct OptionsB {
9119625d8cSopenharmony_ci        #[arg(long)]
9219625d8cSopenharmony_ci        should_be_in_section_b: u32,
9319625d8cSopenharmony_ci    }
9419625d8cSopenharmony_ci
9519625d8cSopenharmony_ci    #[derive(Debug, Clone, Subcommand)]
9619625d8cSopenharmony_ci    enum SubA {
9719625d8cSopenharmony_ci        #[command(flatten)]
9819625d8cSopenharmony_ci        SubB(SubB),
9919625d8cSopenharmony_ci        #[command(subcommand)]
10019625d8cSopenharmony_ci        SubC(SubC),
10119625d8cSopenharmony_ci        SubAOne,
10219625d8cSopenharmony_ci        #[command(next_help_heading = "SUB A")]
10319625d8cSopenharmony_ci        SubATwo {
10419625d8cSopenharmony_ci            should_be_in_sub_a: u32,
10519625d8cSopenharmony_ci        },
10619625d8cSopenharmony_ci    }
10719625d8cSopenharmony_ci
10819625d8cSopenharmony_ci    #[derive(Debug, Clone, Subcommand)]
10919625d8cSopenharmony_ci    enum SubB {
11019625d8cSopenharmony_ci        #[command(next_help_heading = "SUB B")]
11119625d8cSopenharmony_ci        SubBOne { should_be_in_sub_b: u32 },
11219625d8cSopenharmony_ci    }
11319625d8cSopenharmony_ci
11419625d8cSopenharmony_ci    #[derive(Debug, Clone, Subcommand)]
11519625d8cSopenharmony_ci    enum SubC {
11619625d8cSopenharmony_ci        #[command(next_help_heading = "SUB C")]
11719625d8cSopenharmony_ci        SubCOne { should_be_in_sub_c: u32 },
11819625d8cSopenharmony_ci    }
11919625d8cSopenharmony_ci
12019625d8cSopenharmony_ci    let cmd = CliOptions::command();
12119625d8cSopenharmony_ci
12219625d8cSopenharmony_ci    let should_be_in_section_a = cmd
12319625d8cSopenharmony_ci        .get_arguments()
12419625d8cSopenharmony_ci        .find(|a| a.get_id() == "should_be_in_section_a")
12519625d8cSopenharmony_ci        .unwrap();
12619625d8cSopenharmony_ci    assert_eq!(should_be_in_section_a.get_help_heading(), Some("HEADING A"));
12719625d8cSopenharmony_ci
12819625d8cSopenharmony_ci    let should_be_in_section_b = cmd
12919625d8cSopenharmony_ci        .get_arguments()
13019625d8cSopenharmony_ci        .find(|a| a.get_id() == "should_be_in_section_b")
13119625d8cSopenharmony_ci        .unwrap();
13219625d8cSopenharmony_ci    assert_eq!(should_be_in_section_b.get_help_heading(), Some("HEADING B"));
13319625d8cSopenharmony_ci
13419625d8cSopenharmony_ci    let should_be_in_section_b = cmd
13519625d8cSopenharmony_ci        .get_arguments()
13619625d8cSopenharmony_ci        .find(|a| a.get_id() == "should_be_in_default_section")
13719625d8cSopenharmony_ci        .unwrap();
13819625d8cSopenharmony_ci    assert_eq!(should_be_in_section_b.get_help_heading(), Some("HEADING B"));
13919625d8cSopenharmony_ci
14019625d8cSopenharmony_ci    let sub_a_two = cmd.find_subcommand("sub-a-two").unwrap();
14119625d8cSopenharmony_ci
14219625d8cSopenharmony_ci    let should_be_in_sub_a = sub_a_two
14319625d8cSopenharmony_ci        .get_arguments()
14419625d8cSopenharmony_ci        .find(|a| a.get_id() == "should_be_in_sub_a")
14519625d8cSopenharmony_ci        .unwrap();
14619625d8cSopenharmony_ci    assert_eq!(should_be_in_sub_a.get_help_heading(), Some("SUB A"));
14719625d8cSopenharmony_ci
14819625d8cSopenharmony_ci    let sub_b_one = cmd.find_subcommand("sub-b-one").unwrap();
14919625d8cSopenharmony_ci
15019625d8cSopenharmony_ci    let should_be_in_sub_b = sub_b_one
15119625d8cSopenharmony_ci        .get_arguments()
15219625d8cSopenharmony_ci        .find(|a| a.get_id() == "should_be_in_sub_b")
15319625d8cSopenharmony_ci        .unwrap();
15419625d8cSopenharmony_ci    assert_eq!(should_be_in_sub_b.get_help_heading(), Some("SUB B"));
15519625d8cSopenharmony_ci
15619625d8cSopenharmony_ci    let sub_c = cmd.find_subcommand("sub-c").unwrap();
15719625d8cSopenharmony_ci    let sub_c_one = sub_c.find_subcommand("sub-c-one").unwrap();
15819625d8cSopenharmony_ci
15919625d8cSopenharmony_ci    let should_be_in_sub_c = sub_c_one
16019625d8cSopenharmony_ci        .get_arguments()
16119625d8cSopenharmony_ci        .find(|a| a.get_id() == "should_be_in_sub_c")
16219625d8cSopenharmony_ci        .unwrap();
16319625d8cSopenharmony_ci    assert_eq!(should_be_in_sub_c.get_help_heading(), Some("SUB C"));
16419625d8cSopenharmony_ci}
16519625d8cSopenharmony_ci
16619625d8cSopenharmony_ci#[test]
16719625d8cSopenharmony_cifn flatten_field_with_help_heading() {
16819625d8cSopenharmony_ci    #[derive(Debug, Clone, Parser)]
16919625d8cSopenharmony_ci    struct CliOptions {
17019625d8cSopenharmony_ci        #[command(flatten)]
17119625d8cSopenharmony_ci        #[command(next_help_heading = "HEADING A")]
17219625d8cSopenharmony_ci        options_a: OptionsA,
17319625d8cSopenharmony_ci    }
17419625d8cSopenharmony_ci
17519625d8cSopenharmony_ci    #[derive(Debug, Clone, Args)]
17619625d8cSopenharmony_ci    struct OptionsA {
17719625d8cSopenharmony_ci        #[arg(long)]
17819625d8cSopenharmony_ci        should_be_in_section_a: u32,
17919625d8cSopenharmony_ci    }
18019625d8cSopenharmony_ci
18119625d8cSopenharmony_ci    let cmd = CliOptions::command();
18219625d8cSopenharmony_ci
18319625d8cSopenharmony_ci    let should_be_in_section_a = cmd
18419625d8cSopenharmony_ci        .get_arguments()
18519625d8cSopenharmony_ci        .find(|a| a.get_id() == "should_be_in_section_a")
18619625d8cSopenharmony_ci        .unwrap();
18719625d8cSopenharmony_ci    assert_eq!(should_be_in_section_a.get_help_heading(), Some("HEADING A"));
18819625d8cSopenharmony_ci}
18919625d8cSopenharmony_ci
19019625d8cSopenharmony_ci// The challenge with this test is creating an error situation not caught by `clap`'s error checking
19119625d8cSopenharmony_ci// but by the code that `clap_derive` generates.
19219625d8cSopenharmony_ci//
19319625d8cSopenharmony_ci// Ultimately, the easiest way to confirm is to put a debug statement in the desired error path.
19419625d8cSopenharmony_ci#[test]
19519625d8cSopenharmony_cifn derive_generated_error_has_full_context() {
19619625d8cSopenharmony_ci    #[derive(Debug, Parser)]
19719625d8cSopenharmony_ci    #[command(subcommand_negates_reqs = true)]
19819625d8cSopenharmony_ci    struct Opts {
19919625d8cSopenharmony_ci        #[arg(long)]
20019625d8cSopenharmony_ci        req_str: String,
20119625d8cSopenharmony_ci
20219625d8cSopenharmony_ci        #[command(subcommand)]
20319625d8cSopenharmony_ci        cmd: Option<SubCommands>,
20419625d8cSopenharmony_ci    }
20519625d8cSopenharmony_ci
20619625d8cSopenharmony_ci    #[derive(Debug, Parser)]
20719625d8cSopenharmony_ci    enum SubCommands {
20819625d8cSopenharmony_ci        Sub {
20919625d8cSopenharmony_ci            #[arg(short, long, action = clap::ArgAction::Count)]
21019625d8cSopenharmony_ci            verbose: u8,
21119625d8cSopenharmony_ci        },
21219625d8cSopenharmony_ci    }
21319625d8cSopenharmony_ci
21419625d8cSopenharmony_ci    let result = Opts::try_parse_from(["test", "sub"]);
21519625d8cSopenharmony_ci    assert!(
21619625d8cSopenharmony_ci        result.is_err(),
21719625d8cSopenharmony_ci        "`SubcommandsNegateReqs` with non-optional `req_str` should fail: {:?}",
21819625d8cSopenharmony_ci        result.unwrap()
21919625d8cSopenharmony_ci    );
22019625d8cSopenharmony_ci
22119625d8cSopenharmony_ci    let expected = r#"error: The following required argument was not provided: req_str
22219625d8cSopenharmony_ci
22319625d8cSopenharmony_ciUsage: clap --req-str <REQ_STR>
22419625d8cSopenharmony_ci       clap <COMMAND>
22519625d8cSopenharmony_ci
22619625d8cSopenharmony_ciFor more information, try '--help'.
22719625d8cSopenharmony_ci"#;
22819625d8cSopenharmony_ci    assert_eq!(result.unwrap_err().to_string(), expected);
22919625d8cSopenharmony_ci}
23019625d8cSopenharmony_ci
23119625d8cSopenharmony_ci#[test]
23219625d8cSopenharmony_cifn derive_order_next_order() {
23319625d8cSopenharmony_ci    static HELP: &str = "\
23419625d8cSopenharmony_ciUsage: test [OPTIONS]
23519625d8cSopenharmony_ci
23619625d8cSopenharmony_ciOptions:
23719625d8cSopenharmony_ci      --flag-b               first flag
23819625d8cSopenharmony_ci      --option-b <OPTION_B>  first option
23919625d8cSopenharmony_ci  -h, --help                 Print help
24019625d8cSopenharmony_ci  -V, --version              Print version
24119625d8cSopenharmony_ci      --flag-a               second flag
24219625d8cSopenharmony_ci      --option-a <OPTION_A>  second option
24319625d8cSopenharmony_ci";
24419625d8cSopenharmony_ci
24519625d8cSopenharmony_ci    #[derive(Parser, Debug)]
24619625d8cSopenharmony_ci    #[command(name = "test", version = "1.2")]
24719625d8cSopenharmony_ci    struct Args {
24819625d8cSopenharmony_ci        #[command(flatten)]
24919625d8cSopenharmony_ci        a: A,
25019625d8cSopenharmony_ci        #[command(flatten)]
25119625d8cSopenharmony_ci        b: B,
25219625d8cSopenharmony_ci    }
25319625d8cSopenharmony_ci
25419625d8cSopenharmony_ci    #[derive(Args, Debug)]
25519625d8cSopenharmony_ci    #[command(next_display_order = 10000)]
25619625d8cSopenharmony_ci    struct A {
25719625d8cSopenharmony_ci        /// second flag
25819625d8cSopenharmony_ci        #[arg(long)]
25919625d8cSopenharmony_ci        flag_a: bool,
26019625d8cSopenharmony_ci        /// second option
26119625d8cSopenharmony_ci        #[arg(long)]
26219625d8cSopenharmony_ci        option_a: Option<String>,
26319625d8cSopenharmony_ci    }
26419625d8cSopenharmony_ci
26519625d8cSopenharmony_ci    #[derive(Args, Debug)]
26619625d8cSopenharmony_ci    #[command(next_display_order = 10)]
26719625d8cSopenharmony_ci    struct B {
26819625d8cSopenharmony_ci        /// first flag
26919625d8cSopenharmony_ci        #[arg(long)]
27019625d8cSopenharmony_ci        flag_b: bool,
27119625d8cSopenharmony_ci        /// first option
27219625d8cSopenharmony_ci        #[arg(long)]
27319625d8cSopenharmony_ci        option_b: Option<String>,
27419625d8cSopenharmony_ci    }
27519625d8cSopenharmony_ci
27619625d8cSopenharmony_ci    use clap::CommandFactory;
27719625d8cSopenharmony_ci    let mut cmd = Args::command();
27819625d8cSopenharmony_ci
27919625d8cSopenharmony_ci    let help = cmd.render_help().to_string();
28019625d8cSopenharmony_ci    snapbox::assert_eq(HELP, help);
28119625d8cSopenharmony_ci}
28219625d8cSopenharmony_ci
28319625d8cSopenharmony_ci#[test]
28419625d8cSopenharmony_cifn derive_order_next_order_flatten() {
28519625d8cSopenharmony_ci    static HELP: &str = "\
28619625d8cSopenharmony_ciUsage: test [OPTIONS]
28719625d8cSopenharmony_ci
28819625d8cSopenharmony_ciOptions:
28919625d8cSopenharmony_ci      --flag-b               first flag
29019625d8cSopenharmony_ci      --option-b <OPTION_B>  first option
29119625d8cSopenharmony_ci  -h, --help                 Print help
29219625d8cSopenharmony_ci  -V, --version              Print version
29319625d8cSopenharmony_ci      --flag-a               second flag
29419625d8cSopenharmony_ci      --option-a <OPTION_A>  second option
29519625d8cSopenharmony_ci";
29619625d8cSopenharmony_ci
29719625d8cSopenharmony_ci    #[derive(Parser, Debug)]
29819625d8cSopenharmony_ci    #[command(name = "test", version = "1.2")]
29919625d8cSopenharmony_ci    struct Args {
30019625d8cSopenharmony_ci        #[command(flatten)]
30119625d8cSopenharmony_ci        #[command(next_display_order = 10000)]
30219625d8cSopenharmony_ci        a: A,
30319625d8cSopenharmony_ci        #[command(flatten)]
30419625d8cSopenharmony_ci        #[command(next_display_order = 10)]
30519625d8cSopenharmony_ci        b: B,
30619625d8cSopenharmony_ci    }
30719625d8cSopenharmony_ci
30819625d8cSopenharmony_ci    #[derive(Args, Debug)]
30919625d8cSopenharmony_ci    struct A {
31019625d8cSopenharmony_ci        /// second flag
31119625d8cSopenharmony_ci        #[arg(long)]
31219625d8cSopenharmony_ci        flag_a: bool,
31319625d8cSopenharmony_ci        /// second option
31419625d8cSopenharmony_ci        #[arg(long)]
31519625d8cSopenharmony_ci        option_a: Option<String>,
31619625d8cSopenharmony_ci    }
31719625d8cSopenharmony_ci
31819625d8cSopenharmony_ci    #[derive(Args, Debug)]
31919625d8cSopenharmony_ci    struct B {
32019625d8cSopenharmony_ci        /// first flag
32119625d8cSopenharmony_ci        #[arg(long)]
32219625d8cSopenharmony_ci        flag_b: bool,
32319625d8cSopenharmony_ci        /// first option
32419625d8cSopenharmony_ci        #[arg(long)]
32519625d8cSopenharmony_ci        option_b: Option<String>,
32619625d8cSopenharmony_ci    }
32719625d8cSopenharmony_ci
32819625d8cSopenharmony_ci    use clap::CommandFactory;
32919625d8cSopenharmony_ci    let mut cmd = Args::command();
33019625d8cSopenharmony_ci
33119625d8cSopenharmony_ci    let help = cmd.render_help().to_string();
33219625d8cSopenharmony_ci    snapbox::assert_eq(HELP, help);
33319625d8cSopenharmony_ci}
33419625d8cSopenharmony_ci
33519625d8cSopenharmony_ci#[test]
33619625d8cSopenharmony_cifn derive_order_no_next_order() {
33719625d8cSopenharmony_ci    static HELP: &str = "\
33819625d8cSopenharmony_ciUsage: test [OPTIONS]
33919625d8cSopenharmony_ci
34019625d8cSopenharmony_ciOptions:
34119625d8cSopenharmony_ci      --flag-a               first flag
34219625d8cSopenharmony_ci      --flag-b               second flag
34319625d8cSopenharmony_ci  -h, --help                 Print help
34419625d8cSopenharmony_ci      --option-a <OPTION_A>  first option
34519625d8cSopenharmony_ci      --option-b <OPTION_B>  second option
34619625d8cSopenharmony_ci  -V, --version              Print version
34719625d8cSopenharmony_ci";
34819625d8cSopenharmony_ci
34919625d8cSopenharmony_ci    #[derive(Parser, Debug)]
35019625d8cSopenharmony_ci    #[command(name = "test", version = "1.2")]
35119625d8cSopenharmony_ci    #[command(next_display_order = None)]
35219625d8cSopenharmony_ci    struct Args {
35319625d8cSopenharmony_ci        #[command(flatten)]
35419625d8cSopenharmony_ci        a: A,
35519625d8cSopenharmony_ci        #[command(flatten)]
35619625d8cSopenharmony_ci        b: B,
35719625d8cSopenharmony_ci    }
35819625d8cSopenharmony_ci
35919625d8cSopenharmony_ci    #[derive(Args, Debug)]
36019625d8cSopenharmony_ci    struct A {
36119625d8cSopenharmony_ci        /// first flag
36219625d8cSopenharmony_ci        #[arg(long)]
36319625d8cSopenharmony_ci        flag_a: bool,
36419625d8cSopenharmony_ci        /// first option
36519625d8cSopenharmony_ci        #[arg(long)]
36619625d8cSopenharmony_ci        option_a: Option<String>,
36719625d8cSopenharmony_ci    }
36819625d8cSopenharmony_ci
36919625d8cSopenharmony_ci    #[derive(Args, Debug)]
37019625d8cSopenharmony_ci    struct B {
37119625d8cSopenharmony_ci        /// second flag
37219625d8cSopenharmony_ci        #[arg(long)]
37319625d8cSopenharmony_ci        flag_b: bool,
37419625d8cSopenharmony_ci        /// second option
37519625d8cSopenharmony_ci        #[arg(long)]
37619625d8cSopenharmony_ci        option_b: Option<String>,
37719625d8cSopenharmony_ci    }
37819625d8cSopenharmony_ci
37919625d8cSopenharmony_ci    use clap::CommandFactory;
38019625d8cSopenharmony_ci    let mut cmd = Args::command();
38119625d8cSopenharmony_ci
38219625d8cSopenharmony_ci    let help = cmd.render_help().to_string();
38319625d8cSopenharmony_ci    snapbox::assert_eq(HELP, help);
38419625d8cSopenharmony_ci}
38519625d8cSopenharmony_ci
38619625d8cSopenharmony_ci#[test]
38719625d8cSopenharmony_cifn derive_possible_value_help() {
38819625d8cSopenharmony_ci    static HELP: &str = "\
38919625d8cSopenharmony_ciApplication help
39019625d8cSopenharmony_ci
39119625d8cSopenharmony_ciUsage: clap <ARG>
39219625d8cSopenharmony_ci
39319625d8cSopenharmony_ciArguments:
39419625d8cSopenharmony_ci  <ARG>
39519625d8cSopenharmony_ci          Argument help
39619625d8cSopenharmony_ci
39719625d8cSopenharmony_ci          Possible values:
39819625d8cSopenharmony_ci          - foo: Foo help
39919625d8cSopenharmony_ci          - bar: Bar help
40019625d8cSopenharmony_ci
40119625d8cSopenharmony_ciOptions:
40219625d8cSopenharmony_ci  -h, --help
40319625d8cSopenharmony_ci          Print help (see a summary with '-h')
40419625d8cSopenharmony_ci";
40519625d8cSopenharmony_ci
40619625d8cSopenharmony_ci    /// Application help
40719625d8cSopenharmony_ci    #[derive(Parser, PartialEq, Debug)]
40819625d8cSopenharmony_ci    struct Args {
40919625d8cSopenharmony_ci        /// Argument help
41019625d8cSopenharmony_ci        #[arg(value_enum)]
41119625d8cSopenharmony_ci        arg: ArgChoice,
41219625d8cSopenharmony_ci    }
41319625d8cSopenharmony_ci
41419625d8cSopenharmony_ci    #[derive(clap::ValueEnum, PartialEq, Debug, Clone)]
41519625d8cSopenharmony_ci    enum ArgChoice {
41619625d8cSopenharmony_ci        /// Foo help
41719625d8cSopenharmony_ci        Foo,
41819625d8cSopenharmony_ci        /// Bar help
41919625d8cSopenharmony_ci        Bar,
42019625d8cSopenharmony_ci    }
42119625d8cSopenharmony_ci
42219625d8cSopenharmony_ci    use clap::CommandFactory;
42319625d8cSopenharmony_ci    let mut cmd = Args::command();
42419625d8cSopenharmony_ci
42519625d8cSopenharmony_ci    let help = cmd.render_long_help().to_string();
42619625d8cSopenharmony_ci    snapbox::assert_eq(HELP, help);
42719625d8cSopenharmony_ci}
42819625d8cSopenharmony_ci
42919625d8cSopenharmony_ci#[test]
43019625d8cSopenharmony_cifn custom_help_flag() {
43119625d8cSopenharmony_ci    #[derive(Debug, Clone, Parser)]
43219625d8cSopenharmony_ci    #[command(disable_help_flag = true)]
43319625d8cSopenharmony_ci    struct CliOptions {
43419625d8cSopenharmony_ci        #[arg(short = 'h', long = "verbose-help", action = ArgAction::Help, value_parser = clap::value_parser!(bool))]
43519625d8cSopenharmony_ci        help: (),
43619625d8cSopenharmony_ci    }
43719625d8cSopenharmony_ci
43819625d8cSopenharmony_ci    let result = CliOptions::try_parse_from(["cmd", "--verbose-help"]);
43919625d8cSopenharmony_ci    let err = result.unwrap_err();
44019625d8cSopenharmony_ci    assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp);
44119625d8cSopenharmony_ci
44219625d8cSopenharmony_ci    CliOptions::try_parse_from(["cmd"]).unwrap();
44319625d8cSopenharmony_ci}
44419625d8cSopenharmony_ci
44519625d8cSopenharmony_ci#[test]
44619625d8cSopenharmony_cifn custom_version_flag() {
44719625d8cSopenharmony_ci    #[derive(Debug, Clone, Parser)]
44819625d8cSopenharmony_ci    #[command(disable_version_flag = true, version = "2.0.0")]
44919625d8cSopenharmony_ci    struct CliOptions {
45019625d8cSopenharmony_ci        #[arg(short = 'V', long = "verbose-version", action = ArgAction::Version, value_parser = clap::value_parser!(bool))]
45119625d8cSopenharmony_ci        version: (),
45219625d8cSopenharmony_ci    }
45319625d8cSopenharmony_ci
45419625d8cSopenharmony_ci    let result = CliOptions::try_parse_from(["cmd", "--verbose-version"]);
45519625d8cSopenharmony_ci    let err = result.unwrap_err();
45619625d8cSopenharmony_ci    assert_eq!(err.kind(), clap::error::ErrorKind::DisplayVersion);
45719625d8cSopenharmony_ci
45819625d8cSopenharmony_ci    CliOptions::try_parse_from(["cmd"]).unwrap();
45919625d8cSopenharmony_ci}
460