clap/tests/app_settings.rs
Reagan McFarland b184dc001b setting: SubcommandHelpShowsLongForm implemented
Refactoring and better test cases

Refactored SubcommandHelpShowsLongForm to
UseLongFormatForHelpSubcommand.
Tests and docuemntation examples use about and long_about instead of
(before/after)_help.

Removed commented out tests

Linting: Fix trailing new line

Updated change log, refactored tests and doc str

Reordered items in the Changelog
New test added and old tests removed that were redundant
Doc string for AppSettings::UseLongFormatForHelpSubcommand fixed
2021-04-11 14:31:40 -04:00

1131 lines
32 KiB
Rust

mod utils;
use clap::{App, AppSettings, Arg, ErrorKind};
static ALLOW_EXT_SC: &str = "clap-test v1.4.8
USAGE:
clap-test [SUBCOMMAND]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information";
static DONT_COLLAPSE_ARGS: &str = "clap-test v1.4.8
USAGE:
clap-test [arg1] [arg2] [arg3]
ARGS:
<arg1> some
<arg2> some
<arg3> some
FLAGS:
-h, --help Prints help information
-V, --version Prints version information";
static REQUIRE_EQUALS: &str = "clap-test v1.4.8
USAGE:
clap-test --opt=<FILE>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-o, --opt=<FILE> some";
static UNIFIED_HELP: &str = "test 1.3
Kevin K.
tests stuff
USAGE:
test [OPTIONS] [arg1]
ARGS:
<arg1> some pos arg
OPTIONS:
-f, --flag some flag
-h, --help Prints help information
--option <opt> some option
-V, --version Prints version information";
static SKIP_POS_VALS: &str = "test 1.3
Kevin K.
tests stuff
USAGE:
test [OPTIONS] [arg1]
ARGS:
<arg1> some pos arg
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-o, --opt <opt> some option";
static ARG_REQUIRED_ELSE_HELP: &str = "test 1.0
USAGE:
test [FLAGS]
FLAGS:
-h, --help Prints help information
-i, --info Provides more info
-V, --version Prints version information";
static SUBCOMMAND_REQUIRED_ELSE_HELP: &str = "test 1.0
USAGE:
test <SUBCOMMAND>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
SUBCOMMANDS:
help Prints this message or the help of the given subcommand(s)
info";
static LONG_FORMAT_FOR_HELP_SUBCOMMAND: &str = "myprog-test
USAGE:
myprog test [foo]
ARGS:
<foo>
long form about message
FLAGS:
-h, --help
Prints help information
-V, --version
Prints version information";
static LONG_FORMAT_FOR_NESTED_HELP_SUBCOMMAND: &str = "myprog-test-nested
long form about message
USAGE:
myprog test nested
FLAGS:
-h, --help
Prints help information
-V, --version
Prints version information";
static LONG_FORMAT_SINGLE_ARG_HELP_SUBCOMMAND: &str = "myprog
USAGE:
myprog [foo] [SUBCOMMAND]
ARGS:
<foo>
long form about message
FLAGS:
-h, --help
Prints help information
-V, --version
Prints version information
SUBCOMMANDS:
help
Prints this message or the help of the given subcommand(s)
test";
#[test]
fn sub_command_negate_required() {
App::new("sub_command_negate")
.setting(AppSettings::SubcommandsNegateReqs)
.arg(Arg::new("test").required(true).index(1))
.subcommand(App::new("sub1"))
.get_matches_from(vec!["myprog", "sub1"]);
}
#[test]
fn sub_command_negate_required_2() {
let result = App::new("sub_command_negate")
.setting(AppSettings::SubcommandsNegateReqs)
.arg(Arg::new("test").required(true).index(1))
.subcommand(App::new("sub1"))
.try_get_matches_from(vec![""]);
assert!(result.is_err());
let err = result.err().unwrap();
assert_eq!(err.kind, ErrorKind::MissingRequiredArgument);
}
#[test]
fn sub_command_required() {
let result = App::new("sc_required")
.setting(AppSettings::SubcommandRequired)
.subcommand(App::new("sub1"))
.try_get_matches_from(vec![""]);
assert!(result.is_err());
let err = result.err().unwrap();
assert_eq!(err.kind, ErrorKind::MissingSubcommand);
}
#[test]
fn arg_required_else_help() {
let result = App::new("arg_required")
.setting(AppSettings::ArgRequiredElseHelp)
.arg(Arg::new("test").index(1))
.try_get_matches_from(vec![""]);
assert!(result.is_err());
let err = result.err().unwrap();
assert_eq!(
err.kind,
ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand
);
}
#[test]
fn arg_required_else_help_over_reqs() {
let result = App::new("arg_required")
.setting(AppSettings::ArgRequiredElseHelp)
.arg(Arg::new("test").index(1).required(true))
.try_get_matches_from(vec![""]);
assert!(result.is_err());
let err = result.err().unwrap();
assert_eq!(
err.kind,
ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand
);
}
#[test]
fn arg_required_else_help_error_message() {
let app = App::new("test")
.setting(AppSettings::ArgRequiredElseHelp)
.version("1.0")
.arg(
Arg::new("info")
.about("Provides more info")
.short('i')
.long("info"),
);
assert!(utils::compare_output(
app,
"test",
ARG_REQUIRED_ELSE_HELP,
false
));
}
#[test]
fn subcommand_required_else_help() {
let result = App::new("test")
.setting(AppSettings::SubcommandRequiredElseHelp)
.subcommand(App::new("info"))
.try_get_matches_from(&[""]);
assert!(result.is_err());
let err = result.err().unwrap();
assert_eq!(
err.kind,
ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand
);
}
#[test]
fn subcommand_required_else_help_error_message() {
let app = App::new("test")
.setting(AppSettings::SubcommandRequiredElseHelp)
.version("1.0")
.subcommand(App::new("info").arg(Arg::new("filename")));
assert!(utils::compare_output(
app,
"test",
SUBCOMMAND_REQUIRED_ELSE_HELP,
false
));
}
#[cfg(not(feature = "suggestions"))]
#[test]
fn infer_subcommands_fail_no_args() {
let m = App::new("prog")
.setting(AppSettings::InferSubcommands)
.subcommand(App::new("test"))
.subcommand(App::new("temp"))
.try_get_matches_from(vec!["prog", "te"]);
assert!(m.is_err(), "{:#?}", m.unwrap());
assert_eq!(m.unwrap_err().kind, ErrorKind::UnrecognizedSubcommand);
}
#[cfg(feature = "suggestions")]
#[test]
fn infer_subcommands_fail_no_args() {
let m = App::new("prog")
.setting(AppSettings::InferSubcommands)
.subcommand(App::new("test"))
.subcommand(App::new("temp"))
.try_get_matches_from(vec!["prog", "te"]);
assert!(m.is_err(), "{:#?}", m.unwrap());
assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidSubcommand);
}
#[test]
fn infer_subcommands_fail_with_args() {
let m = App::new("prog")
.setting(AppSettings::InferSubcommands)
.arg(Arg::new("some"))
.subcommand(App::new("test"))
.subcommand(App::new("temp"))
.try_get_matches_from(vec!["prog", "t"]);
assert!(m.is_ok(), "{:?}", m.unwrap_err().kind);
assert_eq!(m.unwrap().value_of("some"), Some("t"));
}
#[test]
fn infer_subcommands_fail_with_args2() {
let m = App::new("prog")
.setting(AppSettings::InferSubcommands)
.arg(Arg::new("some"))
.subcommand(App::new("test"))
.subcommand(App::new("temp"))
.try_get_matches_from(vec!["prog", "te"]);
assert!(m.is_ok(), "{:?}", m.unwrap_err().kind);
assert_eq!(m.unwrap().value_of("some"), Some("te"));
}
#[test]
fn infer_subcommands_pass() {
let m = App::new("prog")
.setting(AppSettings::InferSubcommands)
.subcommand(App::new("test"))
.get_matches_from(vec!["prog", "te"]);
assert_eq!(m.subcommand_name(), Some("test"));
}
#[test]
fn infer_subcommands_pass_close() {
let m = App::new("prog")
.setting(AppSettings::InferSubcommands)
.subcommand(App::new("test"))
.subcommand(App::new("temp"))
.get_matches_from(vec!["prog", "tes"]);
assert_eq!(m.subcommand_name(), Some("test"));
}
#[test]
fn infer_subcommands_pass_exact_match() {
let m = App::new("prog")
.setting(AppSettings::InferSubcommands)
.subcommand(App::new("test"))
.subcommand(App::new("testa"))
.subcommand(App::new("testb"))
.get_matches_from(vec!["prog", "test"]);
assert_eq!(m.subcommand_name(), Some("test"));
}
#[cfg(feature = "suggestions")]
#[test]
fn infer_subcommands_fail_suggestions() {
let m = App::new("prog")
.setting(AppSettings::InferSubcommands)
.subcommand(App::new("test"))
.subcommand(App::new("temp"))
.try_get_matches_from(vec!["prog", "temps"]);
assert!(m.is_err(), "{:#?}", m.unwrap());
assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidSubcommand);
}
#[cfg(not(feature = "suggestions"))]
#[test]
fn infer_subcommands_fail_suggestions() {
let m = App::new("prog")
.setting(AppSettings::InferSubcommands)
.subcommand(App::new("test"))
.subcommand(App::new("temp"))
.try_get_matches_from(vec!["prog", "temps"]);
assert!(m.is_err(), "{:#?}", m.unwrap());
assert_eq!(m.unwrap_err().kind, ErrorKind::UnrecognizedSubcommand);
}
#[test]
fn no_bin_name() {
let result = App::new("arg_required")
.setting(AppSettings::NoBinaryName)
.arg(Arg::new("test").required(true).index(1))
.try_get_matches_from(vec!["testing"]);
assert!(result.is_ok());
let matches = result.unwrap();
assert_eq!(matches.value_of("test").unwrap(), "testing");
}
#[test]
fn unified_help() {
let app = App::new("myTest")
.name("test")
.author("Kevin K.")
.about("tests stuff")
.version("1.3")
.setting(AppSettings::UnifiedHelpMessage)
.arg("-f, --flag 'some flag'")
.arg("[arg1] 'some pos arg'")
.arg("--option [opt] 'some option'");
assert!(utils::compare_output(
app,
"test --help",
UNIFIED_HELP,
false
));
}
#[test]
fn skip_possible_values() {
let app = App::new("test")
.author("Kevin K.")
.about("tests stuff")
.version("1.3")
.setting(AppSettings::HidePossibleValuesInHelp)
.args(&[
Arg::from("-o, --opt [opt] 'some option'").possible_values(&["one", "two"]),
Arg::from("[arg1] 'some pos arg'").possible_values(&["three", "four"]),
]);
assert!(utils::compare_output(
app,
"test --help",
SKIP_POS_VALS,
false
));
}
#[test]
fn stop_delim_values_only_pos_follows() {
let r = App::new("onlypos")
.setting(AppSettings::DontDelimitTrailingValues)
.args(&[
Arg::from("-f [flag] 'some opt'"),
Arg::from("[arg]... 'some arg'"),
])
.try_get_matches_from(vec!["", "--", "-f", "-g,x"]);
assert!(r.is_ok());
let m = r.unwrap();
assert!(m.is_present("arg"));
assert!(!m.is_present("f"));
assert_eq!(
m.values_of("arg").unwrap().collect::<Vec<_>>(),
&["-f", "-g,x"]
);
}
#[test]
fn dont_delim_values_trailingvararg() {
let m = App::new("positional")
.setting(AppSettings::TrailingVarArg)
.setting(AppSettings::DontDelimitTrailingValues)
.arg(Arg::from("[opt]... 'some pos'"))
.get_matches_from(vec!["", "test", "--foo", "-Wl,-bar"]);
assert!(m.is_present("opt"));
assert_eq!(
m.values_of("opt").unwrap().collect::<Vec<_>>(),
&["test", "--foo", "-Wl,-bar"]
);
}
#[test]
fn delim_values_only_pos_follows() {
let r = App::new("onlypos")
.args(&[
Arg::from("-f [flag] 'some opt'"),
Arg::from("[arg]... 'some arg'"),
])
.try_get_matches_from(vec!["", "--", "-f", "-g,x"]);
assert!(r.is_ok());
let m = r.unwrap();
assert!(m.is_present("arg"));
assert!(!m.is_present("f"));
assert_eq!(
m.values_of("arg").unwrap().collect::<Vec<_>>(),
&["-f", "-g,x"]
);
}
#[test]
fn delim_values_trailingvararg() {
let m = App::new("positional")
.setting(AppSettings::TrailingVarArg)
.arg(Arg::from("[opt]... 'some pos'"))
.get_matches_from(vec!["", "test", "--foo", "-Wl,-bar"]);
assert!(m.is_present("opt"));
assert_eq!(
m.values_of("opt").unwrap().collect::<Vec<_>>(),
&["test", "--foo", "-Wl,-bar"]
);
}
#[test]
fn delim_values_only_pos_follows_with_delim() {
let r = App::new("onlypos")
.args(&[
Arg::from("-f [flag] 'some opt'"),
Arg::from("[arg]... 'some arg'").use_delimiter(true),
])
.try_get_matches_from(vec!["", "--", "-f", "-g,x"]);
assert!(r.is_ok());
let m = r.unwrap();
assert!(m.is_present("arg"));
assert!(!m.is_present("f"));
assert_eq!(
m.values_of("arg").unwrap().collect::<Vec<_>>(),
&["-f", "-g", "x"]
);
}
#[test]
fn delim_values_trailingvararg_with_delim() {
let m = App::new("positional")
.setting(AppSettings::TrailingVarArg)
.arg(Arg::from("[opt]... 'some pos'").use_delimiter(true))
.get_matches_from(vec!["", "test", "--foo", "-Wl,-bar"]);
assert!(m.is_present("opt"));
assert_eq!(
m.values_of("opt").unwrap().collect::<Vec<_>>(),
&["test", "--foo", "-Wl", "-bar"]
);
}
#[test]
fn leading_hyphen_short() {
let res = App::new("leadhy")
.setting(AppSettings::AllowLeadingHyphen)
.arg(Arg::new("some"))
.arg(Arg::new("other").short('o'))
.try_get_matches_from(vec!["", "-bar", "-o"]);
assert!(res.is_ok(), "Error: {:?}", res.unwrap_err().kind);
let m = res.unwrap();
assert!(m.is_present("some"));
assert!(m.is_present("other"));
assert_eq!(m.value_of("some").unwrap(), "-bar");
}
#[test]
fn leading_hyphen_long() {
let res = App::new("leadhy")
.setting(AppSettings::AllowLeadingHyphen)
.arg(Arg::new("some"))
.arg(Arg::new("other").short('o'))
.try_get_matches_from(vec!["", "--bar", "-o"]);
assert!(res.is_ok(), "Error: {:?}", res.unwrap_err().kind);
let m = res.unwrap();
assert!(m.is_present("some"));
assert!(m.is_present("other"));
assert_eq!(m.value_of("some").unwrap(), "--bar");
}
#[test]
fn leading_hyphen_opt() {
let res = App::new("leadhy")
.setting(AppSettings::AllowLeadingHyphen)
.arg(Arg::new("some").takes_value(true).long("opt"))
.arg(Arg::new("other").short('o'))
.try_get_matches_from(vec!["", "--opt", "--bar", "-o"]);
assert!(res.is_ok(), "Error: {:?}", res.unwrap_err().kind);
let m = res.unwrap();
assert!(m.is_present("some"));
assert!(m.is_present("other"));
assert_eq!(m.value_of("some").unwrap(), "--bar");
}
#[test]
fn allow_negative_numbers() {
let res = App::new("negnum")
.setting(AppSettings::AllowNegativeNumbers)
.arg(Arg::new("panum"))
.arg(Arg::new("onum").short('o').takes_value(true))
.try_get_matches_from(vec!["negnum", "-20", "-o", "-1.2"]);
assert!(res.is_ok(), "Error: {:?}", res.unwrap_err().kind);
let m = res.unwrap();
assert_eq!(m.value_of("panum").unwrap(), "-20");
assert_eq!(m.value_of("onum").unwrap(), "-1.2");
}
#[test]
fn allow_negative_numbers_fail() {
let res = App::new("negnum")
.setting(AppSettings::AllowNegativeNumbers)
.arg(Arg::new("panum"))
.arg(Arg::new("onum").short('o').takes_value(true))
.try_get_matches_from(vec!["negnum", "--foo", "-o", "-1.2"]);
assert!(res.is_err());
assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument)
}
#[test]
fn leading_double_hyphen_trailingvararg() {
let m = App::new("positional")
.setting(AppSettings::TrailingVarArg)
.setting(AppSettings::AllowLeadingHyphen)
.arg(Arg::from("[opt]... 'some pos'"))
.get_matches_from(vec!["", "--foo", "-Wl", "bar"]);
assert!(m.is_present("opt"));
assert_eq!(
m.values_of("opt").unwrap().collect::<Vec<_>>(),
&["--foo", "-Wl", "bar"]
);
}
#[test]
fn unset_setting() {
let m = App::new("unset_setting").setting(AppSettings::AllArgsOverrideSelf);
assert!(m.is_set(AppSettings::AllArgsOverrideSelf));
let m = m.unset_setting(AppSettings::AllArgsOverrideSelf);
assert!(!m.is_set(AppSettings::AllArgsOverrideSelf));
}
#[test]
fn unset_settings() {
let m = App::new("unset_settings");
assert!(&m.is_set(AppSettings::AllowInvalidUtf8));
assert!(&m.is_set(AppSettings::ColorAuto));
let m = m
.unset_global_setting(AppSettings::AllowInvalidUtf8)
.unset_global_setting(AppSettings::ColorAuto);
assert!(!m.is_set(AppSettings::AllowInvalidUtf8), "{:#?}", m);
assert!(!m.is_set(AppSettings::ColorAuto), "{:#?}", m);
}
#[test]
fn disable_help_subcommand() {
let result = App::new("disablehelp")
.setting(AppSettings::DisableHelpSubcommand)
.subcommand(App::new("sub1"))
.try_get_matches_from(vec!["", "help"]);
assert!(result.is_err());
let err = result.err().unwrap();
assert_eq!(err.kind, ErrorKind::UnknownArgument);
}
#[test]
fn dont_collapse_args() {
let app = App::new("clap-test")
.version("v1.4.8")
.setting(AppSettings::DontCollapseArgsInUsage)
.args(&[
Arg::new("arg1").about("some"),
Arg::new("arg2").about("some"),
Arg::new("arg3").about("some"),
]);
assert!(utils::compare_output(
app,
"clap-test --help",
DONT_COLLAPSE_ARGS,
false
));
}
#[test]
fn require_eq() {
let app = App::new("clap-test").version("v1.4.8").arg(
Arg::new("opt")
.long("opt")
.short('o')
.required(true)
.require_equals(true)
.value_name("FILE")
.about("some"),
);
assert!(utils::compare_output(
app,
"clap-test --help",
REQUIRE_EQUALS,
false
));
}
#[test]
fn args_negate_subcommands_one_level() {
let res = App::new("disablehelp")
.setting(AppSettings::ArgsNegateSubcommands)
.setting(AppSettings::SubcommandsNegateReqs)
.arg("<arg1> 'some arg'")
.arg("<arg2> 'some arg'")
.subcommand(App::new("sub1").subcommand(App::new("sub2").subcommand(App::new("sub3"))))
.try_get_matches_from(vec!["", "pickles", "sub1"]);
assert!(res.is_ok(), "error: {:?}", res.unwrap_err().kind);
let m = res.unwrap();
assert_eq!(m.value_of("arg2"), Some("sub1"));
}
#[test]
fn args_negate_subcommands_two_levels() {
let res = App::new("disablehelp")
.global_setting(AppSettings::ArgsNegateSubcommands)
.global_setting(AppSettings::SubcommandsNegateReqs)
.arg("<arg1> 'some arg'")
.arg("<arg2> 'some arg'")
.subcommand(
App::new("sub1")
.arg("<arg> 'some'")
.arg("<arg2> 'some'")
.subcommand(App::new("sub2").subcommand(App::new("sub3"))),
)
.try_get_matches_from(vec!["", "sub1", "arg", "sub2"]);
assert!(res.is_ok(), "error: {:?}", res.unwrap_err().kind);
let m = res.unwrap();
assert_eq!(
m.subcommand_matches("sub1").unwrap().value_of("arg2"),
Some("sub2")
);
}
#[test]
fn propagate_vals_down() {
let m = App::new("myprog")
.arg(Arg::from("[cmd] 'command to run'").global(true))
.subcommand(App::new("foo"))
.try_get_matches_from(vec!["myprog", "set", "foo"]);
assert!(m.is_ok(), "{:?}", m.unwrap_err().kind);
let m = m.unwrap();
assert_eq!(m.value_of("cmd"), Some("set"));
let sub_m = m.subcommand_matches("foo").unwrap();
assert_eq!(sub_m.value_of("cmd"), Some("set"));
}
#[test]
fn allow_missing_positional() {
let m = App::new("test")
.setting(AppSettings::AllowMissingPositional)
.arg(Arg::from("[src] 'some file'").default_value("src"))
.arg("<dest> 'some file'")
.try_get_matches_from(vec!["test", "file"]);
assert!(m.is_ok(), "{:?}", m.unwrap_err().kind);
let m = m.unwrap();
assert_eq!(m.value_of("src"), Some("src"));
assert_eq!(m.value_of("dest"), Some("file"));
}
#[test]
fn allow_missing_positional_no_default() {
let m = App::new("test")
.setting(AppSettings::AllowMissingPositional)
.arg(Arg::from("[src] 'some file'"))
.arg("<dest> 'some file'")
.try_get_matches_from(vec!["test", "file"]);
assert!(m.is_ok(), "{:?}", m.unwrap_err().kind);
let m = m.unwrap();
assert_eq!(m.value_of("src"), None);
assert_eq!(m.value_of("dest"), Some("file"));
}
#[test]
fn missing_positional_no_hyphen() {
let r = App::new("bench")
.setting(AppSettings::AllowMissingPositional)
.arg(Arg::from("[BENCH] 'some bench'"))
.arg(Arg::from("[ARGS]... 'some args'"))
.try_get_matches_from(vec!["bench", "foo", "arg1", "arg2", "arg3"]);
assert!(r.is_ok(), "{:?}", r.unwrap_err().kind);
let m = r.unwrap();
let expected_bench = Some("foo");
let expected_args = vec!["arg1", "arg2", "arg3"];
assert_eq!(m.value_of("BENCH"), expected_bench);
assert_eq!(
m.values_of("ARGS").unwrap().collect::<Vec<_>>(),
&*expected_args
);
}
#[test]
fn missing_positional_hyphen() {
let r = App::new("bench")
.setting(AppSettings::AllowMissingPositional)
.arg(Arg::from("[BENCH] 'some bench'"))
.arg(Arg::from("[ARGS]... 'some args'"))
.try_get_matches_from(vec!["bench", "--", "arg1", "arg2", "arg3"]);
assert!(r.is_ok(), "{:?}", r.unwrap_err().kind);
let m = r.unwrap();
let expected_bench = None;
let expected_args = vec!["arg1", "arg2", "arg3"];
assert_eq!(m.value_of("BENCH"), expected_bench);
assert_eq!(
m.values_of("ARGS").unwrap().collect::<Vec<_>>(),
&*expected_args
);
}
#[test]
fn missing_positional_hyphen_far_back() {
let r = App::new("bench")
.setting(AppSettings::AllowMissingPositional)
.arg(Arg::from("[BENCH1] 'some bench'"))
.arg(Arg::from("[BENCH2] 'some bench'"))
.arg(Arg::from("[BENCH3] 'some bench'"))
.arg(Arg::from("[ARGS]... 'some args'"))
.try_get_matches_from(vec!["bench", "foo", "--", "arg1", "arg2", "arg3"]);
assert!(r.is_ok(), "{:?}", r.unwrap_err().kind);
let m = r.unwrap();
let expected_bench1 = Some("foo");
let expected_bench2 = None;
let expected_bench3 = None;
let expected_args = vec!["arg1", "arg2", "arg3"];
assert_eq!(m.value_of("BENCH1"), expected_bench1);
assert_eq!(m.value_of("BENCH2"), expected_bench2);
assert_eq!(m.value_of("BENCH3"), expected_bench3);
assert_eq!(
m.values_of("ARGS").unwrap().collect::<Vec<_>>(),
&*expected_args
);
}
#[test]
fn missing_positional_hyphen_req_error() {
let r = App::new("bench")
.setting(AppSettings::AllowMissingPositional)
.arg(Arg::from("[BENCH1] 'some bench'"))
.arg(Arg::from("<BENCH2> 'some bench'"))
.arg(Arg::from("[ARGS]... 'some args'"))
.try_get_matches_from(vec!["bench", "foo", "--", "arg1", "arg2", "arg3"]);
assert!(r.is_err());
assert_eq!(r.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
}
#[test]
fn issue_1066_allow_leading_hyphen_and_unknown_args() {
let res = App::new("prog")
.global_setting(AppSettings::AllowLeadingHyphen)
.arg(Arg::from("--some-argument"))
.try_get_matches_from(vec!["prog", "hello"]);
assert!(res.is_err());
assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
}
#[test]
fn issue_1066_allow_leading_hyphen_and_unknown_args_no_vals() {
let res = App::new("prog")
.global_setting(AppSettings::AllowLeadingHyphen)
.arg(Arg::from("--some-argument"))
.try_get_matches_from(vec!["prog", "--hello"]);
assert!(res.is_err());
assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
}
#[test]
fn issue_1066_allow_leading_hyphen_and_unknown_args_option() {
let res = App::new("prog")
.global_setting(AppSettings::AllowLeadingHyphen)
.arg(Arg::from("--some-argument=[val]"))
.try_get_matches_from(vec!["prog", "-hello"]);
assert!(res.is_err());
assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
}
#[test]
fn issue_1093_allow_ext_sc() {
let app = App::new("clap-test")
.version("v1.4.8")
.setting(AppSettings::AllowExternalSubcommands);
assert!(utils::compare_output(
app,
"clap-test --help",
ALLOW_EXT_SC,
false
));
}
#[test]
fn allow_ext_sc_when_sc_required() {
let res = App::new("clap-test")
.version("v1.4.8")
.setting(AppSettings::AllowExternalSubcommands)
.setting(AppSettings::SubcommandRequiredElseHelp)
.try_get_matches_from(vec!["clap-test", "external-cmd", "foo"]);
assert!(res.is_ok());
match res.unwrap().subcommand() {
Some((name, args)) => {
assert_eq!(name, "external-cmd");
assert_eq!(args.values_of_lossy(""), Some(vec!["foo".to_string()]));
}
_ => unreachable!(),
}
}
#[test]
fn external_subcommand_looks_like_built_in() {
let res = App::new("cargo")
.version("1.26.0")
.setting(AppSettings::AllowExternalSubcommands)
.subcommand(App::new("install"))
.try_get_matches_from(vec!["cargo", "install-update", "foo"]);
assert!(res.is_ok());
let m = res.unwrap();
match m.subcommand() {
Some((name, args)) => {
assert_eq!(name, "install-update");
assert_eq!(args.values_of_lossy(""), Some(vec!["foo".to_string()]));
}
_ => panic!("external_subcommand didn't work"),
}
}
#[test]
fn aaos_flags() {
// flags
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--flag 'some flag'"))
.try_get_matches_from(vec!["", "--flag", "--flag"]);
assert!(res.is_ok());
let m = res.unwrap();
assert!(m.is_present("flag"));
assert_eq!(m.occurrences_of("flag"), 1);
}
#[test]
fn aaos_flags_mult() {
// flags with multiple
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--flag... 'some flag'"))
.try_get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]);
assert!(res.is_ok());
let m = res.unwrap();
assert!(m.is_present("flag"));
assert_eq!(m.occurrences_of("flag"), 4);
}
#[test]
fn aaos_opts() {
// opts
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--opt [val] 'some option'"))
.try_get_matches_from(vec!["", "--opt=some", "--opt=other"]);
assert!(res.is_ok());
let m = res.unwrap();
assert!(m.is_present("opt"));
assert_eq!(m.occurrences_of("opt"), 1);
assert_eq!(m.value_of("opt"), Some("other"));
}
#[test]
fn aaos_opts_w_other_overrides() {
// opts with other overrides
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--opt [val] 'some option'"))
.arg(Arg::from("--other [val] 'some other option'").overrides_with("opt"))
.try_get_matches_from(vec!["", "--opt=some", "--other=test", "--opt=other"]);
assert!(res.is_ok());
let m = res.unwrap();
assert!(m.is_present("opt"));
assert!(!m.is_present("other"));
assert_eq!(m.occurrences_of("opt"), 1);
assert_eq!(m.value_of("opt"), Some("other"));
}
#[test]
fn aaos_opts_w_other_overrides_rev() {
// opts with other overrides, rev
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--opt [val] 'some option'"))
.arg(Arg::from("--other [val] 'some other option'").overrides_with("opt"))
.try_get_matches_from(vec!["", "--opt=some", "--opt=other", "--other=val"]);
assert!(res.is_ok());
let m = res.unwrap();
assert!(!m.is_present("opt"));
assert!(m.is_present("other"));
assert_eq!(m.value_of("other"), Some("val"));
}
#[test]
fn aaos_opts_w_other_overrides_2() {
// opts with other overrides
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--opt [val] 'some option'").overrides_with("other"))
.arg(Arg::from("--other [val] 'some other option'"))
.try_get_matches_from(vec!["", "--opt=some", "--other=test", "--opt=other"]);
assert!(res.is_ok());
let m = res.unwrap();
assert!(m.is_present("opt"));
assert!(!m.is_present("other"));
assert_eq!(m.occurrences_of("opt"), 1);
assert_eq!(m.value_of("opt"), Some("other"));
}
#[test]
fn aaos_opts_w_other_overrides_rev_2() {
// opts with other overrides, rev
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--opt [val] 'some option'").overrides_with("other"))
.arg(Arg::from("--other [val] 'some other option'"))
.try_get_matches_from(vec!["", "--opt=some", "--opt=other", "--other=val"]);
assert!(res.is_ok());
let m = res.unwrap();
assert!(!m.is_present("opt"));
assert!(m.is_present("other"));
assert_eq!(m.value_of("other"), Some("val"));
}
#[test]
fn aaos_opts_mult() {
// opts with multiple
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(
Arg::from("--opt [val]... 'some option'")
.number_of_values(1)
.takes_value(true)
.use_delimiter(true)
.require_delimiter(true),
)
.try_get_matches_from(vec!["", "--opt=some", "--opt=other", "--opt=one,two"]);
assert!(res.is_ok());
let m = res.unwrap();
assert!(m.is_present("opt"));
assert_eq!(m.occurrences_of("opt"), 3);
assert_eq!(
m.values_of("opt").unwrap().collect::<Vec<_>>(),
&["some", "other", "one", "two"]
);
}
#[test]
fn aaos_opts_mult_req_delims() {
// opts with multiple and require delims
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--opt [val]... 'some option'"))
.try_get_matches_from(vec![
"",
"--opt",
"first",
"overrides",
"--opt",
"some",
"other",
"val",
]);
assert!(res.is_ok());
let m = res.unwrap();
assert!(m.is_present("opt"));
assert_eq!(m.occurrences_of("opt"), 2);
assert_eq!(
m.values_of("opt").unwrap().collect::<Vec<_>>(),
&["first", "overrides", "some", "other", "val"]
);
}
#[test]
fn aaos_pos_mult() {
// opts with multiple
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("[val]... 'some pos'"))
.try_get_matches_from(vec!["", "some", "other", "value"]);
assert!(res.is_ok());
let m = res.unwrap();
assert!(m.is_present("val"));
assert_eq!(m.occurrences_of("val"), 3);
assert_eq!(
m.values_of("val").unwrap().collect::<Vec<_>>(),
&["some", "other", "value"]
);
}
#[test]
fn aaos_option_use_delim_false() {
let m = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--opt [val] 'some option'").use_delimiter(false))
.get_matches_from(vec!["", "--opt=some,other", "--opt=one,two"]);
assert!(m.is_present("opt"));
assert_eq!(m.occurrences_of("opt"), 1);
assert_eq!(
m.values_of("opt").unwrap().collect::<Vec<_>>(),
&["one,two"]
);
}
#[test]
fn nested_help_subcommand_with_global_setting() {
let m = App::new("myprog")
.global_setting(AppSettings::UseLongFormatForHelpSubcommand)
.subcommand(
App::new("test").subcommand(
App::new("nested")
.about("short form about message")
.long_about("long form about message"),
),
);
assert!(utils::compare_output(
m,
"myprog test help nested",
LONG_FORMAT_FOR_NESTED_HELP_SUBCOMMAND,
false
));
}
#[test]
fn single_arg_help_with_long_format_setting() {
let m = App::new("myprog")
.setting(AppSettings::UseLongFormatForHelpSubcommand)
.subcommand(App::new("test"))
.arg(
Arg::new("foo")
.about("short form about message")
.long_about("long form about message"),
);
assert!(utils::compare_output(
m,
"myprog help",
LONG_FORMAT_SINGLE_ARG_HELP_SUBCOMMAND,
false
));
}
#[test]
fn use_long_format_for_help_subcommand_with_setting() {
let m = App::new("myprog")
.setting(AppSettings::UseLongFormatForHelpSubcommand)
.subcommand(
App::new("test").arg(
Arg::new("foo")
.about("short form about message")
.long_about("long form about message"),
),
);
assert!(utils::compare_output(
m,
"myprog help test",
LONG_FORMAT_FOR_HELP_SUBCOMMAND,
false
));
}