mirror of
https://github.com/clap-rs/clap
synced 2024-12-14 06:42:33 +00:00
b184dc001b
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
1131 lines
32 KiB
Rust
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
|
|
));
|
|
}
|