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