From 91199f0eed6483db86e9627af2af272b932ea74d Mon Sep 17 00:00:00 2001 From: Michael Yang Date: Wed, 8 May 2024 18:48:26 +1000 Subject: [PATCH] test: Add `require_no_space` tests Remove and modify some `require_equals` tests that are no longer valid. --- tests/builder/help.rs | 115 +++++++++++++++++++++++++++++ tests/builder/opts.rs | 139 +++++++++++++++++++++++++++++++++++ tests/builder/require.rs | 152 ++++++++++++++++++++++++++++----------- 3 files changed, 365 insertions(+), 41 deletions(-) diff --git a/tests/builder/help.rs b/tests/builder/help.rs index 5f413145018..f4c73799133 100644 --- a/tests/builder/help.rs +++ b/tests/builder/help.rs @@ -2004,6 +2004,121 @@ Options: utils::assert_output(cmd, "ctest -h", ISSUE_1487, false); } +#[test] +fn help_require_equals() { + static REQUIRE_EQUALS: &str = "\ +Usage: myapp [OPTIONS] + +Options: + --foo= + -h, --help Print help +"; + let cmd = Command::new("myapp").arg( + Arg::new("foo") + .long("foo") + .require_equals(true) + .action(ArgAction::Set), + ); + utils::assert_output(cmd, "myapp -h", REQUIRE_EQUALS, false); +} + +#[test] +fn help_require_equals_short() { + static REQUIRE_EQUALS_SHORT: &str = "\ +Usage: myapp [OPTIONS] + +Options: + -f + -h, --help Print help +"; + let cmd = Command::new("myapp").arg( + Arg::new("foo") + .short('f') + .require_equals(true) + .action(ArgAction::Set), + ); + utils::assert_output(cmd, "myapp -h", REQUIRE_EQUALS_SHORT, false); +} + +#[test] +fn help_require_no_space() { + static REQUIRE_NO_SPACE: &str = "\ +Usage: myapp [OPTIONS] + +Options: + -f + -h, --help Print help +"; + let cmd = Command::new("myapp").arg( + Arg::new("foo") + .short('f') + .require_no_space(true) + .action(ArgAction::Set), + ); + utils::assert_output(cmd, "myapp -h", REQUIRE_NO_SPACE, false); +} + +#[test] +fn help_require_no_space_long() { + static REQUIRE_NO_SPACE_LONG: &str = "\ +Usage: myapp [OPTIONS] + +Options: + --foo + -h, --help Print help +"; + let cmd = Command::new("myapp").arg( + Arg::new("foo") + .long("foo") + .require_no_space(true) + .action(ArgAction::Set), + ); + utils::assert_output(cmd, "myapp -h", REQUIRE_NO_SPACE_LONG, false); +} + +#[test] +fn help_require_equals_no_space() { + static REQUIRE_EQUALS_NO_SPACE: &str = "\ +Usage: myapp [OPTIONS] + +Options: + -f, --foo= This is foo + -h, --help Print help +"; + let cmd = Command::new("myapp").arg( + Arg::new("foo") + .long("foo") + .short('f') + .help("This is foo") + .require_equals(true) + .require_no_space(true) + .action(ArgAction::Set), + ); + utils::assert_output(cmd, "myapp -h", REQUIRE_EQUALS_NO_SPACE, false); +} + +#[test] +fn help_require_equals_no_space_optional() { + static REQUIRE_EQUALS_NO_SPACE_OPTIONAL: &str = "\ +Usage: myapp [OPTIONS] + +Options: + -f[], --foo[=] This is foo + -h, --help Print help +"; + let cmd = Command::new("myapp").arg( + Arg::new("foo") + .long("foo") + .short('f') + .help("This is foo") + .num_args(0..=1) + .require_equals(true) + .require_no_space(true) + .action(ArgAction::Set), + ); + utils::assert_output(cmd, "myapp -h", REQUIRE_EQUALS_NO_SPACE_OPTIONAL, false); +} + #[cfg(debug_assertions)] #[test] #[should_panic = "Command::help_expected is enabled for the Command"] diff --git a/tests/builder/opts.rs b/tests/builder/opts.rs index 501bb469c3d..696cd51df6f 100644 --- a/tests/builder/opts.rs +++ b/tests/builder/opts.rs @@ -113,6 +113,145 @@ fn require_equals_pass() { assert!(res.is_ok(), "{}", res.unwrap_err()); } +#[test] +fn require_equals_short_unaffected() { + let res = Command::new("prog") + .arg( + Arg::new("cfg") + .action(ArgAction::Set) + .require_equals(true) + .short('c'), + ) + .try_get_matches_from(vec!["prog", "-c", "file.conf"]); + assert!(res.is_ok(), "{}", res.unwrap_err()); +} + +#[test] +fn require_equals_short_min_values_zero() { + let res = Command::new("prog") + .arg( + Arg::new("cfg") + .action(ArgAction::Set) + .require_equals(true) + .num_args(0..) + .short('c'), + ) + .arg(Arg::new("cmd")) + .try_get_matches_from(vec!["prog", "-c", "cmd"]); + assert!(res.is_ok(), "{}", res.unwrap_err()); + let m = res.unwrap(); + assert_eq!(m.get_one::("cfg").map(|v| v.as_str()), Some("cmd")); + assert_eq!(m.get_one::("cmd"), None); +} + +#[test] +fn require_no_space_fail() { + let res = Command::new("prog") + .arg( + Arg::new("cfg") + .action(ArgAction::Set) + .require_no_space(true) + .short('c'), + ) + .try_get_matches_from(vec!["prog", "-c", "file.conf"]); + assert!(res.is_err()); + assert_eq!(res.unwrap_err().kind(), ErrorKind::SpaceFound); +} + +#[test] +#[cfg(feature = "error-context")] +fn require_no_space_fail_message() { + static SPACE_FOUND: &str = "error: no space is allowed when assigning values to '-c' + +Usage: prog [OPTIONS] + +For more information, try '--help'. +"; + let cmd = Command::new("prog").arg( + Arg::new("cfg") + .action(ArgAction::Set) + .require_no_space(true) + .short('c'), + ); + utils::assert_output(cmd, "prog -c file.conf", SPACE_FOUND, true); +} + +#[test] +fn require_no_space_min_values_zero() { + let res = Command::new("prog") + .arg( + Arg::new("cfg") + .action(ArgAction::Set) + .require_no_space(true) + .num_args(0..) + .short('c'), + ) + .arg(Arg::new("cmd")) + .try_get_matches_from(vec!["prog", "-c", "cmd"]); + assert!(res.is_ok(), "{}", res.unwrap_err()); + let m = res.unwrap(); + assert!(m.contains_id("cfg")); + assert_eq!(m.get_one::("cmd").map(|v| v.as_str()), Some("cmd")); +} + +#[test] +fn require_no_space_empty_fail() { + let res = Command::new("prog") + .arg( + Arg::new("cfg") + .action(ArgAction::Set) + .require_no_space(true) + .short('c'), + ) + .try_get_matches_from(vec!["prog", "-c"]); + assert!(res.is_err()); + assert_eq!(res.unwrap_err().kind(), ErrorKind::SpaceFound); +} + +#[test] +fn require_no_space_pass() { + let res = Command::new("prog") + .arg( + Arg::new("cfg") + .action(ArgAction::Set) + .require_no_space(true) + .short('c'), + ) + .try_get_matches_from(vec!["prog", "-cfile.conf"]); + assert!(res.is_ok(), "{}", res.unwrap_err()); +} + +#[test] +fn require_no_space_equals_pass() { + let res = Command::new("prog") + .arg( + Arg::new("cfg") + .action(ArgAction::Set) + .require_no_space(true) + .short('c'), + ) + .try_get_matches_from(vec!["prog", "-c=file.conf"]); + assert!(res.is_ok(), "{}", res.unwrap_err()); + assert_eq!( + res.unwrap().get_one::("cfg").map(|v| v.as_str()), + Some("=file.conf") + ); +} + +#[test] +fn require_no_space_long_unaffected() { + let res = Command::new("prog") + .arg( + Arg::new("cfg") + .action(ArgAction::Set) + .require_no_space(true) + .short('c') + .long("config"), + ) + .try_get_matches_from(vec!["prog", "--config", "file.conf"]); + assert!(res.is_ok(), "{}", res.unwrap_err()) +} + #[test] fn stdin_char() { let r = Command::new("opts") diff --git a/tests/builder/require.rs b/tests/builder/require.rs index ea0f09f57ef..5fbfc1a1a05 100644 --- a/tests/builder/require.rs +++ b/tests/builder/require.rs @@ -1061,6 +1061,117 @@ fn issue_1158_app() -> Command { .arg(arg!(z: -z "Z")) } +#[test] +#[cfg(feature = "error-context")] +fn require_no_space() { + static REQUIRE_NO_SPACE:&str = "\ +error: the following required arguments were not provided: + --opt + +Usage: clap-test --opt + +For more information, try '--help'. +"; + let cmd = Command::new("clap-test").version("v1.4.8").arg( + Arg::new("opt") + .long("opt") + .short('o') + .required(true) + .require_no_space(true) + .value_name("FILE") + .help("some"), + ); + utils::assert_output(cmd, "clap-test", REQUIRE_NO_SPACE, true); +} + +#[test] +#[cfg(feature = "error-context")] +fn require_no_space_filtered() { + static REQUIRE_NO_SPACE_FILTERED: &str = "\ +error: the following required arguments were not provided: + -o + +Usage: clap-test -o -f + +For more information, try '--help'. +"; + + let cmd = Command::new("clap-test") + .version("v1.4.8") + .arg( + Arg::new("opt") + .short('o') + .required(true) + .require_no_space(true) + .value_name("FILE") + .help("some"), + ) + .arg( + Arg::new("foo") + .short('f') + .required(true) + .require_no_space(true) + .value_name("FILE") + .help("some other arg"), + ); + utils::assert_output(cmd, "clap-test -fblah", REQUIRE_NO_SPACE_FILTERED, true); +} + +#[test] +#[cfg(feature = "error-context")] +fn require_no_space_filtered_group() { + static REQUIRE_NO_SPACE_FILTERED_GROUP: &str = "\ +error: the following required arguments were not provided: + -o + +Usage: clap-test -o -f <-g|-i> + +For more information, try '--help'. +"; + + let cmd = Command::new("clap-test") + .version("v1.4.8") + .arg( + Arg::new("opt") + .short('o') + .required(true) + .require_no_space(true) + .value_name("FILE") + .help("some"), + ) + .arg( + Arg::new("foo") + .short('f') + .required(true) + .require_no_space(true) + .value_name("FILE") + .help("some other arg"), + ) + .arg( + Arg::new("g1") + .short('g') + .require_no_space(true) + .value_name("FILE"), + ) + .arg( + Arg::new("g2") + .short('i') + .require_no_space(true) + .value_name("FILE"), + ) + .group( + ArgGroup::new("test_group") + .args(["g1", "g2"]) + .required(true), + ); + utils::assert_output( + cmd, + "clap-test -fblah -gblah", + REQUIRE_NO_SPACE_FILTERED_GROUP, + true, + ); +} + #[test] #[cfg(feature = "error-context")] fn multiple_required_unless_usage_printing() { @@ -1157,47 +1268,6 @@ fn issue_1643_args_mutually_require_each_other() { .unwrap(); } -#[test] -fn short_flag_require_equals_with_minvals_zero() { - let m = Command::new("foo") - .arg( - Arg::new("check") - .short('c') - .num_args(0..) - .require_equals(true), - ) - .arg(Arg::new("unique").short('u').action(ArgAction::SetTrue)) - .try_get_matches_from(["foo", "-cu"]) - .unwrap(); - assert!(m.contains_id("check")); - assert!(*m.get_one::("unique").expect("defaulted by clap")); -} - -#[test] -fn issue_2624() { - let matches = Command::new("foo") - .arg( - Arg::new("check") - .short('c') - .long("check") - .require_equals(true) - .num_args(0..) - .value_parser(["silent", "quiet", "diagnose-first"]), - ) - .arg( - Arg::new("unique") - .short('u') - .long("unique") - .action(ArgAction::SetTrue), - ) - .try_get_matches_from(["foo", "-cu"]) - .unwrap(); - assert!(matches.contains_id("check")); - assert!(*matches - .get_one::("unique") - .expect("defaulted by clap")); -} - #[test] fn required_unless_all_with_any() { let cmd = Command::new("prog")