diff --git a/CHANGELOG.md b/CHANGELOG.md index 2df5baf8984..6b22b0d5c6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## 4.0.0 - Upcoming -_gated behind `unstable-v4`_ - ### Breaking Changes - `Error::EmptyValue` replaced with `Error::InvalidValue` @@ -25,6 +23,7 @@ _gated behind `unstable-v4`_ - *(assert)* Always enforce that version is specified when the `ArgAction::Version` is used - *(assert)* Add missing `#[track_caller]`s to make it easier to debug asserts - *(help)* Use `Command::display_name` in the help title rather than `Command::bin_name` +- *(version)* Use `Command::display_name` rather than `Command::bin_name` - *(parser)* Assert on unknown args when using external subcommands (#3703) - *(parser)* Always fill in `""` argument for external subcommands (#3263) - *(derive)* Detect escaped external subcommands that look like built-in subcommands (#3703) diff --git a/Cargo.toml b/Cargo.toml index f27ffa7e83a..ed15fefd981 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -79,8 +79,8 @@ unicode = ["textwrap/unicode-width", "unicase"] # Support for unicode character # In-work features unstable-replace = [] unstable-grouped = [] -# note: this will always enable clap_derive, change this to `clap_derive?/unstable-v4` when MSRV is bigger than 1.60 -unstable-v4 = ["clap_derive/unstable-v4", "deprecated"] +# note: this will always enable clap_derive, change this to `clap_derive?/unstable-v5` when MSRV is bigger than 1.60 +unstable-v5 = ["clap_derive/unstable-v5", "deprecated"] [lib] bench = false diff --git a/Makefile b/Makefile index 3a09164970f..84c24843b6a 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ _FEATURES_minimal = --no-default-features --features "std" _FEATURES_default = _FEATURES_wasm = --features "deprecated derive cargo env unicode unstable-replace unstable-grouped" _FEATURES_full = --features "deprecated derive cargo env unicode unstable-replace unstable-grouped wrap_help" -_FEATURES_next = ${_FEATURES_full} --features unstable-v4 +_FEATURES_next = ${_FEATURES_full} --features unstable-v5 _FEATURES_debug = ${_FEATURES_full} --features debug _FEATURES_release = ${_FEATURES_full} --release diff --git a/clap_derive/Cargo.toml b/clap_derive/Cargo.toml index e2fc77d8766..2b4ae88f2a4 100644 --- a/clap_derive/Cargo.toml +++ b/clap_derive/Cargo.toml @@ -49,6 +49,6 @@ proc-macro-error = "1" [features] default = [] debug = [] -unstable-v4 = ["deprecated"] +unstable-v5 = ["deprecated"] deprecated = [] raw-deprecated = ["deprecated"] diff --git a/clap_derive/src/attrs.rs b/clap_derive/src/attrs.rs index b9e01b0c827..da38c01630b 100644 --- a/clap_derive/src/attrs.rs +++ b/clap_derive/src/attrs.rs @@ -750,16 +750,10 @@ impl Attrs { quote!( #(#next_help_heading)* #(#help_heading)* ) } - #[cfg(feature = "unstable-v4")] pub fn id(&self) -> TokenStream { self.name.clone().raw() } - #[cfg(not(feature = "unstable-v4"))] - pub fn id(&self) -> TokenStream { - self.cased_name() - } - pub fn cased_name(&self) -> TokenStream { self.name.clone().translate(*self.casing) } @@ -780,7 +774,7 @@ impl Attrs { let inner_type = inner_type(field_type); let span = action.span(); default_value_parser(inner_type, span) - } else if !self.ignore_parser() || cfg!(not(feature = "unstable-v4")) { + } else if !self.ignore_parser() { self.parser(field_type).value_parser() } else { let inner_type = inner_type(field_type); @@ -802,7 +796,7 @@ impl Attrs { if let Some(value_parser) = self.value_parser.as_ref() { let span = value_parser.span(); default_action(field_type, span) - } else if !self.ignore_parser() || cfg!(not(feature = "unstable-v4")) { + } else if !self.ignore_parser() { self.parser(field_type).action() } else { let span = self @@ -815,16 +809,10 @@ impl Attrs { }) } - #[cfg(feature = "unstable-v4")] pub fn ignore_parser(&self) -> bool { self.parser.is_none() } - #[cfg(not(feature = "unstable-v4"))] - pub fn ignore_parser(&self) -> bool { - self.value_parser.is_some() || self.action.is_some() - } - pub fn explicit_parser(&self) -> bool { self.parser.is_some() } @@ -1200,7 +1188,6 @@ pub enum Name { } impl Name { - #[cfg(feature = "unstable-v4")] pub fn raw(self) -> TokenStream { match self { Name::Assigned(tokens) => tokens, diff --git a/clap_derive/src/derives/subcommand.rs b/clap_derive/src/derives/subcommand.rs index 07bdce5ec1d..daf72d836f7 100644 --- a/clap_derive/src/derives/subcommand.rs +++ b/clap_derive/src/derives/subcommand.rs @@ -484,17 +484,9 @@ fn gen_from_arg_matches( Unnamed(..) => abort_call_site!("{}: tuple enums are not supported", variant.ident), }; - if cfg!(feature = "unstable-v4") { - quote! { - if #sub_name == #subcommand_name_var && !#sub_arg_matches_var.contains_id("") { - return ::std::result::Result::Ok(#name :: #variant_name #constructor_block) - } - } - } else { - quote! { - if #sub_name == #subcommand_name_var { - return ::std::result::Result::Ok(#name :: #variant_name #constructor_block) - } + quote! { + if #sub_name == #subcommand_name_var && !#sub_arg_matches_var.contains_id("") { + return ::std::result::Result::Ok(#name :: #variant_name #constructor_block) } } }); @@ -528,7 +520,7 @@ fn gen_from_arg_matches( .chain( #sub_arg_matches_var .remove_many::<#str_ty>("") - .into_iter().flatten() // `""` isn't present, bug in `unstable-v4` + .unwrap() .map(#str_ty::from) ) .collect::<::std::vec::Vec<_>>() diff --git a/examples/git-derive.md b/examples/git-derive.md index aa1ca6d9dfa..edf5849d0ac 100644 --- a/examples/git-derive.md +++ b/examples/git-derive.md @@ -40,7 +40,7 @@ SUBCOMMANDS: stash $ git-derive help add -git-derive[EXE]-add +git-add adds things USAGE: @@ -58,7 +58,7 @@ A basic argument: ```console $ git-derive add ? failed -git-derive[EXE]-add +git-add adds things USAGE: @@ -78,7 +78,7 @@ Adding ["Cargo.toml", "Cargo.lock"] Default subcommand: ```console $ git-derive stash -h -git-derive[EXE]-stash +git-stash USAGE: git-derive[EXE] stash [OPTIONS] @@ -95,7 +95,7 @@ SUBCOMMANDS: push $ git-derive stash push -h -git-derive[EXE]-stash-push +git-stash-push USAGE: git-derive[EXE] stash push [OPTIONS] @@ -105,7 +105,7 @@ OPTIONS: -m, --message $ git-derive stash pop -h -git-derive[EXE]-stash-pop +git-stash-pop USAGE: git-derive[EXE] stash pop [STASH] diff --git a/examples/git.md b/examples/git.md index 9e413415a4b..d836775f803 100644 --- a/examples/git.md +++ b/examples/git.md @@ -38,7 +38,7 @@ SUBCOMMANDS: stash $ git help add -git[EXE]-add +git-add adds things USAGE: @@ -56,7 +56,7 @@ A basic argument: ```console $ git add ? failed -git[EXE]-add +git-add adds things USAGE: @@ -76,7 +76,7 @@ Adding ["Cargo.toml", "Cargo.lock"] Default subcommand: ```console $ git stash -h -git[EXE]-stash +git-stash USAGE: git[EXE] stash [OPTIONS] @@ -93,7 +93,7 @@ SUBCOMMANDS: push $ git stash push -h -git[EXE]-stash-push +git-stash-push USAGE: git[EXE] stash push [OPTIONS] @@ -103,7 +103,7 @@ OPTIONS: -m, --message $ git stash pop -h -git[EXE]-stash-pop +git-stash-pop USAGE: git[EXE] stash pop [STASH] diff --git a/examples/pacman.md b/examples/pacman.md index b8ddd09d91f..e81594dfdff 100644 --- a/examples/pacman.md +++ b/examples/pacman.md @@ -52,7 +52,7 @@ SUBCOMMANDS: sync -S --sync Synchronize packages. $ pacman -S -h -pacman[EXE]-sync +pacman-sync Synchronize packages. USAGE: diff --git a/examples/tutorial_builder/03_04_subcommands.md b/examples/tutorial_builder/03_04_subcommands.md index 8f9efa911bf..6c94e35a001 100644 --- a/examples/tutorial_builder/03_04_subcommands.md +++ b/examples/tutorial_builder/03_04_subcommands.md @@ -15,7 +15,7 @@ SUBCOMMANDS: help Print this message or the help of the given subcommand(s) $ 03_04_subcommands help add -03_04_subcommands[EXE]-add [..] +clap-add 3.2.14 Adds files to myapp USAGE: @@ -59,6 +59,6 @@ $ 03_04_subcommands --version clap [..] $ 03_04_subcommands add --version -03_04_subcommands[EXE]-add [..] +clap-add [..] ``` diff --git a/examples/tutorial_derive/03_04_subcommands.md b/examples/tutorial_derive/03_04_subcommands.md index 8f3e7a8943c..41f449b2ea1 100644 --- a/examples/tutorial_derive/03_04_subcommands.md +++ b/examples/tutorial_derive/03_04_subcommands.md @@ -15,7 +15,7 @@ SUBCOMMANDS: help Print this message or the help of the given subcommand(s) $ 03_04_subcommands help add -03_04_subcommands[EXE]-add [..] +clap-add 3.2.14 Adds files to myapp USAGE: @@ -59,6 +59,6 @@ $ 03_04_subcommands --version clap [..] $ 03_04_subcommands add --version -03_04_subcommands[EXE]-add [..] +clap-add [..] ``` diff --git a/src/_features.rs b/src/_features.rs index b1977308ff2..518978b835f 100644 --- a/src/_features.rs +++ b/src/_features.rs @@ -23,4 +23,4 @@ //! //! * **unstable-replace**: Enable [`Command::replace`](https://github.com/clap-rs/clap/issues/2836) //! * **unstable-grouped**: Enable [`ArgMatches::grouped_values_of`](https://github.com/clap-rs/clap/issues/2924) -//! * **unstable-v4**: Preview features which will be stable on the v4.0 release +//! * **unstable-v5**: Preview features which will be stable on the v5.0 release diff --git a/src/builder/arg.rs b/src/builder/arg.rs index 528d5b2009c..9318e82b795 100644 --- a/src/builder/arg.rs +++ b/src/builder/arg.rs @@ -186,14 +186,7 @@ impl<'help> Arg<'help> { #[inline] #[must_use] pub fn long(mut self, l: &'help str) -> Self { - #[cfg(feature = "unstable-v4")] - { - self.long = Some(l); - } - #[cfg(not(feature = "unstable-v4"))] - { - self.long = Some(l.trim_start_matches(|c| c == '-')); - } + self.long = Some(l); self } diff --git a/src/builder/command.rs b/src/builder/command.rs index 4ecb7daa7f8..5871c62f3d3 100644 --- a/src/builder/command.rs +++ b/src/builder/command.rs @@ -2273,14 +2273,7 @@ impl<'help> Command<'help> { /// [`Arg::long`]: Arg::long() #[must_use] pub fn long_flag(mut self, long: &'help str) -> Self { - #[cfg(feature = "unstable-v4")] - { - self.long_flag = Some(long); - } - #[cfg(not(feature = "unstable-v4"))] - { - self.long_flag = Some(long.trim_start_matches(|c| c == '-')); - } + self.long_flag = Some(long); self } @@ -4398,16 +4391,8 @@ To change `help`s short, call `cmd.arg(Arg::new(\"help\")...)`.", } else { self.version.or(self.long_version).unwrap_or("") }; - if let Some(bn) = self.bin_name.as_ref() { - if bn.contains(' ') { - // In case we're dealing with subcommands i.e. git mv is translated to git-mv - format!("{} {}\n", bn.replace(' ', "-"), ver) - } else { - format!("{} {}\n", &self.name[..], ver) - } - } else { - format!("{} {}\n", &self.name[..], ver) - } + let display_name = self.get_display_name().unwrap_or_else(|| self.get_name()); + format!("{} {}\n", display_name, ver) } pub(crate) fn format_group(&self, g: &Id) -> String { @@ -4674,10 +4659,9 @@ impl<'help> Command<'help> { v.long_help.is_some() || v.is_hide_long_help_set() || v.is_hide_short_help_set() - || cfg!(feature = "unstable-v4") - && v.get_possible_values() - .iter() - .any(PossibleValue::should_show_help) + || v.get_possible_values() + .iter() + .any(PossibleValue::should_show_help) }; // Subcommands aren't checked because we prefer short help for them, deferring to diff --git a/src/builder/debug_asserts.rs b/src/builder/debug_asserts.rs index 5d13ac27e56..a555ffa76f0 100644 --- a/src/builder/debug_asserts.rs +++ b/src/builder/debug_asserts.rs @@ -27,9 +27,6 @@ pub(crate) fn assert_app(cmd: &Command) { .get_arguments() .filter(|x| { let action_set = matches!(x.get_action(), ArgAction::Version); - #[cfg(not(feature = "unstable-v4"))] - let provider_set = matches!(x.provider, ArgProvider::GeneratedMutated); - #[cfg(feature = "unstable-v4")] let provider_set = matches!( x.provider, ArgProvider::User | ArgProvider::GeneratedMutated @@ -54,10 +51,7 @@ pub(crate) fn assert_app(cmd: &Command) { } if let Some(l) = sc.get_long_flag().as_ref() { - #[cfg(feature = "unstable-v4")] - { - assert!(!l.starts_with('-'), "Command {}: long_flag {:?} must not start with a `-`, that will be handled by the parser", sc.get_name(), l); - } + assert!(!l.starts_with('-'), "Command {}: long_flag {:?} must not start with a `-`, that will be handled by the parser", sc.get_name(), l); long_flags.push(Flag::Command(format!("--{}", l), sc.get_name())); } @@ -85,10 +79,7 @@ pub(crate) fn assert_app(cmd: &Command) { } if let Some(l) = arg.long.as_ref() { - #[cfg(feature = "unstable-v4")] - { - assert!(!l.starts_with('-'), "Argument {}: long {:?} must not start with a `-`, that will be handled by the parser", arg.name, l); - } + assert!(!l.starts_with('-'), "Argument {}: long {:?} must not start with a `-`, that will be handled by the parser", arg.name, l); long_flags.push(Flag::Arg(format!("--{}", l), &*arg.name)); } @@ -161,14 +152,11 @@ pub(crate) fn assert_app(cmd: &Command) { } for req in &arg.r_ifs { - #[cfg(feature = "unstable-v4")] - { - assert!( - !arg.is_required_set(), - "Argument {}: `required` conflicts with `required_if_eq*`", - arg.name - ); - } + assert!( + !arg.is_required_set(), + "Argument {}: `required` conflicts with `required_if_eq*`", + arg.name + ); assert!( cmd.id_exists(&req.0), "Command {}: Argument or group '{:?}' specified in 'required_if_eq*' for '{}' does not exist", @@ -179,14 +167,11 @@ pub(crate) fn assert_app(cmd: &Command) { } for req in &arg.r_ifs_all { - #[cfg(feature = "unstable-v4")] - { - assert!( - !arg.is_required_set(), - "Argument {}: `required` conflicts with `required_if_eq_all`", - arg.name - ); - } + assert!( + !arg.is_required_set(), + "Argument {}: `required` conflicts with `required_if_eq_all`", + arg.name + ); assert!( cmd.id_exists(&req.0), "Command {}: Argument or group '{:?}' specified in 'required_if_eq_all' for '{}' does not exist", @@ -197,14 +182,11 @@ pub(crate) fn assert_app(cmd: &Command) { } for req in &arg.r_unless { - #[cfg(feature = "unstable-v4")] - { - assert!( - !arg.is_required_set(), - "Argument {}: `required` conflicts with `required_unless*`", - arg.name - ); - } + assert!( + !arg.is_required_set(), + "Argument {}: `required` conflicts with `required_unless*`", + arg.name + ); assert!( cmd.id_exists(req), "Command {}: Argument or group '{:?}' specified in 'required_unless*' for '{}' does not exist", @@ -215,14 +197,11 @@ pub(crate) fn assert_app(cmd: &Command) { } for req in &arg.r_unless_all { - #[cfg(feature = "unstable-v4")] - { - assert!( - !arg.is_required_set(), - "Argument {}: `required` conflicts with `required_unless*`", - arg.name - ); - } + assert!( + !arg.is_required_set(), + "Argument {}: `required` conflicts with `required_unless*`", + arg.name + ); assert!( cmd.id_exists(req), "Command {}: Argument or group '{:?}' specified in 'required_unless*' for '{}' does not exist", @@ -680,16 +659,13 @@ fn assert_arg(arg: &Arg) { ); } - #[cfg(feature = "unstable-v4")] - { - let num_vals = arg.get_num_vals().unwrap_or(usize::MAX); - let num_val_names = arg.get_value_names().unwrap_or(&[]).len(); - if num_vals < num_val_names { - panic!( - "Argument {}: Too many value names ({}) compared to number_of_values ({})", - arg.name, num_val_names, num_vals - ); - } + let num_vals = arg.get_num_vals().unwrap_or(usize::MAX); + let num_val_names = arg.get_value_names().unwrap_or(&[]).len(); + if num_vals < num_val_names { + panic!( + "Argument {}: Too many value names ({}) compared to number_of_values ({})", + arg.name, num_val_names, num_vals + ); } assert_arg_flags(arg); diff --git a/src/builder/possible_value.rs b/src/builder/possible_value.rs index 3b5ea906add..9c55ff1daa1 100644 --- a/src/builder/possible_value.rs +++ b/src/builder/possible_value.rs @@ -153,7 +153,6 @@ impl<'help> PossibleValue<'help> { /// Get the help specified for this argument, if any and the argument /// value is not hidden #[inline] - #[cfg(feature = "unstable-v4")] pub(crate) fn get_visible_help(&self) -> Option<&'help str> { if !self.hide { self.help diff --git a/src/output/help.rs b/src/output/help.rs index 99081aff7e0..cb22dc69e8d 100644 --- a/src/output/help.rs +++ b/src/output/help.rs @@ -28,7 +28,6 @@ pub(crate) struct Help<'help, 'cmd, 'writer> { // Public Functions impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { - #[cfg(feature = "unstable-v4")] const DEFAULT_TEMPLATE: &'static str = "\ {before-help}{name} {version}\n\ {author-with-newline}{about-with-newline}\n\ @@ -36,27 +35,12 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { \n\ {all-args}{after-help}\ "; - #[cfg(not(feature = "unstable-v4"))] - const DEFAULT_TEMPLATE: &'static str = "\ - {before-help}{bin} {version}\n\ - {author-with-newline}{about-with-newline}\n\ - {usage-heading}\n {usage}\n\ - \n\ - {all-args}{after-help}\ - "; - #[cfg(feature = "unstable-v4")] const DEFAULT_NO_ARGS_TEMPLATE: &'static str = "\ {before-help}{name} {version}\n\ {author-with-newline}{about-with-newline}\n\ {usage-heading}\n {usage}{after-help}\ "; - #[cfg(not(feature = "unstable-v4"))] - const DEFAULT_NO_ARGS_TEMPLATE: &'static str = "\ - {before-help}{bin} {version}\n\ - {author-with-newline}{about-with-newline}\n\ - {usage-heading}\n {usage}{after-help}\ - "; /// Create a new `Help` instance. pub(crate) fn new( @@ -477,7 +461,6 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { self.none(part)?; } - #[cfg(feature = "unstable-v4")] if let Some(arg) = arg { const DASH_SPACE: usize = "- ".len(); const COLON_SPACE: usize = ": ".len(); @@ -663,9 +646,7 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { let possible_vals = a.get_possible_values(); if !(a.is_hide_possible_values_set() || possible_vals.is_empty() - || cfg!(feature = "unstable-v4") - && self.use_long - && possible_vals.iter().any(PossibleValue::should_show_help)) + || self.use_long && possible_vals.iter().any(PossibleValue::should_show_help)) { debug!("Help::spec_vals: Found possible vals...{:?}", possible_vals); diff --git a/src/parser/arg_matcher.rs b/src/parser/arg_matcher.rs index 22087e72201..08a3815327e 100644 --- a/src/parser/arg_matcher.rs +++ b/src/parser/arg_matcher.rs @@ -31,16 +31,6 @@ impl ArgMatcher { }, #[cfg(debug_assertions)] valid_subcommands: _cmd.get_subcommands().map(|sc| sc.get_id()).collect(), - // HACK: Allow an external subcommand's ArgMatches be a stand-in for any ArgMatches - // since users can't detect it and avoid the asserts. - // - // See clap-rs/clap#3263 - #[cfg(debug_assertions)] - #[cfg(not(feature = "unstable-v4"))] - disable_asserts: _cmd.is_allow_external_subcommands_set(), - #[cfg(debug_assertions)] - #[cfg(feature = "unstable-v4")] - disable_asserts: false, ..Default::default() }, pending: None, diff --git a/src/parser/matches/arg_matches.rs b/src/parser/matches/arg_matches.rs index 50e0da2d67d..a60bf7d8459 100644 --- a/src/parser/matches/arg_matches.rs +++ b/src/parser/matches/arg_matches.rs @@ -67,8 +67,6 @@ pub struct ArgMatches { pub(crate) valid_args: Vec, #[cfg(debug_assertions)] pub(crate) valid_subcommands: Vec, - #[cfg(debug_assertions)] - pub(crate) disable_asserts: bool, pub(crate) args: IndexMap, pub(crate) subcommand: Option>, } @@ -685,7 +683,7 @@ impl ArgMatches { #[cfg(debug_assertions)] { let id = Id::from(_id); - self.disable_asserts || id == Id::empty_hash() || self.valid_args.contains(&id) + id == Id::empty_hash() || self.valid_args.contains(&id) } #[cfg(not(debug_assertions))] { @@ -890,7 +888,7 @@ impl ArgMatches { #[cfg(debug_assertions)] { let id = Id::from(_id); - self.disable_asserts || id == Id::empty_hash() || self.valid_subcommands.contains(&id) + id == Id::empty_hash() || self.valid_subcommands.contains(&id) } #[cfg(not(debug_assertions))] { @@ -1066,7 +1064,7 @@ impl ArgMatches { fn verify_arg(&self, _arg: &Id) -> Result<(), MatchesError> { #[cfg(debug_assertions)] { - if self.disable_asserts || *_arg == Id::empty_hash() || self.valid_args.contains(_arg) { + if *_arg == Id::empty_hash() || self.valid_args.contains(_arg) { } else if self.valid_subcommands.contains(_arg) { debug!( "Subcommand `{:?}` used where an argument or group name was expected.", @@ -1091,7 +1089,7 @@ impl ArgMatches { fn get_arg(&self, arg: &Id) -> Option<&MatchedArg> { #[cfg(debug_assertions)] { - if self.disable_asserts || *arg == Id::empty_hash() || self.valid_args.contains(arg) { + if *arg == Id::empty_hash() || self.valid_args.contains(arg) { } else if self.valid_subcommands.contains(arg) { panic!( "Subcommand `{:?}` used where an argument or group name was expected.", @@ -1115,10 +1113,7 @@ impl ArgMatches { fn get_subcommand(&self, id: &Id) -> Option<&SubCommand> { #[cfg(debug_assertions)] { - if self.disable_asserts - || *id == Id::empty_hash() - || self.valid_subcommands.contains(id) - { + if *id == Id::empty_hash() || self.valid_subcommands.contains(id) { } else if self.valid_args.contains(id) { panic!( "Argument or group `{:?}` used where a subcommand name was expected.", diff --git a/src/parser/parser.rs b/src/parser/parser.rs index ad2bc6e9ca6..3821f9d63fd 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -431,9 +431,7 @@ impl<'help, 'cmd> Parser<'help, 'cmd> { // Collect the external subcommand args let mut sc_m = ArgMatcher::new(self.cmd); - if cfg!(feature = "unstable-v4") || !raw_args.is_end(&args_cursor) { - sc_m.start_occurrence_of_external(self.cmd); - } + sc_m.start_occurrence_of_external(self.cmd); for raw_val in raw_args.remaining(&mut args_cursor) { let val = external_parser.parse_ref(self.cmd, None, raw_val)?; diff --git a/tests/builder/app_settings.rs b/tests/builder/app_settings.rs index 4c87ac41c4d..9cd549a6b53 100644 --- a/tests/builder/app_settings.rs +++ b/tests/builder/app_settings.rs @@ -890,27 +890,6 @@ fn issue_1093_allow_ext_sc() { } #[test] -#[cfg(not(feature = "unstable-v4"))] -fn allow_ext_sc_empty_args() { - let res = Command::new("clap-test") - .version("v1.4.8") - .allow_external_subcommands(true) - .allow_invalid_utf8_for_external_subcommands(true) - .try_get_matches_from(vec!["clap-test", "external-cmd"]); - - assert!(res.is_ok(), "{}", res.unwrap_err()); - - match res.unwrap().subcommand() { - Some((name, args)) => { - assert_eq!(name, "external-cmd"); - assert!(args.get_many::("").is_none()); - } - _ => unreachable!(), - } -} - -#[test] -#[cfg(feature = "unstable-v4")] fn allow_ext_sc_empty_args() { let res = Command::new("clap-test") .version("v1.4.8") diff --git a/tests/builder/flags.rs b/tests/builder/flags.rs index 3b12941bdac..8715b1b50a9 100644 --- a/tests/builder/flags.rs +++ b/tests/builder/flags.rs @@ -190,21 +190,6 @@ For more information try --help } #[test] -#[cfg(not(feature = "unstable-v4"))] -fn leading_dash_stripped() { - let cmd = Command::new("mycat").arg( - Arg::new("filename") - .long("--filename") - .action(ArgAction::SetTrue), - ); - let matches = cmd.try_get_matches_from(["mycat", "--filename"]).unwrap(); - assert!(*matches - .get_one::("filename") - .expect("defaulted by clap")); -} - -#[test] -#[cfg(feature = "unstable-v4")] #[cfg(debug_assertions)] #[should_panic = "Argument filename: long \"--filename\" must not start with a `-`, that will be handled by the parser"] fn leading_dash_stripped() { diff --git a/tests/builder/help.rs b/tests/builder/help.rs index 26ad3b546c2..3262465d8a9 100644 --- a/tests/builder/help.rs +++ b/tests/builder/help.rs @@ -942,7 +942,6 @@ OPTIONS: #[test] #[cfg(all(feature = "wrap_help"))] fn possible_value_wrapped_help() { - #[cfg(feature = "unstable-v4")] static WRAPPED_HELP: &str = "test USAGE: @@ -971,18 +970,6 @@ OPTIONS: - name: Short enough help message with no wrapping - second: short help "; - #[cfg(not(feature = "unstable-v4"))] - static WRAPPED_HELP: &str = r#"test - -USAGE: - test [OPTIONS] - -OPTIONS: - -h, --help Print help information - --possible-values [possible values: short_name, second] - --possible-values-with-new-line [possible values: "long enough name to trigger new line", second] - --possible-values-without-new-line [possible values: name, second] -"#; let cmd = Command::new("test") .term_width(67) .arg( @@ -1100,7 +1087,6 @@ fn hide_single_possible_val() { #[test] fn possible_vals_with_help() { - #[cfg(feature = "unstable-v4")] static POS_VALS_HELP: &str = "ctest 0.1 USAGE: @@ -1122,18 +1108,6 @@ OPTIONS: -V, --version Print version information -"; - #[cfg(not(feature = "unstable-v4"))] - static POS_VALS_HELP: &str = "ctest 0.1 - -USAGE: - ctest [OPTIONS] - -OPTIONS: - -c, --cafe A coffeehouse, coffee shop, or café. - -h, --help Print help information - -p, --pos Some vals [possible values: fast, slow] - -V, --version Print version information "; let app = Command::new("ctest") .version("0.1") @@ -2603,22 +2577,6 @@ OPTIONS: } #[test] -#[cfg(not(feature = "unstable-v4"))] -fn too_many_value_names_panics() { - Command::new("test") - .arg( - Arg::new("foo") - .long("foo") - .required(true) - .takes_value(true) - .number_of_values(1) - .value_names(&["one", "two"]), - ) - .debug_assert() -} - -#[test] -#[cfg(feature = "unstable-v4")] #[should_panic = "Argument foo: Too many value names (2) compared to number_of_values (1)"] fn too_many_value_names_panics() { Command::new("test") diff --git a/tests/derive/arguments.rs b/tests/derive/arguments.rs index 0d3f0b1e262..57c5866d4ee 100644 --- a/tests/derive/arguments.rs +++ b/tests/derive/arguments.rs @@ -19,7 +19,6 @@ use clap::Parser; fn required_argument() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_parser)] arg: i32, } assert_eq!( @@ -34,7 +33,7 @@ fn required_argument() { fn argument_with_default() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_parser, default_value = "42")] + #[clap(default_value = "42")] arg: i32, } assert_eq!( @@ -49,7 +48,6 @@ fn argument_with_default() { fn auto_value_name() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_parser)] my_special_arg: i32, } @@ -69,7 +67,7 @@ fn auto_value_name() { fn explicit_value_name() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_parser, value_name = "BROWNIE_POINTS")] + #[clap(value_name = "BROWNIE_POINTS")] my_special_arg: i32, } @@ -90,7 +88,6 @@ fn explicit_value_name() { fn option_type_is_optional() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_parser)] arg: Option, } assert_eq!( @@ -105,7 +102,6 @@ fn option_type_is_optional() { fn vec_type_is_multiple_values() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_parser)] arg: Vec, } assert_eq!( diff --git a/tests/derive/basic.rs b/tests/derive/basic.rs index f32d17791ae..d2e1ca9001a 100644 --- a/tests/derive/basic.rs +++ b/tests/derive/basic.rs @@ -18,7 +18,7 @@ use clap::Parser; fn basic() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short = 'a', long = "arg", value_parser)] + #[clap(short = 'a', long = "arg")] arg: i32, } assert_eq!( @@ -31,7 +31,7 @@ fn basic() { fn update_basic() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short = 'a', long = "arg", value_parser)] + #[clap(short = 'a', long = "arg")] single_value: i32, } diff --git a/tests/derive/boxed.rs b/tests/derive/boxed.rs index 0af81f6fcfd..03efbe9c551 100644 --- a/tests/derive/boxed.rs +++ b/tests/derive/boxed.rs @@ -16,7 +16,6 @@ enum Sub { #[derive(Args, PartialEq, Debug)] struct Ext { - #[clap(value_parser)] arg: u32, } diff --git a/tests/derive/custom_string_parsers.rs b/tests/derive/custom_string_parsers.rs index f5d5aece0ad..4c6f3d0f134 100644 --- a/tests/derive/custom_string_parsers.rs +++ b/tests/derive/custom_string_parsers.rs @@ -21,19 +21,19 @@ use std::path::PathBuf; #[derive(Parser, PartialEq, Debug)] struct PathOpt { - #[clap(short, long, value_parser)] + #[clap(short, long)] path: PathBuf, - #[clap(short, default_value = "../", value_parser)] + #[clap(short, default_value = "../")] default_path: PathBuf, - #[clap(short, value_parser, multiple_occurrences(true))] + #[clap(short, multiple_occurrences(true))] vector_path: Vec, - #[clap(short, value_parser)] + #[clap(short)] option_path_1: Option, - #[clap(short = 'q', value_parser)] + #[clap(short = 'q')] option_path_2: Option, } @@ -134,10 +134,10 @@ struct DefaultedOpt { #[clap(short, parse(from_str))] bytes: Bytes, - #[clap(short, value_parser)] + #[clap(short)] integer: u64, - #[clap(short, value_parser)] + #[clap(short)] path: PathBuf, } diff --git a/tests/derive/default_value.rs b/tests/derive/default_value.rs index 6a78f8d6b75..db2b7838014 100644 --- a/tests/derive/default_value.rs +++ b/tests/derive/default_value.rs @@ -1,5 +1,3 @@ -use std::path::PathBuf; - use clap::{CommandFactory, Parser}; use crate::utils; @@ -8,7 +6,7 @@ use crate::utils; fn default_value() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_parser, default_value = "3")] + #[clap(default_value = "3")] arg: i32, } assert_eq!(Opt { arg: 3 }, Opt::try_parse_from(&["test"]).unwrap()); @@ -22,7 +20,7 @@ fn default_value() { fn default_value_t() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_parser, default_value_t = 3)] + #[clap(default_value_t = 3)] arg: i32, } assert_eq!(Opt { arg: 3 }, Opt::try_parse_from(&["test"]).unwrap()); @@ -36,7 +34,7 @@ fn default_value_t() { fn auto_default_value_t() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_parser, default_value_t)] + #[clap(default_value_t)] arg: i32, } assert_eq!(Opt { arg: 0 }, Opt::try_parse_from(&["test"]).unwrap()); @@ -46,37 +44,13 @@ fn auto_default_value_t() { assert!(help.contains("[default: 0]")); } -#[test] -fn default_value_os_t() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_parser, default_value_os_t = PathBuf::from("abc.def"))] - arg: PathBuf, - } - assert_eq!( - Opt { - arg: PathBuf::from("abc.def") - }, - Opt::try_parse_from(&["test"]).unwrap() - ); - assert_eq!( - Opt { - arg: PathBuf::from("ghi") - }, - Opt::try_parse_from(&["test", "ghi"]).unwrap() - ); - - let help = utils::get_long_help::(); - assert!(help.contains("[default: abc.def]")); -} - #[test] fn detect_os_variant() { #![allow(unused_parens)] // needed for `as_ref` call #[derive(clap::Parser)] pub struct Options { - #[clap(value_parser, default_value_os = ("123".as_ref()))] + #[clap(default_value_os = ("123".as_ref()))] x: String, } Options::command().debug_assert(); diff --git a/tests/derive/doc_comments_help.rs b/tests/derive/doc_comments_help.rs index e6aab515ce8..bfe152a6102 100644 --- a/tests/derive/doc_comments_help.rs +++ b/tests/derive/doc_comments_help.rs @@ -23,7 +23,7 @@ fn doc_comments() { struct LoremIpsum { /// Fooify a bar /// and a baz - #[clap(short, long, action)] + #[clap(short, long)] foo: bool, } @@ -39,12 +39,7 @@ fn help_is_better_than_comments() { #[clap(name = "lorem-ipsum", about = "Dolor sit amet")] struct LoremIpsum { /// Fooify a bar - #[clap( - short, - long, - help = "DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES", - action - )] + #[clap(short, long, help = "DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES")] foo: bool, } @@ -76,11 +71,11 @@ fn field_long_doc_comment_both_help_long_help() { /// Dot is removed from multiline comments. /// /// Long help - #[clap(long, action)] + #[clap(long)] foo: bool, /// Dot is removed from one short comment. - #[clap(long, action)] + #[clap(long)] bar: bool, } @@ -111,7 +106,7 @@ fn top_long_doc_comment_both_help_long_help() { /// /// Or something else Foo { - #[clap(value_parser, help = "foo")] + #[clap(help = "foo")] bars: String, }, } @@ -146,7 +141,7 @@ fn verbatim_doc_comment() { #[derive(Parser, Debug)] #[clap(verbatim_doc_comment)] struct SeeFigure1 { - #[clap(long, action)] + #[clap(long)] foo: bool, } @@ -176,10 +171,10 @@ fn verbatim_doc_comment_field() { #[derive(Parser, Debug)] struct Command { /// This help ends in a period. - #[clap(long, verbatim_doc_comment, action)] + #[clap(long, verbatim_doc_comment)] foo: bool, /// This help does not end in a period. - #[clap(long, action)] + #[clap(long)] bar: bool, } @@ -196,7 +191,7 @@ fn multiline_separates_default() { /// Multiline /// /// Doc comment - #[clap(long, default_value = "x", value_parser)] + #[clap(long, default_value = "x")] x: String, } @@ -234,10 +229,7 @@ fn doc_comment_about_handles_both_abouts() { /// Sub doc comment body #[derive(Parser, PartialEq, Eq, Debug)] pub enum Sub { - Compress { - #[clap(value_parser)] - output: String, - }, + Compress { output: String }, } let cmd = Opts::command(); diff --git a/tests/derive/explicit_name_no_renaming.rs b/tests/derive/explicit_name_no_renaming.rs index 15402e85ab4..dcdbc3820c7 100644 --- a/tests/derive/explicit_name_no_renaming.rs +++ b/tests/derive/explicit_name_no_renaming.rs @@ -6,7 +6,7 @@ use clap::Parser; fn explicit_short_long_no_rename() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short = '.', long = ".foo", value_parser)] + #[clap(short = '.', long = ".foo")] foo: String, } @@ -27,7 +27,7 @@ fn explicit_short_long_no_rename() { fn explicit_name_no_rename() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(name = ".options", value_parser)] + #[clap(name = ".options")] foo: String, } diff --git a/tests/derive/flags.rs b/tests/derive/flags.rs index d8e55290d0a..02bcc45b478 100644 --- a/tests/derive/flags.rs +++ b/tests/derive/flags.rs @@ -20,7 +20,7 @@ use clap::Parser; fn bool_type_is_flag() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, long, action)] + #[clap(short, long)] alice: bool, } @@ -113,7 +113,7 @@ fn non_bool_type_flag() { fn mixed_type_flags() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, long, action)] + #[clap(short, long)] alice: bool, #[clap(short, long, action = clap::ArgAction::Count)] bob: u8, @@ -181,7 +181,6 @@ fn ignore_qualified_bool_type() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(action)] arg: inner::bool, } diff --git a/tests/derive/flatten.rs b/tests/derive/flatten.rs index df451265baa..77561997bd6 100644 --- a/tests/derive/flatten.rs +++ b/tests/derive/flatten.rs @@ -20,7 +20,6 @@ use clap::{Args, Parser, Subcommand}; fn flatten() { #[derive(Args, PartialEq, Debug)] struct Common { - #[clap(value_parser)] arg: i32, } @@ -45,7 +44,6 @@ fn flatten() { fn flatten_twice() { #[derive(Args, PartialEq, Debug)] struct Common { - #[clap(value_parser)] arg: i32, } @@ -64,13 +62,12 @@ fn flatten_twice() { fn flatten_in_subcommand() { #[derive(Args, PartialEq, Debug)] struct Common { - #[clap(value_parser)] arg: i32, } #[derive(Args, PartialEq, Debug)] struct Add { - #[clap(short, action)] + #[clap(short)] interactive: bool, #[clap(flatten)] common: Common, @@ -79,7 +76,7 @@ fn flatten_in_subcommand() { #[derive(Parser, PartialEq, Debug)] enum Opt { Fetch { - #[clap(short, action)] + #[clap(short)] all: bool, #[clap(flatten)] common: Common, @@ -108,7 +105,6 @@ fn flatten_in_subcommand() { fn update_args_with_flatten() { #[derive(Args, PartialEq, Debug)] struct Common { - #[clap(value_parser)] arg: i32, } @@ -138,15 +134,13 @@ enum BaseCli { #[derive(Args, PartialEq, Debug)] struct Command1 { - #[clap(value_parser)] arg1: i32, - #[clap(value_parser)] + arg2: i32, } #[derive(Args, PartialEq, Debug)] struct Command2 { - #[clap(value_parser)] arg2: i32, } @@ -199,7 +193,6 @@ fn flatten_with_doc_comment() { #[derive(Args, PartialEq, Debug)] struct Common { /// This is an arg. Arg means "argument". Command line argument. - #[clap(value_parser)] arg: i32, } @@ -227,7 +220,7 @@ fn docstrings_ordering_with_multiple_clap() { /// This is the docstring for Flattened #[derive(Args)] struct Flattened { - #[clap(long, action)] + #[clap(long)] foo: bool, } @@ -248,7 +241,7 @@ fn docstrings_ordering_with_multiple_clap_partial() { /// This is the docstring for Flattened #[derive(Args)] struct Flattened { - #[clap(long, action)] + #[clap(long)] foo: bool, } diff --git a/tests/derive/generic.rs b/tests/derive/generic.rs index cea94729083..5d484295148 100644 --- a/tests/derive/generic.rs +++ b/tests/derive/generic.rs @@ -4,7 +4,6 @@ use clap::{Args, Parser}; fn generic_struct_flatten() { #[derive(Args, PartialEq, Debug)] struct Inner { - #[clap(value_parser)] pub answer: isize, } @@ -26,7 +25,6 @@ fn generic_struct_flatten() { fn generic_struct_flatten_w_where_clause() { #[derive(Args, PartialEq, Debug)] struct Inner { - #[clap(value_parser)] pub answer: isize, } @@ -51,7 +49,6 @@ fn generic_struct_flatten_w_where_clause() { fn generic_enum() { #[derive(Args, PartialEq, Debug)] struct Inner { - #[clap(value_parser)] pub answer: isize, } @@ -71,7 +68,6 @@ fn generic_enum() { fn generic_enum_w_where_clause() { #[derive(Args, PartialEq, Debug)] struct Inner { - #[clap(value_parser)] pub answer: isize, } @@ -100,7 +96,6 @@ fn generic_w_fromstr_trait_bound() { T: FromStr + Send + Sync + Clone + 'static, ::Err: std::error::Error + Sync + Send + 'static, { - #[clap(value_parser)] answer: T, } @@ -116,7 +111,6 @@ fn generic_wo_trait_bound() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_parser)] answer: isize, #[clap(skip)] took: Option, @@ -141,7 +135,6 @@ fn generic_where_clause_w_trailing_comma() { T: FromStr + Send + Sync + Clone + 'static, ::Err: std::error::Error + Sync + Send + 'static, { - #[clap(value_parser)] pub answer: T, } diff --git a/tests/derive/help.rs b/tests/derive/help.rs index 8496248949b..97fb394e75f 100644 --- a/tests/derive/help.rs +++ b/tests/derive/help.rs @@ -4,36 +4,26 @@ use clap::{AppSettings, Args, CommandFactory, Parser, Subcommand}; fn arg_help_heading_applied() { #[derive(Debug, Clone, Parser)] struct CliOptions { - #[clap(long, value_parser)] + #[clap(long)] #[clap(help_heading = Some("HEADING A"))] should_be_in_section_a: u32, - #[clap(long, value_parser)] + #[clap(long)] no_section: u32, } let cmd = CliOptions::command(); - let should_be_in_section_a = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_section_a") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-section-a") - .unwrap() - }; + let should_be_in_section_a = cmd + .get_arguments() + .find(|a| a.get_id() == "should_be_in_section_a") + .unwrap(); assert_eq!(should_be_in_section_a.get_help_heading(), Some("HEADING A")); - let should_be_in_section_b = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "no_section") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "no-section") - .unwrap() - }; + let should_be_in_section_b = cmd + .get_arguments() + .find(|a| a.get_id() == "no_section") + .unwrap(); assert_eq!(should_be_in_section_b.get_help_heading(), None); } @@ -42,36 +32,26 @@ fn app_help_heading_applied() { #[derive(Debug, Clone, Parser)] #[clap(next_help_heading = "DEFAULT")] struct CliOptions { - #[clap(long, value_parser)] + #[clap(long)] #[clap(help_heading = Some("HEADING A"))] should_be_in_section_a: u32, - #[clap(long, value_parser)] + #[clap(long)] should_be_in_default_section: u32, } let cmd = CliOptions::command(); - let should_be_in_section_a = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_section_a") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-section-a") - .unwrap() - }; + let should_be_in_section_a = cmd + .get_arguments() + .find(|a| a.get_id() == "should_be_in_section_a") + .unwrap(); assert_eq!(should_be_in_section_a.get_help_heading(), Some("HEADING A")); - let should_be_in_default_section = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_default_section") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-default-section") - .unwrap() - }; + let should_be_in_default_section = cmd + .get_arguments() + .find(|a| a.get_id() == "should_be_in_default_section") + .unwrap(); assert_eq!( should_be_in_default_section.get_help_heading(), Some("DEFAULT") @@ -94,21 +74,21 @@ fn app_help_heading_flattened() { #[clap(subcommand)] sub_a: SubA, - #[clap(long, value_parser)] + #[clap(long)] should_be_in_default_section: u32, } #[derive(Debug, Clone, Args)] #[clap(next_help_heading = "HEADING A")] struct OptionsA { - #[clap(long, value_parser)] + #[clap(long)] should_be_in_section_a: u32, } #[derive(Debug, Clone, Args)] #[clap(next_help_heading = "HEADING B")] struct OptionsB { - #[clap(long, value_parser)] + #[clap(long)] should_be_in_section_b: u32, } @@ -121,7 +101,6 @@ fn app_help_heading_flattened() { SubAOne, #[clap(next_help_heading = "SUB A")] SubATwo { - #[clap(value_parser)] should_be_in_sub_a: u32, }, } @@ -129,100 +108,58 @@ fn app_help_heading_flattened() { #[derive(Debug, Clone, Subcommand)] enum SubB { #[clap(next_help_heading = "SUB B")] - SubBOne { - #[clap(value_parser)] - should_be_in_sub_b: u32, - }, + SubBOne { should_be_in_sub_b: u32 }, } #[derive(Debug, Clone, Subcommand)] enum SubC { #[clap(next_help_heading = "SUB C")] - SubCOne { - #[clap(value_parser)] - should_be_in_sub_c: u32, - }, + SubCOne { should_be_in_sub_c: u32 }, } let cmd = CliOptions::command(); - let should_be_in_section_a = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_section_a") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-section-a") - .unwrap() - }; + let should_be_in_section_a = cmd + .get_arguments() + .find(|a| a.get_id() == "should_be_in_section_a") + .unwrap(); assert_eq!(should_be_in_section_a.get_help_heading(), Some("HEADING A")); - let should_be_in_section_b = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_section_b") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-section-b") - .unwrap() - }; + let should_be_in_section_b = cmd + .get_arguments() + .find(|a| a.get_id() == "should_be_in_section_b") + .unwrap(); assert_eq!(should_be_in_section_b.get_help_heading(), Some("HEADING B")); - let should_be_in_default_section = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_default_section") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-default-section") - .unwrap() - }; + let should_be_in_default_section = cmd + .get_arguments() + .find(|a| a.get_id() == "should_be_in_default_section") + .unwrap(); assert_eq!(should_be_in_default_section.get_help_heading(), None); let sub_a_two = cmd.find_subcommand("sub-a-two").unwrap(); - let should_be_in_sub_a = if cfg!(feature = "unstable-v4") { - sub_a_two - .get_arguments() - .find(|a| a.get_id() == "should_be_in_sub_a") - .unwrap() - } else { - sub_a_two - .get_arguments() - .find(|a| a.get_id() == "should-be-in-sub-a") - .unwrap() - }; + let should_be_in_sub_a = sub_a_two + .get_arguments() + .find(|a| a.get_id() == "should_be_in_sub_a") + .unwrap(); assert_eq!(should_be_in_sub_a.get_help_heading(), Some("SUB A")); let sub_b_one = cmd.find_subcommand("sub-b-one").unwrap(); - let should_be_in_sub_b = if cfg!(feature = "unstable-v4") { - sub_b_one - .get_arguments() - .find(|a| a.get_id() == "should_be_in_sub_b") - .unwrap() - } else { - sub_b_one - .get_arguments() - .find(|a| a.get_id() == "should-be-in-sub-b") - .unwrap() - }; + let should_be_in_sub_b = sub_b_one + .get_arguments() + .find(|a| a.get_id() == "should_be_in_sub_b") + .unwrap(); assert_eq!(should_be_in_sub_b.get_help_heading(), Some("SUB B")); let sub_c = cmd.find_subcommand("sub-c").unwrap(); let sub_c_one = sub_c.find_subcommand("sub-c-one").unwrap(); - let should_be_in_sub_c = if cfg!(feature = "unstable-v4") { - sub_c_one - .get_arguments() - .find(|a| a.get_id() == "should_be_in_sub_c") - .unwrap() - } else { - sub_c_one - .get_arguments() - .find(|a| a.get_id() == "should-be-in-sub-c") - .unwrap() - }; + let should_be_in_sub_c = sub_c_one + .get_arguments() + .find(|a| a.get_id() == "should_be_in_sub_c") + .unwrap(); assert_eq!(should_be_in_sub_c.get_help_heading(), Some("SUB C")); } @@ -237,21 +174,16 @@ fn flatten_field_with_help_heading() { #[derive(Debug, Clone, Args)] struct OptionsA { - #[clap(long, value_parser)] + #[clap(long)] should_be_in_section_a: u32, } let cmd = CliOptions::command(); - let should_be_in_section_a = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_section_a") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-section-a") - .unwrap() - }; + let should_be_in_section_a = cmd + .get_arguments() + .find(|a| a.get_id() == "should_be_in_section_a") + .unwrap(); assert_eq!(should_be_in_section_a.get_help_heading(), Some("HEADING A")); } @@ -264,7 +196,7 @@ fn derive_generated_error_has_full_context() { #[derive(Debug, Parser)] #[clap(subcommand_negates_reqs = true)] struct Opts { - #[clap(long, value_parser)] + #[clap(long)] req_str: String, #[clap(subcommand)] @@ -286,18 +218,7 @@ fn derive_generated_error_has_full_context() { result.unwrap() ); - if cfg!(feature = "unstable-v4") { - let expected = r#"error: The following required argument was not provided: req_str - -USAGE: - clap --req-str - clap - -For more information try --help -"#; - assert_eq!(result.unwrap_err().to_string(), expected); - } else { - let expected = r#"error: The following required argument was not provided: req-str + let expected = r#"error: The following required argument was not provided: req_str USAGE: clap --req-str @@ -305,8 +226,7 @@ USAGE: For more information try --help "#; - assert_eq!(result.unwrap_err().to_string(), expected); - } + assert_eq!(result.unwrap_err().to_string(), expected); } #[test] @@ -339,10 +259,10 @@ OPTIONS: #[clap(next_display_order = 10000)] struct A { /// second flag - #[clap(long, action)] + #[clap(long)] flag_a: bool, /// second option - #[clap(long, value_parser)] + #[clap(long)] option_a: Option, } @@ -350,10 +270,10 @@ OPTIONS: #[clap(next_display_order = 10)] struct B { /// first flag - #[clap(long, action)] + #[clap(long)] flag_b: bool, /// first option - #[clap(long, value_parser)] + #[clap(long)] option_b: Option, } @@ -397,20 +317,20 @@ OPTIONS: #[derive(Args, Debug)] struct A { /// second flag - #[clap(long, action)] + #[clap(long)] flag_a: bool, /// second option - #[clap(long, value_parser)] + #[clap(long)] option_a: Option, } #[derive(Args, Debug)] struct B { /// first flag - #[clap(long, action)] + #[clap(long)] flag_b: bool, /// first option - #[clap(long, value_parser)] + #[clap(long)] option_b: Option, } @@ -453,20 +373,20 @@ OPTIONS: #[derive(Args, Debug)] struct A { /// first flag - #[clap(long, action)] + #[clap(long)] flag_a: bool, /// first option - #[clap(long, value_parser)] + #[clap(long)] option_a: Option, } #[derive(Args, Debug)] struct B { /// second flag - #[clap(long, action)] + #[clap(long)] flag_b: bool, /// second option - #[clap(long, value_parser)] + #[clap(long)] option_b: Option, } @@ -480,7 +400,6 @@ OPTIONS: } #[test] -#[cfg(feature = "unstable-v4")] fn derive_possible_value_help() { static HELP: &str = "clap Application help @@ -505,7 +424,7 @@ OPTIONS: #[derive(Parser, PartialEq, Debug)] struct Args { /// Argument help - #[clap(value_enum, value_parser)] + #[clap(value_enum)] arg: ArgChoice, } diff --git a/tests/derive/issues.rs b/tests/derive/issues.rs index 22c93c87172..d2c01363b14 100644 --- a/tests/derive/issues.rs +++ b/tests/derive/issues.rs @@ -9,9 +9,9 @@ fn issue_151_groups_within_subcommands() { #[derive(Args, Debug)] #[clap(group = ArgGroup::new("verb").required(true).multiple(true))] struct Opt { - #[clap(long, group = "verb", value_parser)] + #[clap(long, group = "verb")] foo: Option, - #[clap(long, group = "verb", value_parser)] + #[clap(long, group = "verb")] bar: Option, } @@ -89,7 +89,6 @@ fn issue_418() { #[clap(visible_alias = "ret")] Reticulate { /// How many splines - #[clap(value_parser)] num_splines: u8, }, /// Frobnicate the rest @@ -122,9 +121,8 @@ fn issue_490() { #[derive(Parser, Debug)] struct Opt { - #[clap(value_parser)] opt_vec: Vec, - #[clap(long, value_parser)] + #[clap(long)] opt_opt_vec: Option>, } diff --git a/tests/derive/macros.rs b/tests/derive/macros.rs index 5dbec71a39c..a2e671b4abc 100644 --- a/tests/derive/macros.rs +++ b/tests/derive/macros.rs @@ -22,7 +22,7 @@ fn use_option() { ($name:ident: $ty:ty) => { #[derive(Parser)] struct Outer { - #[clap(short, long, value_parser)] + #[clap(short, long)] #[allow(dead_code)] $name: $ty, } diff --git a/tests/derive/main.rs b/tests/derive/main.rs index 50ea297487b..02e40d3ed2d 100644 --- a/tests/derive/main.rs +++ b/tests/derive/main.rs @@ -1,7 +1,5 @@ #![cfg(feature = "derive")] -mod next; - mod app_name; mod arguments; mod author_version_about; diff --git a/tests/derive/naming.rs b/tests/derive/naming.rs index d0b897f7e89..e3018a02f7c 100644 --- a/tests/derive/naming.rs +++ b/tests/derive/naming.rs @@ -5,7 +5,7 @@ fn test_standalone_long_generates_kebab_case() { #[derive(Parser, Debug, PartialEq)] #[allow(non_snake_case)] struct Opt { - #[clap(long, action)] + #[clap(long)] FOO_OPTION: bool, } @@ -19,7 +19,7 @@ fn test_standalone_long_generates_kebab_case() { fn test_custom_long_overwrites_default_name() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(long = "foo", action)] + #[clap(long = "foo")] foo_option: bool, } @@ -33,7 +33,7 @@ fn test_custom_long_overwrites_default_name() { fn test_standalone_long_uses_previous_defined_custom_name() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(name = "foo", long, action)] + #[clap(name = "foo", long)] foo_option: bool, } @@ -47,7 +47,7 @@ fn test_standalone_long_uses_previous_defined_custom_name() { fn test_standalone_long_ignores_afterwards_defined_custom_name() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(long, name = "foo", action)] + #[clap(long, name = "foo")] foo_option: bool, } @@ -62,7 +62,7 @@ fn test_standalone_short_generates_kebab_case() { #[derive(Parser, Debug, PartialEq)] #[allow(non_snake_case)] struct Opt { - #[clap(short, action)] + #[clap(short)] FOO_OPTION: bool, } @@ -76,7 +76,7 @@ fn test_standalone_short_generates_kebab_case() { fn test_custom_short_overwrites_default_name() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(short = 'o', action)] + #[clap(short = 'o')] foo_option: bool, } @@ -90,7 +90,7 @@ fn test_custom_short_overwrites_default_name() { fn test_standalone_short_uses_previous_defined_custom_name() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(name = "option", short, action)] + #[clap(name = "option", short)] foo_option: bool, } @@ -104,7 +104,7 @@ fn test_standalone_short_uses_previous_defined_custom_name() { fn test_standalone_short_ignores_afterwards_defined_custom_name() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(short, name = "option", action)] + #[clap(short, name = "option")] foo_option: bool, } @@ -118,7 +118,7 @@ fn test_standalone_short_ignores_afterwards_defined_custom_name() { fn test_standalone_long_uses_previous_defined_casing() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(rename_all = "screaming_snake", long, action)] + #[clap(rename_all = "screaming_snake", long)] foo_option: bool, } @@ -132,7 +132,7 @@ fn test_standalone_long_uses_previous_defined_casing() { fn test_standalone_short_uses_previous_defined_casing() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(rename_all = "screaming_snake", short, action)] + #[clap(rename_all = "screaming_snake", short)] foo_option: bool, } @@ -147,7 +147,7 @@ fn test_standalone_long_works_with_verbatim_casing() { #[derive(Parser, Debug, PartialEq)] #[allow(non_snake_case)] struct Opt { - #[clap(rename_all = "verbatim", long, action)] + #[clap(rename_all = "verbatim", long)] _fOO_oPtiON: bool, } @@ -161,7 +161,7 @@ fn test_standalone_long_works_with_verbatim_casing() { fn test_standalone_short_works_with_verbatim_casing() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(rename_all = "verbatim", short, action)] + #[clap(rename_all = "verbatim", short)] _foo: bool, } @@ -176,7 +176,7 @@ fn test_rename_all_is_propagated_from_struct_to_fields() { #[derive(Parser, Debug, PartialEq)] #[clap(rename_all = "screaming_snake")] struct Opt { - #[clap(long, action)] + #[clap(long)] foo: bool, } @@ -197,7 +197,7 @@ fn test_rename_all_is_not_propagated_from_struct_into_flattened() { #[derive(Parser, Debug, PartialEq)] struct Foo { - #[clap(long, action)] + #[clap(long)] foo: bool, } @@ -213,7 +213,7 @@ fn test_rename_all_is_not_propagated_from_struct_into_flattened() { fn test_lower_is_renamed() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(rename_all = "lower", long, action)] + #[clap(rename_all = "lower", long)] foo_option: bool, } @@ -227,7 +227,7 @@ fn test_lower_is_renamed() { fn test_upper_is_renamed() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(rename_all = "upper", long, action)] + #[clap(rename_all = "upper", long)] foo_option: bool, } @@ -241,10 +241,7 @@ fn test_upper_is_renamed() { fn test_single_word_enum_variant_is_default_renamed_into_kebab_case() { #[derive(Parser, Debug, PartialEq)] enum Opt { - Command { - #[clap(value_parser)] - foo: u32, - }, + Command { foo: u32 }, } assert_eq!( @@ -257,10 +254,7 @@ fn test_single_word_enum_variant_is_default_renamed_into_kebab_case() { fn test_multi_word_enum_variant_is_renamed() { #[derive(Parser, Debug, PartialEq)] enum Opt { - FirstCommand { - #[clap(value_parser)] - foo: u32, - }, + FirstCommand { foo: u32 }, } assert_eq!( @@ -281,7 +275,7 @@ fn test_rename_all_is_not_propagated_from_struct_into_subcommand() { #[derive(Parser, Debug, PartialEq)] enum Foo { Command { - #[clap(long, action)] + #[clap(long)] foo: bool, }, } @@ -301,7 +295,7 @@ fn test_rename_all_is_propagated_from_enum_to_variants() { enum Opt { FirstVariant, SecondVariant { - #[clap(long, value_parser)] + #[clap(long)] foo: String, }, } @@ -319,7 +313,7 @@ fn test_rename_all_is_propagated_from_enum_to_variant_fields() { enum Opt { FirstVariant, SecondVariant { - #[clap(long, value_parser)] + #[clap(long)] foo: String, }, } @@ -339,11 +333,11 @@ fn test_rename_all_is_propagation_can_be_overridden() { enum Opt { #[clap(rename_all = "kebab_case")] FirstVariant { - #[clap(long, action)] + #[clap(long)] foo_option: bool, }, SecondVariant { - #[clap(rename_all = "kebab_case", long, action)] + #[clap(rename_all = "kebab_case", long)] foo_option: bool, }, } diff --git a/tests/derive/nested_subcommands.rs b/tests/derive/nested_subcommands.rs index 59a5ad57053..e5e32bfff7a 100644 --- a/tests/derive/nested_subcommands.rs +++ b/tests/derive/nested_subcommands.rs @@ -16,7 +16,7 @@ use clap::{Parser, Subcommand}; #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, long, action)] + #[clap(short, long)] force: bool, #[clap(short, long, action = clap::ArgAction::Count)] verbose: u8, @@ -32,7 +32,7 @@ enum Sub { #[derive(Parser, PartialEq, Debug)] struct Opt2 { - #[clap(short, long, action)] + #[clap(short, long)] force: bool, #[clap(short, long, action = clap::ArgAction::Count)] verbose: u8, @@ -109,7 +109,7 @@ fn test_badinput() { #[derive(Parser, PartialEq, Debug)] struct Opt3 { - #[clap(short, long, action)] + #[clap(short, long)] all: bool, #[clap(subcommand)] cmd: Sub2, @@ -118,7 +118,6 @@ struct Opt3 { #[derive(Subcommand, PartialEq, Debug)] enum Sub2 { Foo { - #[clap(value_parser)] file: String, #[clap(subcommand)] cmd: Sub3, @@ -159,16 +158,8 @@ enum SubSubCmdWithOption { } #[derive(Subcommand, PartialEq, Debug)] enum Remote { - Add { - #[clap(value_parser)] - name: String, - #[clap(value_parser)] - url: String, - }, - Remove { - #[clap(value_parser)] - name: String, - }, + Add { name: String, url: String }, + Remove { name: String }, } #[derive(Subcommand, PartialEq, Debug)] diff --git a/tests/derive/next/app_name.rs b/tests/derive/next/app_name.rs deleted file mode 100644 index 9e2f8d802c1..00000000000 --- a/tests/derive/next/app_name.rs +++ /dev/null @@ -1,97 +0,0 @@ -use clap::CommandFactory; -use clap::Parser; -#[test] -fn app_name_in_short_help_from_struct() { - #[derive(Parser)] - #[clap(name = "my-cmd")] - struct MyApp {} - - let mut help = Vec::new(); - MyApp::command().write_help(&mut help).unwrap(); - let help = String::from_utf8(help).unwrap(); - - assert!(help.contains("my-cmd")); -} - -#[test] -fn app_name_in_long_help_from_struct() { - #[derive(Parser)] - #[clap(name = "my-cmd")] - struct MyApp {} - - let mut help = Vec::new(); - MyApp::command().write_long_help(&mut help).unwrap(); - let help = String::from_utf8(help).unwrap(); - - assert!(help.contains("my-cmd")); -} - -#[test] -fn app_name_in_short_help_from_enum() { - #[derive(Parser)] - #[clap(name = "my-cmd")] - enum MyApp {} - - let mut help = Vec::new(); - MyApp::command().write_help(&mut help).unwrap(); - let help = String::from_utf8(help).unwrap(); - - assert!(help.contains("my-cmd")); -} - -#[test] -fn app_name_in_long_help_from_enum() { - #[derive(Parser)] - #[clap(name = "my-cmd")] - enum MyApp {} - - let mut help = Vec::new(); - MyApp::command().write_long_help(&mut help).unwrap(); - let help = String::from_utf8(help).unwrap(); - - assert!(help.contains("my-cmd")); -} - -#[test] -fn app_name_in_short_version_from_struct() { - #[derive(Parser)] - #[clap(name = "my-cmd")] - struct MyApp {} - - let version = MyApp::command().render_version(); - - assert!(version.contains("my-cmd")); -} - -#[test] -fn app_name_in_long_version_from_struct() { - #[derive(Parser)] - #[clap(name = "my-cmd")] - struct MyApp {} - - let version = MyApp::command().render_long_version(); - - assert!(version.contains("my-cmd")); -} - -#[test] -fn app_name_in_short_version_from_enum() { - #[derive(Parser)] - #[clap(name = "my-cmd")] - enum MyApp {} - - let version = MyApp::command().render_version(); - - assert!(version.contains("my-cmd")); -} - -#[test] -fn app_name_in_long_version_from_enum() { - #[derive(Parser)] - #[clap(name = "my-cmd")] - enum MyApp {} - - let version = MyApp::command().render_long_version(); - - assert!(version.contains("my-cmd")); -} diff --git a/tests/derive/next/arguments.rs b/tests/derive/next/arguments.rs deleted file mode 100644 index 57c5866d4ee..00000000000 --- a/tests/derive/next/arguments.rs +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -use clap::CommandFactory; -use clap::Parser; - -#[test] -fn required_argument() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - arg: i32, - } - assert_eq!( - Opt { arg: 42 }, - Opt::try_parse_from(&["test", "42"]).unwrap() - ); - assert!(Opt::try_parse_from(&["test"]).is_err()); - assert!(Opt::try_parse_from(&["test", "42", "24"]).is_err()); -} - -#[test] -fn argument_with_default() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(default_value = "42")] - arg: i32, - } - assert_eq!( - Opt { arg: 24 }, - Opt::try_parse_from(&["test", "24"]).unwrap() - ); - assert_eq!(Opt { arg: 42 }, Opt::try_parse_from(&["test"]).unwrap()); - assert!(Opt::try_parse_from(&["test", "42", "24"]).is_err()); -} - -#[test] -fn auto_value_name() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - my_special_arg: i32, - } - - let mut help = Vec::new(); - Opt::command().write_help(&mut help).unwrap(); - let help = String::from_utf8(help).unwrap(); - - assert!(help.contains("MY_SPECIAL_ARG")); - // Ensure the implicit `num_vals` is just 1 - assert_eq!( - Opt { my_special_arg: 10 }, - Opt::try_parse_from(&["test", "10"]).unwrap() - ); -} - -#[test] -fn explicit_value_name() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_name = "BROWNIE_POINTS")] - my_special_arg: i32, - } - - let mut help = Vec::new(); - Opt::command().write_help(&mut help).unwrap(); - let help = String::from_utf8(help).unwrap(); - - assert!(help.contains("BROWNIE_POINTS")); - assert!(!help.contains("MY_SPECIAL_ARG")); - // Ensure the implicit `num_vals` is just 1 - assert_eq!( - Opt { my_special_arg: 10 }, - Opt::try_parse_from(&["test", "10"]).unwrap() - ); -} - -#[test] -fn option_type_is_optional() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - arg: Option, - } - assert_eq!( - Opt { arg: Some(42) }, - Opt::try_parse_from(&["test", "42"]).unwrap() - ); - assert_eq!(Opt { arg: None }, Opt::try_parse_from(&["test"]).unwrap()); - assert!(Opt::try_parse_from(&["test", "42", "24"]).is_err()); -} - -#[test] -fn vec_type_is_multiple_values() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - arg: Vec, - } - assert_eq!( - Opt { arg: vec![24] }, - Opt::try_parse_from(&["test", "24"]).unwrap() - ); - assert_eq!(Opt { arg: vec![] }, Opt::try_parse_from(&["test"]).unwrap()); - assert_eq!( - Opt { arg: vec![24, 42] }, - Opt::try_parse_from(&["test", "24", "42"]).unwrap() - ); - assert_eq!( - clap::ErrorKind::ValueValidation, - Opt::try_parse_from(&["test", "NOPE"]).err().unwrap().kind() - ); -} diff --git a/tests/derive/next/author_version_about.rs b/tests/derive/next/author_version_about.rs deleted file mode 100644 index 3c68cd56129..00000000000 --- a/tests/derive/next/author_version_about.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -use crate::utils; - -use clap::Parser; - -#[test] -fn no_author_version_about() { - #[derive(Parser, PartialEq, Debug)] - #[clap(name = "foo")] - struct Opt {} - - let output = utils::get_long_help::(); - assert!(output.starts_with("foo \n\nUSAGE:")); -} - -#[test] -fn use_env() { - #[derive(Parser, PartialEq, Debug)] - #[clap(author, about, version)] - struct Opt {} - - let output = utils::get_long_help::(); - assert!(output.starts_with("clap")); - assert!(output - .contains("A simple to use, efficient, and full-featured Command Line Argument Parser")); -} - -#[test] -fn explicit_version_not_str_lit() { - const VERSION: &str = "custom version"; - - #[derive(Parser)] - #[clap(version = VERSION)] - pub struct Opt {} - - let output = utils::get_long_help::(); - assert!(output.contains("custom version")); -} diff --git a/tests/derive/next/basic.rs b/tests/derive/next/basic.rs deleted file mode 100644 index d2e1ca9001a..00000000000 --- a/tests/derive/next/basic.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -use clap::Parser; - -#[test] -fn basic() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short = 'a', long = "arg")] - arg: i32, - } - assert_eq!( - Opt { arg: 24 }, - Opt::try_parse_from(&["test", "-a24"]).unwrap() - ); -} - -#[test] -fn update_basic() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short = 'a', long = "arg")] - single_value: i32, - } - - let mut opt = Opt::try_parse_from(&["test", "-a0"]).unwrap(); - - opt.update_from(&["test", "-a42"]); - - assert_eq!(Opt { single_value: 42 }, opt); -} - -#[test] -fn unit_struct() { - #[derive(Parser, PartialEq, Debug)] - struct Opt; - - assert_eq!(Opt {}, Opt::try_parse_from(&["test"]).unwrap()); -} diff --git a/tests/derive/next/boxed.rs b/tests/derive/next/boxed.rs deleted file mode 100644 index 03efbe9c551..00000000000 --- a/tests/derive/next/boxed.rs +++ /dev/null @@ -1,48 +0,0 @@ -use clap::{Args, Parser, Subcommand}; - -#[derive(Parser, PartialEq, Debug)] -struct Opt { - #[clap(subcommand)] - sub: Box, -} - -#[derive(Subcommand, PartialEq, Debug)] -enum Sub { - Flame { - #[clap(flatten)] - arg: Box, - }, -} - -#[derive(Args, PartialEq, Debug)] -struct Ext { - arg: u32, -} - -#[test] -fn boxed_flatten_subcommand() { - assert_eq!( - Opt { - sub: Box::new(Sub::Flame { - arg: Box::new(Ext { arg: 1 }) - }) - }, - Opt::try_parse_from(&["test", "flame", "1"]).unwrap() - ); -} - -#[test] -fn update_boxed_flatten_subcommand() { - let mut opt = Opt::try_parse_from(&["test", "flame", "1"]).unwrap(); - - opt.update_from(&["test", "flame", "42"]); - - assert_eq!( - Opt { - sub: Box::new(Sub::Flame { - arg: Box::new(Ext { arg: 42 }) - }) - }, - opt - ); -} diff --git a/tests/derive/next/custom_string_parsers.rs b/tests/derive/next/custom_string_parsers.rs deleted file mode 100644 index 4c6f3d0f134..00000000000 --- a/tests/derive/next/custom_string_parsers.rs +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -#![allow(deprecated)] - -use clap::Parser; - -use std::num::ParseIntError; -use std::path::PathBuf; - -#[derive(Parser, PartialEq, Debug)] -struct PathOpt { - #[clap(short, long)] - path: PathBuf, - - #[clap(short, default_value = "../")] - default_path: PathBuf, - - #[clap(short, multiple_occurrences(true))] - vector_path: Vec, - - #[clap(short)] - option_path_1: Option, - - #[clap(short = 'q')] - option_path_2: Option, -} - -#[test] -fn test_path_opt_simple() { - assert_eq!( - PathOpt { - path: PathBuf::from("/usr/bin"), - default_path: PathBuf::from("../"), - vector_path: vec![ - PathBuf::from("/a/b/c"), - PathBuf::from("/d/e/f"), - PathBuf::from("/g/h/i"), - ], - option_path_1: None, - option_path_2: Some(PathBuf::from("j.zip")), - }, - PathOpt::try_parse_from(&[ - "test", "-p", "/usr/bin", "-v", "/a/b/c", "-v", "/d/e/f", "-v", "/g/h/i", "-q", - "j.zip", - ]) - .unwrap() - ); -} - -fn parse_hex(input: &str) -> Result { - u64::from_str_radix(input, 16) -} - -#[derive(Parser, PartialEq, Debug)] -struct HexOpt { - #[clap(short, value_parser = parse_hex)] - number: u64, -} - -#[test] -fn test_parse_hex() { - assert_eq!( - HexOpt { number: 5 }, - HexOpt::try_parse_from(&["test", "-n", "5"]).unwrap() - ); - assert_eq!( - HexOpt { - number: 0x00ab_cdef - }, - HexOpt::try_parse_from(&["test", "-n", "abcdef"]).unwrap() - ); - - let err = HexOpt::try_parse_from(&["test", "-n", "gg"]).unwrap_err(); - assert!( - err.to_string().contains("invalid digit found in string"), - "{}", - err - ); -} - -#[derive(Debug)] -struct ErrCode(u32); -impl std::error::Error for ErrCode {} -impl std::fmt::Display for ErrCode { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.0, f) - } -} -fn custom_parser_2(_: &str) -> Result<&'static str, ErrCode> { - Ok("B") -} - -#[derive(Parser, PartialEq, Debug)] -struct NoOpOpt { - #[clap(short, value_parser = custom_parser_2)] - b: &'static str, -} - -#[test] -fn test_every_custom_parser() { - assert_eq!( - NoOpOpt { b: "B" }, - NoOpOpt::try_parse_from(&["test", "-b=?"]).unwrap() - ); -} - -#[test] -fn update_every_custom_parser() { - let mut opt = NoOpOpt { b: "0" }; - - opt.try_update_from(&["test", "-b=?"]).unwrap(); - - assert_eq!(NoOpOpt { b: "B" }, opt); -} - -// Note: can't use `Vec` directly, as clap would instead look for -// conversion function from `&str` to `u8`. -type Bytes = Vec; - -#[derive(Parser, PartialEq, Debug)] -struct DefaultedOpt { - #[clap(short, parse(from_str))] - bytes: Bytes, - - #[clap(short)] - integer: u64, - - #[clap(short)] - path: PathBuf, -} - -#[test] -fn test_parser_with_default_value() { - assert_eq!( - DefaultedOpt { - bytes: b"E\xc2\xb2=p\xc2\xb2c\xc2\xb2+m\xc2\xb2c\xe2\x81\xb4".to_vec(), - integer: 9000, - path: PathBuf::from("src/lib.rs"), - }, - DefaultedOpt::try_parse_from(&[ - "test", - "-b", - "E²=p²c²+m²c⁴", - "-i", - "9000", - "-p", - "src/lib.rs", - ]) - .unwrap() - ); -} - -#[derive(PartialEq, Debug)] -struct Foo(u8); - -fn foo(value: u64) -> Foo { - Foo(value as u8) -} - -#[derive(Parser, PartialEq, Debug)] -struct Occurrences { - #[clap(short, long, parse(from_occurrences))] - signed: i32, - - #[clap(short, parse(from_occurrences))] - little_signed: i8, - - #[clap(short, parse(from_occurrences))] - unsigned: usize, - - #[clap(short = 'r', parse(from_occurrences))] - little_unsigned: u8, - - #[clap(short, long, parse(from_occurrences = foo))] - custom: Foo, -} - -#[test] -fn test_parser_occurrences() { - assert_eq!( - Occurrences { - signed: 3, - little_signed: 1, - unsigned: 0, - little_unsigned: 4, - custom: Foo(5), - }, - Occurrences::try_parse_from(&[ - "test", "-s", "--signed", "--signed", "-l", "-rrrr", "-cccc", "--custom", - ]) - .unwrap() - ); -} diff --git a/tests/derive/next/default_value.rs b/tests/derive/next/default_value.rs deleted file mode 100644 index db2b7838014..00000000000 --- a/tests/derive/next/default_value.rs +++ /dev/null @@ -1,57 +0,0 @@ -use clap::{CommandFactory, Parser}; - -use crate::utils; - -#[test] -fn default_value() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(default_value = "3")] - arg: i32, - } - assert_eq!(Opt { arg: 3 }, Opt::try_parse_from(&["test"]).unwrap()); - assert_eq!(Opt { arg: 1 }, Opt::try_parse_from(&["test", "1"]).unwrap()); - - let help = utils::get_long_help::(); - assert!(help.contains("[default: 3]")); -} - -#[test] -fn default_value_t() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(default_value_t = 3)] - arg: i32, - } - assert_eq!(Opt { arg: 3 }, Opt::try_parse_from(&["test"]).unwrap()); - assert_eq!(Opt { arg: 1 }, Opt::try_parse_from(&["test", "1"]).unwrap()); - - let help = utils::get_long_help::(); - assert!(help.contains("[default: 3]")); -} - -#[test] -fn auto_default_value_t() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(default_value_t)] - arg: i32, - } - assert_eq!(Opt { arg: 0 }, Opt::try_parse_from(&["test"]).unwrap()); - assert_eq!(Opt { arg: 1 }, Opt::try_parse_from(&["test", "1"]).unwrap()); - - let help = utils::get_long_help::(); - assert!(help.contains("[default: 0]")); -} - -#[test] -fn detect_os_variant() { - #![allow(unused_parens)] // needed for `as_ref` call - - #[derive(clap::Parser)] - pub struct Options { - #[clap(default_value_os = ("123".as_ref()))] - x: String, - } - Options::command().debug_assert(); -} diff --git a/tests/derive/next/deny_warnings.rs b/tests/derive/next/deny_warnings.rs deleted file mode 100644 index 6e05b9277cc..00000000000 --- a/tests/derive/next/deny_warnings.rs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -#![deny(warnings)] - -use clap::Parser; - -fn try_str(s: &str) -> Result { - Ok(s.into()) -} - -#[test] -fn warning_never_struct() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(value_parser = try_str, default_value_t)] - s: String, - } - assert_eq!( - Opt { - s: "foo".to_string() - }, - Opt::try_parse_from(&["test", "foo"]).unwrap() - ); -} - -#[test] -fn warning_never_enum() { - #[derive(Parser, Debug, PartialEq)] - enum Opt { - Foo { - #[clap(value_parser = try_str, default_value_t)] - s: String, - }, - } - assert_eq!( - Opt::Foo { - s: "foo".to_string() - }, - Opt::try_parse_from(&["test", "foo", "foo"]).unwrap() - ); -} diff --git a/tests/derive/next/doc_comments_help.rs b/tests/derive/next/doc_comments_help.rs deleted file mode 100644 index bfe152a6102..00000000000 --- a/tests/derive/next/doc_comments_help.rs +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -use crate::utils; - -use clap::{CommandFactory, Parser, ValueEnum}; - -#[test] -fn doc_comments() { - /// Lorem ipsum - #[derive(Parser, PartialEq, Debug)] - struct LoremIpsum { - /// Fooify a bar - /// and a baz - #[clap(short, long)] - foo: bool, - } - - let help = utils::get_long_help::(); - assert!(help.contains("Lorem ipsum")); - assert!(help.contains("Fooify a bar and a baz")); -} - -#[test] -fn help_is_better_than_comments() { - /// Lorem ipsum - #[derive(Parser, PartialEq, Debug)] - #[clap(name = "lorem-ipsum", about = "Dolor sit amet")] - struct LoremIpsum { - /// Fooify a bar - #[clap(short, long, help = "DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES")] - foo: bool, - } - - let help = utils::get_long_help::(); - assert!(help.contains("Dolor sit amet")); - assert!(!help.contains("Lorem ipsum")); - assert!(help.contains("DO NOT PASS A BAR")); -} - -#[test] -fn empty_line_in_doc_comment_is_double_linefeed() { - /// Foo. - /// - /// Bar - #[derive(Parser, PartialEq, Debug)] - #[clap(name = "lorem-ipsum")] - struct LoremIpsum {} - - let help = utils::get_long_help::(); - assert!(help.starts_with("lorem-ipsum \nFoo.\n\nBar\n\nUSAGE:")); -} - -#[test] -fn field_long_doc_comment_both_help_long_help() { - /// Lorem ipsumclap - #[derive(Parser, PartialEq, Debug)] - #[clap(name = "lorem-ipsum", about = "Dolor sit amet")] - struct LoremIpsum { - /// Dot is removed from multiline comments. - /// - /// Long help - #[clap(long)] - foo: bool, - - /// Dot is removed from one short comment. - #[clap(long)] - bar: bool, - } - - let short_help = utils::get_help::(); - let long_help = utils::get_long_help::(); - - assert!(short_help.contains("Dot is removed from one short comment")); - assert!(!short_help.contains("Dot is removed from one short comment.")); - assert!(short_help.contains("Dot is removed from multiline comments")); - assert!(!short_help.contains("Dot is removed from multiline comments.")); - assert!(long_help.contains("Long help")); - assert!(!short_help.contains("Long help")); -} - -#[test] -fn top_long_doc_comment_both_help_long_help() { - /// Lorem ipsumclap - #[derive(Parser, Debug)] - #[clap(name = "lorem-ipsum", about = "Dolor sit amet")] - struct LoremIpsum { - #[clap(subcommand)] - foo: SubCommand, - } - - #[derive(Parser, Debug)] - pub enum SubCommand { - /// DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES - /// - /// Or something else - Foo { - #[clap(help = "foo")] - bars: String, - }, - } - - let short_help = utils::get_help::(); - let long_help = utils::get_subcommand_long_help::("foo"); - - assert!(!short_help.contains("Or something else")); - assert!(long_help.contains("DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES")); - assert!(long_help.contains("Or something else")); -} - -#[test] -fn verbatim_doc_comment() { - /// DANCE! - /// - /// () - /// | - /// ( () ) - /// ) ________ // ) - /// () |\ \ // - /// ( \\__ \ ______\// - /// \__) | | - /// | | | - /// \ | | - /// \|_______| - /// // \\ - /// (( || - /// \\ || - /// ( () || - /// ( () ) ) - #[derive(Parser, Debug)] - #[clap(verbatim_doc_comment)] - struct SeeFigure1 { - #[clap(long)] - foo: bool, - } - - let help = utils::get_long_help::(); - let sample = r#" - () - | - ( () ) - ) ________ // ) - () |\ \ // -( \\__ \ ______\// - \__) | | - | | | - \ | | - \|_______| - // \\ - (( || - \\ || - ( () || - ( () ) )"#; - - assert!(help.contains(sample)) -} - -#[test] -fn verbatim_doc_comment_field() { - #[derive(Parser, Debug)] - struct Command { - /// This help ends in a period. - #[clap(long, verbatim_doc_comment)] - foo: bool, - /// This help does not end in a period. - #[clap(long)] - bar: bool, - } - - let help = utils::get_long_help::(); - - assert!(help.contains("This help ends in a period.")); - assert!(help.contains("This help does not end in a period")); -} - -#[test] -fn multiline_separates_default() { - #[derive(Parser, Debug)] - struct Command { - /// Multiline - /// - /// Doc comment - #[clap(long, default_value = "x")] - x: String, - } - - let help = utils::get_long_help::(); - assert!(!help.contains("Doc comment [default")); - assert!(help.lines().any(|s| s.trim().starts_with("[default"))); - - // The short help should still have the default on the same line - let help = utils::get_help::(); - assert!(help.contains("Multiline [default")); -} - -#[test] -fn argenum_multiline_doc_comment() { - #[derive(ValueEnum, Clone)] - enum LoremIpsum { - /// Multiline - /// - /// Doc comment - Bar, - } -} - -#[test] -fn doc_comment_about_handles_both_abouts() { - /// Opts doc comment summary - #[derive(Parser, Debug)] - pub struct Opts { - #[clap(subcommand)] - pub cmd: Sub, - } - - /// Sub doc comment summary - /// - /// Sub doc comment body - #[derive(Parser, PartialEq, Eq, Debug)] - pub enum Sub { - Compress { output: String }, - } - - let cmd = Opts::command(); - assert_eq!(cmd.get_about(), Some("Opts doc comment summary")); - // clap will fallback to `about` on `None`. The main care about is not providing a `Sub` doc - // comment. - assert_eq!(cmd.get_long_about(), None); -} diff --git a/tests/derive/next/explicit_name_no_renaming.rs b/tests/derive/next/explicit_name_no_renaming.rs deleted file mode 100644 index dcdbc3820c7..00000000000 --- a/tests/derive/next/explicit_name_no_renaming.rs +++ /dev/null @@ -1,36 +0,0 @@ -use crate::utils; - -use clap::Parser; - -#[test] -fn explicit_short_long_no_rename() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short = '.', long = ".foo")] - foo: String, - } - - assert_eq!( - Opt { foo: "long".into() }, - Opt::try_parse_from(&["test", "--.foo", "long"]).unwrap() - ); - - assert_eq!( - Opt { - foo: "short".into(), - }, - Opt::try_parse_from(&["test", "-.", "short"]).unwrap() - ); -} - -#[test] -fn explicit_name_no_rename() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(name = ".options")] - foo: String, - } - - let help = utils::get_long_help::(); - assert!(help.contains("<.options>")) -} diff --git a/tests/derive/next/flags.rs b/tests/derive/next/flags.rs deleted file mode 100644 index 02bcc45b478..00000000000 --- a/tests/derive/next/flags.rs +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -#![allow(deprecated)] - -use clap::Parser; - -#[test] -fn bool_type_is_flag() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short, long)] - alice: bool, - } - - assert_eq!( - Opt { alice: false }, - Opt::try_parse_from(&["test"]).unwrap() - ); - assert_eq!( - Opt { alice: true }, - Opt::try_parse_from(&["test", "-a"]).unwrap() - ); - assert_eq!( - Opt { alice: true }, - Opt::try_parse_from(&["test", "-a", "-a"]).unwrap() - ); - assert_eq!( - Opt { alice: true }, - Opt::try_parse_from(&["test", "--alice"]).unwrap() - ); - assert!(Opt::try_parse_from(&["test", "-i"]).is_err()); - assert!(Opt::try_parse_from(&["test", "-a", "foo"]).is_err()); -} - -#[test] -fn count() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short, long, action = clap::ArgAction::Count)] - alice: u8, - #[clap(short, long, action = clap::ArgAction::Count)] - bob: u8, - } - - assert_eq!( - Opt { alice: 0, bob: 0 }, - Opt::try_parse_from(&["test"]).unwrap() - ); - assert_eq!( - Opt { alice: 1, bob: 0 }, - Opt::try_parse_from(&["test", "-a"]).unwrap() - ); - assert_eq!( - Opt { alice: 2, bob: 0 }, - Opt::try_parse_from(&["test", "-a", "-a"]).unwrap() - ); - assert_eq!( - Opt { alice: 2, bob: 2 }, - Opt::try_parse_from(&["test", "-a", "--alice", "-bb"]).unwrap() - ); - assert_eq!( - Opt { alice: 3, bob: 1 }, - Opt::try_parse_from(&["test", "-aaa", "--bob"]).unwrap() - ); - assert!(Opt::try_parse_from(&["test", "-i"]).is_err()); - assert!(Opt::try_parse_from(&["test", "-a", "foo"]).is_err()); -} - -#[test] -fn non_bool_type_flag() { - fn parse_from_flag(b: bool) -> std::sync::atomic::AtomicBool { - std::sync::atomic::AtomicBool::new(b) - } - - #[derive(Parser, Debug)] - struct Opt { - #[clap(short, long, parse(from_flag = parse_from_flag))] - alice: std::sync::atomic::AtomicBool, - #[clap(short, long, parse(from_flag))] - bob: std::sync::atomic::AtomicBool, - } - - let falsey = Opt::try_parse_from(&["test"]).unwrap(); - assert!(!falsey.alice.load(std::sync::atomic::Ordering::Relaxed)); - assert!(!falsey.bob.load(std::sync::atomic::Ordering::Relaxed)); - - let alice = Opt::try_parse_from(&["test", "-a"]).unwrap(); - assert!(alice.alice.load(std::sync::atomic::Ordering::Relaxed)); - assert!(!alice.bob.load(std::sync::atomic::Ordering::Relaxed)); - - let bob = Opt::try_parse_from(&["test", "-b"]).unwrap(); - assert!(!bob.alice.load(std::sync::atomic::Ordering::Relaxed)); - assert!(bob.bob.load(std::sync::atomic::Ordering::Relaxed)); - - let both = Opt::try_parse_from(&["test", "-b", "-a"]).unwrap(); - assert!(both.alice.load(std::sync::atomic::Ordering::Relaxed)); - assert!(both.bob.load(std::sync::atomic::Ordering::Relaxed)); -} - -#[test] -fn mixed_type_flags() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short, long)] - alice: bool, - #[clap(short, long, action = clap::ArgAction::Count)] - bob: u8, - } - - assert_eq!( - Opt { - alice: false, - bob: 0 - }, - Opt::try_parse_from(&["test"]).unwrap() - ); - assert_eq!( - Opt { - alice: true, - bob: 0 - }, - Opt::try_parse_from(&["test", "-a"]).unwrap() - ); - assert_eq!( - Opt { - alice: true, - bob: 0 - }, - Opt::try_parse_from(&["test", "-a"]).unwrap() - ); - assert_eq!( - Opt { - alice: false, - bob: 1 - }, - Opt::try_parse_from(&["test", "-b"]).unwrap() - ); - assert_eq!( - Opt { - alice: true, - bob: 1 - }, - Opt::try_parse_from(&["test", "--alice", "--bob"]).unwrap() - ); - assert_eq!( - Opt { - alice: true, - bob: 4 - }, - Opt::try_parse_from(&["test", "-bb", "-a", "-bb"]).unwrap() - ); -} - -#[test] -fn ignore_qualified_bool_type() { - mod inner { - #[allow(non_camel_case_types)] - #[derive(PartialEq, Debug, Clone)] - pub struct bool(pub String); - - impl std::str::FromStr for self::bool { - type Err = String; - - fn from_str(s: &str) -> Result { - Ok(self::bool(s.into())) - } - } - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - arg: inner::bool, - } - - assert_eq!( - Opt { - arg: inner::bool("success".into()) - }, - Opt::try_parse_from(&["test", "success"]).unwrap() - ); -} - -#[test] -fn override_implicit_action() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(long, action = clap::ArgAction::Set)] - arg: bool, - } - - assert_eq!( - Opt { arg: false }, - Opt::try_parse_from(&["test", "--arg", "false"]).unwrap() - ); - - assert_eq!( - Opt { arg: true }, - Opt::try_parse_from(&["test", "--arg", "true"]).unwrap() - ); -} - -#[test] -fn override_implicit_from_flag_positional() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(action = clap::ArgAction::Set)] - arg: bool, - } - - assert_eq!( - Opt { arg: false }, - Opt::try_parse_from(&["test", "false"]).unwrap() - ); - - assert_eq!( - Opt { arg: true }, - Opt::try_parse_from(&["test", "true"]).unwrap() - ); -} diff --git a/tests/derive/next/flatten.rs b/tests/derive/next/flatten.rs deleted file mode 100644 index 77561997bd6..00000000000 --- a/tests/derive/next/flatten.rs +++ /dev/null @@ -1,257 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -use crate::utils; - -use clap::{Args, Parser, Subcommand}; - -#[test] -fn flatten() { - #[derive(Args, PartialEq, Debug)] - struct Common { - arg: i32, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(flatten)] - common: Common, - } - assert_eq!( - Opt { - common: Common { arg: 42 } - }, - Opt::try_parse_from(&["test", "42"]).unwrap() - ); - assert!(Opt::try_parse_from(&["test"]).is_err()); - assert!(Opt::try_parse_from(&["test", "42", "24"]).is_err()); -} - -#[cfg(debug_assertions)] -#[test] -#[should_panic] -fn flatten_twice() { - #[derive(Args, PartialEq, Debug)] - struct Common { - arg: i32, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(flatten)] - c1: Common, - // Defines "arg" twice, so this should not work. - #[clap(flatten)] - c2: Common, - } - Opt::try_parse_from(&["test", "42", "43"]).unwrap(); -} - -#[test] -fn flatten_in_subcommand() { - #[derive(Args, PartialEq, Debug)] - struct Common { - arg: i32, - } - - #[derive(Args, PartialEq, Debug)] - struct Add { - #[clap(short)] - interactive: bool, - #[clap(flatten)] - common: Common, - } - - #[derive(Parser, PartialEq, Debug)] - enum Opt { - Fetch { - #[clap(short)] - all: bool, - #[clap(flatten)] - common: Common, - }, - - Add(Add), - } - - assert_eq!( - Opt::Fetch { - all: false, - common: Common { arg: 42 } - }, - Opt::try_parse_from(&["test", "fetch", "42"]).unwrap() - ); - assert_eq!( - Opt::Add(Add { - interactive: true, - common: Common { arg: 43 } - }), - Opt::try_parse_from(&["test", "add", "-i", "43"]).unwrap() - ); -} - -#[test] -fn update_args_with_flatten() { - #[derive(Args, PartialEq, Debug)] - struct Common { - arg: i32, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(flatten)] - common: Common, - } - - let mut opt = Opt { - common: Common { arg: 42 }, - }; - opt.try_update_from(&["test"]).unwrap(); - assert_eq!(Opt::try_parse_from(&["test", "42"]).unwrap(), opt); - - let mut opt = Opt { - common: Common { arg: 42 }, - }; - opt.try_update_from(&["test", "52"]).unwrap(); - assert_eq!(Opt::try_parse_from(&["test", "52"]).unwrap(), opt); -} - -#[derive(Subcommand, PartialEq, Debug)] -enum BaseCli { - Command1(Command1), -} - -#[derive(Args, PartialEq, Debug)] -struct Command1 { - arg1: i32, - - arg2: i32, -} - -#[derive(Args, PartialEq, Debug)] -struct Command2 { - arg2: i32, -} - -#[derive(Parser, PartialEq, Debug)] -enum Opt { - #[clap(flatten)] - BaseCli(BaseCli), - Command2(Command2), -} - -#[test] -fn merge_subcommands_with_flatten() { - assert_eq!( - Opt::BaseCli(BaseCli::Command1(Command1 { arg1: 42, arg2: 44 })), - Opt::try_parse_from(&["test", "command1", "42", "44"]).unwrap() - ); - assert_eq!( - Opt::Command2(Command2 { arg2: 43 }), - Opt::try_parse_from(&["test", "command2", "43"]).unwrap() - ); -} - -#[test] -fn update_subcommands_with_flatten() { - let mut opt = Opt::BaseCli(BaseCli::Command1(Command1 { arg1: 12, arg2: 14 })); - opt.try_update_from(&["test", "command1", "42", "44"]) - .unwrap(); - assert_eq!( - Opt::try_parse_from(&["test", "command1", "42", "44"]).unwrap(), - opt - ); - - let mut opt = Opt::BaseCli(BaseCli::Command1(Command1 { arg1: 12, arg2: 14 })); - opt.try_update_from(&["test", "command1", "42"]).unwrap(); - assert_eq!( - Opt::try_parse_from(&["test", "command1", "42", "14"]).unwrap(), - opt - ); - - let mut opt = Opt::BaseCli(BaseCli::Command1(Command1 { arg1: 12, arg2: 14 })); - opt.try_update_from(&["test", "command2", "43"]).unwrap(); - assert_eq!( - Opt::try_parse_from(&["test", "command2", "43"]).unwrap(), - opt - ); -} - -#[test] -fn flatten_with_doc_comment() { - #[derive(Args, PartialEq, Debug)] - struct Common { - /// This is an arg. Arg means "argument". Command line argument. - arg: i32, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - /// The very important comment that clippy had me put here. - /// It knows better. - #[clap(flatten)] - common: Common, - } - assert_eq!( - Opt { - common: Common { arg: 42 } - }, - Opt::try_parse_from(&["test", "42"]).unwrap() - ); - - let help = utils::get_help::(); - assert!(help.contains("This is an arg.")); - assert!(!help.contains("The very important")); -} - -#[test] -fn docstrings_ordering_with_multiple_clap() { - /// This is the docstring for Flattened - #[derive(Args)] - struct Flattened { - #[clap(long)] - foo: bool, - } - - /// This is the docstring for Command - #[derive(Parser)] - struct Command { - #[clap(flatten)] - flattened: Flattened, - } - - let short_help = utils::get_help::(); - - assert!(short_help.contains("This is the docstring for Command")); -} - -#[test] -fn docstrings_ordering_with_multiple_clap_partial() { - /// This is the docstring for Flattened - #[derive(Args)] - struct Flattened { - #[clap(long)] - foo: bool, - } - - #[derive(Parser)] - struct Command { - #[clap(flatten)] - flattened: Flattened, - } - - let short_help = utils::get_help::(); - - assert!(short_help.contains("This is the docstring for Flattened")); -} diff --git a/tests/derive/next/generic.rs b/tests/derive/next/generic.rs deleted file mode 100644 index 5d484295148..00000000000 --- a/tests/derive/next/generic.rs +++ /dev/null @@ -1,145 +0,0 @@ -use clap::{Args, Parser}; - -#[test] -fn generic_struct_flatten() { - #[derive(Args, PartialEq, Debug)] - struct Inner { - pub answer: isize, - } - - #[derive(Parser, PartialEq, Debug)] - struct Outer { - #[clap(flatten)] - pub inner: T, - } - - assert_eq!( - Outer { - inner: Inner { answer: 42 } - }, - Outer::parse_from(&["--answer", "42"]) - ) -} - -#[test] -fn generic_struct_flatten_w_where_clause() { - #[derive(Args, PartialEq, Debug)] - struct Inner { - pub answer: isize, - } - - #[derive(Parser, PartialEq, Debug)] - struct Outer - where - T: Args, - { - #[clap(flatten)] - pub inner: T, - } - - assert_eq!( - Outer { - inner: Inner { answer: 42 } - }, - Outer::parse_from(&["--answer", "42"]) - ) -} - -#[test] -fn generic_enum() { - #[derive(Args, PartialEq, Debug)] - struct Inner { - pub answer: isize, - } - - #[derive(Parser, PartialEq, Debug)] - enum GenericEnum { - Start(T), - Stop, - } - - assert_eq!( - GenericEnum::Start(Inner { answer: 42 }), - GenericEnum::parse_from(&["test", "start", "42"]) - ) -} - -#[test] -fn generic_enum_w_where_clause() { - #[derive(Args, PartialEq, Debug)] - struct Inner { - pub answer: isize, - } - - #[derive(Parser, PartialEq, Debug)] - enum GenericEnum - where - T: Args, - { - Start(T), - Stop, - } - - assert_eq!( - GenericEnum::Start(Inner { answer: 42 }), - GenericEnum::parse_from(&["test", "start", "42"]) - ) -} - -#[test] -fn generic_w_fromstr_trait_bound() { - use std::str::FromStr; - - #[derive(Parser, PartialEq, Debug)] - struct Opt - where - T: FromStr + Send + Sync + Clone + 'static, - ::Err: std::error::Error + Sync + Send + 'static, - { - answer: T, - } - - assert_eq!( - Opt:: { answer: 42 }, - Opt::::parse_from(&["--answer", "42"]) - ) -} - -#[test] -fn generic_wo_trait_bound() { - use std::time::Duration; - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - answer: isize, - #[clap(skip)] - took: Option, - } - - assert_eq!( - Opt:: { - answer: 42, - took: None - }, - Opt::::parse_from(&["--answer", "42"]) - ) -} - -#[test] -fn generic_where_clause_w_trailing_comma() { - use std::str::FromStr; - - #[derive(Parser, PartialEq, Debug)] - struct Opt - where - T: FromStr + Send + Sync + Clone + 'static, - ::Err: std::error::Error + Sync + Send + 'static, - { - pub answer: T, - } - - assert_eq!( - Opt:: { answer: 42 }, - Opt::::parse_from(&["--answer", "42"]) - ) -} diff --git a/tests/derive/next/help.rs b/tests/derive/next/help.rs deleted file mode 100644 index 14b6a876d77..00000000000 --- a/tests/derive/next/help.rs +++ /dev/null @@ -1,520 +0,0 @@ -use clap::{AppSettings, Args, CommandFactory, Parser, Subcommand}; - -#[test] -fn arg_help_heading_applied() { - #[derive(Debug, Clone, Parser)] - struct CliOptions { - #[clap(long)] - #[clap(help_heading = Some("HEADING A"))] - should_be_in_section_a: u32, - - #[clap(long)] - no_section: u32, - } - - let cmd = CliOptions::command(); - - let should_be_in_section_a = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_section_a") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-section-a") - .unwrap() - }; - assert_eq!(should_be_in_section_a.get_help_heading(), Some("HEADING A")); - - let should_be_in_section_b = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "no_section") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "no-section") - .unwrap() - }; - assert_eq!(should_be_in_section_b.get_help_heading(), None); -} - -#[test] -fn app_help_heading_applied() { - #[derive(Debug, Clone, Parser)] - #[clap(next_help_heading = "DEFAULT")] - struct CliOptions { - #[clap(long)] - #[clap(help_heading = Some("HEADING A"))] - should_be_in_section_a: u32, - - #[clap(long)] - should_be_in_default_section: u32, - } - - let cmd = CliOptions::command(); - - let should_be_in_section_a = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_section_a") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-section-a") - .unwrap() - }; - assert_eq!(should_be_in_section_a.get_help_heading(), Some("HEADING A")); - - let should_be_in_default_section = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_default_section") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-default-section") - .unwrap() - }; - assert_eq!( - should_be_in_default_section.get_help_heading(), - Some("DEFAULT") - ); -} - -#[test] -fn app_help_heading_flattened() { - // Used to help track the cause in tests - #![allow(clippy::enum_variant_names)] - - #[derive(Debug, Clone, Parser)] - struct CliOptions { - #[clap(flatten)] - options_a: OptionsA, - - #[clap(flatten)] - options_b: OptionsB, - - #[clap(subcommand)] - sub_a: SubA, - - #[clap(long)] - should_be_in_default_section: u32, - } - - #[derive(Debug, Clone, Args)] - #[clap(next_help_heading = "HEADING A")] - struct OptionsA { - #[clap(long)] - should_be_in_section_a: u32, - } - - #[derive(Debug, Clone, Args)] - #[clap(next_help_heading = "HEADING B")] - struct OptionsB { - #[clap(long)] - should_be_in_section_b: u32, - } - - #[derive(Debug, Clone, Subcommand)] - enum SubA { - #[clap(flatten)] - SubB(SubB), - #[clap(subcommand)] - SubC(SubC), - SubAOne, - #[clap(next_help_heading = "SUB A")] - SubATwo { - should_be_in_sub_a: u32, - }, - } - - #[derive(Debug, Clone, Subcommand)] - enum SubB { - #[clap(next_help_heading = "SUB B")] - SubBOne { should_be_in_sub_b: u32 }, - } - - #[derive(Debug, Clone, Subcommand)] - enum SubC { - #[clap(next_help_heading = "SUB C")] - SubCOne { should_be_in_sub_c: u32 }, - } - - let cmd = CliOptions::command(); - - let should_be_in_section_a = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_section_a") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-section-a") - .unwrap() - }; - assert_eq!(should_be_in_section_a.get_help_heading(), Some("HEADING A")); - - let should_be_in_section_b = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_section_b") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-section-b") - .unwrap() - }; - assert_eq!(should_be_in_section_b.get_help_heading(), Some("HEADING B")); - - let should_be_in_default_section = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_default_section") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-default-section") - .unwrap() - }; - assert_eq!(should_be_in_default_section.get_help_heading(), None); - - let sub_a_two = cmd.find_subcommand("sub-a-two").unwrap(); - - let should_be_in_sub_a = if cfg!(feature = "unstable-v4") { - sub_a_two - .get_arguments() - .find(|a| a.get_id() == "should_be_in_sub_a") - .unwrap() - } else { - sub_a_two - .get_arguments() - .find(|a| a.get_id() == "should-be-in-sub-a") - .unwrap() - }; - assert_eq!(should_be_in_sub_a.get_help_heading(), Some("SUB A")); - - let sub_b_one = cmd.find_subcommand("sub-b-one").unwrap(); - - let should_be_in_sub_b = if cfg!(feature = "unstable-v4") { - sub_b_one - .get_arguments() - .find(|a| a.get_id() == "should_be_in_sub_b") - .unwrap() - } else { - sub_b_one - .get_arguments() - .find(|a| a.get_id() == "should-be-in-sub-b") - .unwrap() - }; - assert_eq!(should_be_in_sub_b.get_help_heading(), Some("SUB B")); - - let sub_c = cmd.find_subcommand("sub-c").unwrap(); - let sub_c_one = sub_c.find_subcommand("sub-c-one").unwrap(); - - let should_be_in_sub_c = if cfg!(feature = "unstable-v4") { - sub_c_one - .get_arguments() - .find(|a| a.get_id() == "should_be_in_sub_c") - .unwrap() - } else { - sub_c_one - .get_arguments() - .find(|a| a.get_id() == "should-be-in-sub-c") - .unwrap() - }; - assert_eq!(should_be_in_sub_c.get_help_heading(), Some("SUB C")); -} - -#[test] -fn flatten_field_with_help_heading() { - #[derive(Debug, Clone, Parser)] - struct CliOptions { - #[clap(flatten)] - #[clap(next_help_heading = "HEADING A")] - options_a: OptionsA, - } - - #[derive(Debug, Clone, Args)] - struct OptionsA { - #[clap(long)] - should_be_in_section_a: u32, - } - - let cmd = CliOptions::command(); - - let should_be_in_section_a = if cfg!(feature = "unstable-v4") { - cmd.get_arguments() - .find(|a| a.get_id() == "should_be_in_section_a") - .unwrap() - } else { - cmd.get_arguments() - .find(|a| a.get_id() == "should-be-in-section-a") - .unwrap() - }; - assert_eq!(should_be_in_section_a.get_help_heading(), Some("HEADING A")); -} - -// The challenge with this test is creating an error situation not caught by `clap`'s error checking -// but by the code that `clap_derive` generates. -// -// Ultimately, the easiest way to confirm is to put a debug statement in the desired error path. -#[test] -fn derive_generated_error_has_full_context() { - #[derive(Debug, Parser)] - #[clap(subcommand_negates_reqs = true)] - struct Opts { - #[clap(long)] - req_str: String, - - #[clap(subcommand)] - cmd: Option, - } - - #[derive(Debug, Parser)] - enum SubCommands { - Sub { - #[clap(short, long, action = clap::ArgAction::Count)] - verbose: u8, - }, - } - - let result = Opts::try_parse_from(&["test", "sub"]); - assert!( - result.is_err(), - "`SubcommandsNegateReqs` with non-optional `req_str` should fail: {:?}", - result.unwrap() - ); - - if cfg!(feature = "unstable-v4") { - let expected = r#"error: The following required argument was not provided: req_str - -USAGE: - clap --req-str - clap - -For more information try --help -"#; - assert_eq!(result.unwrap_err().to_string(), expected); - } else { - let expected = r#"error: The following required argument was not provided: req-str - -USAGE: - clap --req-str - clap - -For more information try --help -"#; - assert_eq!(result.unwrap_err().to_string(), expected); - } -} - -#[test] -fn derive_order_next_order() { - static HELP: &str = "test 1.2 - -USAGE: - test [OPTIONS] - -OPTIONS: - --flag-b first flag - --option-b first option - -h, --help Print help information - -V, --version Print version information - --flag-a second flag - --option-a second option -"; - - #[derive(Parser, Debug)] - #[clap(name = "test", version = "1.2")] - #[clap(setting = AppSettings::DeriveDisplayOrder)] - struct Args { - #[clap(flatten)] - a: A, - #[clap(flatten)] - b: B, - } - - #[derive(Args, Debug)] - #[clap(next_display_order = 10000)] - struct A { - /// second flag - #[clap(long)] - flag_a: bool, - /// second option - #[clap(long)] - option_a: Option, - } - - #[derive(Args, Debug)] - #[clap(next_display_order = 10)] - struct B { - /// first flag - #[clap(long)] - flag_b: bool, - /// first option - #[clap(long)] - option_b: Option, - } - - use clap::CommandFactory; - let mut cmd = Args::command(); - - let mut buffer: Vec = Default::default(); - cmd.write_help(&mut buffer).unwrap(); - let help = String::from_utf8(buffer).unwrap(); - snapbox::assert_eq(HELP, help); -} - -#[test] -fn derive_order_next_order_flatten() { - static HELP: &str = "test 1.2 - -USAGE: - test [OPTIONS] - -OPTIONS: - --flag-b first flag - --option-b first option - -h, --help Print help information - -V, --version Print version information - --flag-a second flag - --option-a second option -"; - - #[derive(Parser, Debug)] - #[clap(setting = AppSettings::DeriveDisplayOrder)] - #[clap(name = "test", version = "1.2")] - struct Args { - #[clap(flatten)] - #[clap(next_display_order = 10000)] - a: A, - #[clap(flatten)] - #[clap(next_display_order = 10)] - b: B, - } - - #[derive(Args, Debug)] - struct A { - /// second flag - #[clap(long)] - flag_a: bool, - /// second option - #[clap(long)] - option_a: Option, - } - - #[derive(Args, Debug)] - struct B { - /// first flag - #[clap(long)] - flag_b: bool, - /// first option - #[clap(long)] - option_b: Option, - } - - use clap::CommandFactory; - let mut cmd = Args::command(); - - let mut buffer: Vec = Default::default(); - cmd.write_help(&mut buffer).unwrap(); - let help = String::from_utf8(buffer).unwrap(); - snapbox::assert_eq(HELP, help); -} - -#[test] -fn derive_order_no_next_order() { - static HELP: &str = "test 1.2 - -USAGE: - test [OPTIONS] - -OPTIONS: - --flag-a first flag - --flag-b second flag - -h, --help Print help information - --option-a first option - --option-b second option - -V, --version Print version information -"; - - #[derive(Parser, Debug)] - #[clap(name = "test", version = "1.2")] - #[clap(setting = AppSettings::DeriveDisplayOrder)] - #[clap(next_display_order = None)] - struct Args { - #[clap(flatten)] - a: A, - #[clap(flatten)] - b: B, - } - - #[derive(Args, Debug)] - struct A { - /// first flag - #[clap(long)] - flag_a: bool, - /// first option - #[clap(long)] - option_a: Option, - } - - #[derive(Args, Debug)] - struct B { - /// second flag - #[clap(long)] - flag_b: bool, - /// second option - #[clap(long)] - option_b: Option, - } - - use clap::CommandFactory; - let mut cmd = Args::command(); - - let mut buffer: Vec = Default::default(); - cmd.write_help(&mut buffer).unwrap(); - let help = String::from_utf8(buffer).unwrap(); - snapbox::assert_eq(HELP, help); -} - -#[test] -#[cfg(feature = "unstable-v4")] -fn derive_possible_value_help() { - static HELP: &str = "clap -Application help - -USAGE: - clap - -ARGS: - - Argument help - - Possible values: - - foo: Foo help - - bar: Bar help - -OPTIONS: - -h, --help - Print help information -"; - - /// Application help - #[derive(Parser, PartialEq, Debug)] - struct Args { - /// Argument help - #[clap(value_enum)] - arg: ArgChoice, - } - - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - /// Foo help - Foo, - /// Bar help - Bar, - } - - use clap::CommandFactory; - let mut cmd = Args::command(); - - let mut buffer: Vec = Default::default(); - cmd.write_long_help(&mut buffer).unwrap(); - let help = String::from_utf8(buffer).unwrap(); - snapbox::assert_eq(HELP, help); -} diff --git a/tests/derive/next/issues.rs b/tests/derive/next/issues.rs deleted file mode 100644 index d2c01363b14..00000000000 --- a/tests/derive/next/issues.rs +++ /dev/null @@ -1,130 +0,0 @@ -// https://github.com/TeXitoi/structopt/issues/{NUMBER} - -use crate::utils; - -use clap::{ArgGroup, Args, Parser, Subcommand}; - -#[test] -fn issue_151_groups_within_subcommands() { - #[derive(Args, Debug)] - #[clap(group = ArgGroup::new("verb").required(true).multiple(true))] - struct Opt { - #[clap(long, group = "verb")] - foo: Option, - #[clap(long, group = "verb")] - bar: Option, - } - - #[derive(Debug, Parser)] - struct Cli { - #[clap(flatten)] - a: Opt, - } - - assert!(Cli::try_parse_from(&["test"]).is_err()); - assert!(Cli::try_parse_from(&["test", "--foo=v1"]).is_ok()); - assert!(Cli::try_parse_from(&["test", "--bar=v2"]).is_ok()); - assert!(Cli::try_parse_from(&["test", "--zebra=v3"]).is_err()); - assert!(Cli::try_parse_from(&["test", "--foo=v1", "--bar=v2"]).is_ok()); -} - -#[test] -fn issue_289() { - #[derive(Parser)] - #[clap(infer_subcommands = true)] - enum Args { - SomeCommand { - #[clap(subcommand)] - sub: SubSubCommand, - }, - AnotherCommand, - } - - #[derive(Subcommand)] - #[clap(infer_subcommands = true)] - enum SubSubCommand { - TestCommand, - } - - assert!(Args::try_parse_from(&["test", "some-command", "test-command"]).is_ok()); - assert!(Args::try_parse_from(&["test", "some", "test-command"]).is_ok()); - assert!(Args::try_parse_from(&["test", "some-command", "test"]).is_ok()); - assert!(Args::try_parse_from(&["test", "some", "test"]).is_ok()); -} - -#[test] -fn issue_324() { - fn my_version() -> &'static str { - "MY_VERSION" - } - - #[derive(Parser)] - #[clap(version = my_version())] - struct Opt { - #[clap(subcommand)] - _cmd: SubCommand, - } - - #[derive(Subcommand)] - enum SubCommand { - Start, - } - - let help = utils::get_long_help::(); - assert!(help.contains("MY_VERSION")); -} - -#[test] -fn issue_418() { - #[derive(Debug, Parser)] - struct Opts { - #[clap(subcommand)] - /// The command to run - command: Command, - } - - #[derive(Debug, Subcommand)] - enum Command { - /// Reticulate the splines - #[clap(visible_alias = "ret")] - Reticulate { - /// How many splines - num_splines: u8, - }, - /// Frobnicate the rest - #[clap(visible_alias = "frob")] - Frobnicate, - } - - let help = utils::get_long_help::(); - assert!(help.contains("Reticulate the splines [aliases: ret]")); -} - -#[test] -fn issue_490() { - use clap::Parser; - use std::iter::FromIterator; - use std::str::FromStr; - - struct U16ish; - impl FromStr for U16ish { - type Err = (); - fn from_str(_: &str) -> Result { - unimplemented!() - } - } - impl<'a> FromIterator<&'a U16ish> for Vec { - fn from_iter>(_: T) -> Self { - unimplemented!() - } - } - - #[derive(Parser, Debug)] - struct Opt { - opt_vec: Vec, - #[clap(long)] - opt_opt_vec: Option>, - } - - // Assert that it compiles -} diff --git a/tests/derive/next/macros.rs b/tests/derive/next/macros.rs deleted file mode 100644 index a2e671b4abc..00000000000 --- a/tests/derive/next/macros.rs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -use clap::Parser; - -// Tests that clap_derive properly detects an `Option` field -// that results from a macro expansion -#[test] -fn use_option() { - macro_rules! expand_ty { - ($name:ident: $ty:ty) => { - #[derive(Parser)] - struct Outer { - #[clap(short, long)] - #[allow(dead_code)] - $name: $ty, - } - }; - } - - expand_ty!(my_field: Option); -} - -#[test] -fn issue_447() { - macro_rules! Command { - ( $name:ident, [ - #[$meta:meta] $var:ident($inner:ty) - ] ) => { - #[derive(Debug, PartialEq, clap::Parser)] - enum $name { - #[$meta] - $var($inner), - } - }; - } - - Command! {GitCmd, [ - #[clap(external_subcommand)] - Ext(Vec) - ]} -} diff --git a/tests/derive/next/mod.rs b/tests/derive/next/mod.rs deleted file mode 100644 index 0c4e0303b0f..00000000000 --- a/tests/derive/next/mod.rs +++ /dev/null @@ -1,33 +0,0 @@ -#![cfg(feature = "derive")] -#![cfg(feature = "unstable-v4")] - -mod app_name; -mod arguments; -mod author_version_about; -mod basic; -mod boxed; -mod custom_string_parsers; -mod default_value; -mod deny_warnings; -mod doc_comments_help; -mod explicit_name_no_renaming; -mod flags; -mod flatten; -mod generic; -mod help; -mod issues; -mod macros; -mod naming; -mod nested_subcommands; -mod non_literal_attributes; -mod options; -mod privacy; -mod raw_bool_literal; -mod raw_idents; -mod rename_all_env; -mod skip; -mod subcommands; -mod type_alias_regressions; -mod utf8; -mod utils; -mod value_enum; diff --git a/tests/derive/next/naming.rs b/tests/derive/next/naming.rs deleted file mode 100644 index e3018a02f7c..00000000000 --- a/tests/derive/next/naming.rs +++ /dev/null @@ -1,354 +0,0 @@ -use clap::Parser; - -#[test] -fn test_standalone_long_generates_kebab_case() { - #[derive(Parser, Debug, PartialEq)] - #[allow(non_snake_case)] - struct Opt { - #[clap(long)] - FOO_OPTION: bool, - } - - assert_eq!( - Opt { FOO_OPTION: true }, - Opt::try_parse_from(&["test", "--foo-option"]).unwrap() - ); -} - -#[test] -fn test_custom_long_overwrites_default_name() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(long = "foo")] - foo_option: bool, - } - - assert_eq!( - Opt { foo_option: true }, - Opt::try_parse_from(&["test", "--foo"]).unwrap() - ); -} - -#[test] -fn test_standalone_long_uses_previous_defined_custom_name() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(name = "foo", long)] - foo_option: bool, - } - - assert_eq!( - Opt { foo_option: true }, - Opt::try_parse_from(&["test", "--foo"]).unwrap() - ); -} - -#[test] -fn test_standalone_long_ignores_afterwards_defined_custom_name() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(long, name = "foo")] - foo_option: bool, - } - - assert_eq!( - Opt { foo_option: true }, - Opt::try_parse_from(&["test", "--foo-option"]).unwrap() - ); -} - -#[test] -fn test_standalone_short_generates_kebab_case() { - #[derive(Parser, Debug, PartialEq)] - #[allow(non_snake_case)] - struct Opt { - #[clap(short)] - FOO_OPTION: bool, - } - - assert_eq!( - Opt { FOO_OPTION: true }, - Opt::try_parse_from(&["test", "-f"]).unwrap() - ); -} - -#[test] -fn test_custom_short_overwrites_default_name() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(short = 'o')] - foo_option: bool, - } - - assert_eq!( - Opt { foo_option: true }, - Opt::try_parse_from(&["test", "-o"]).unwrap() - ); -} - -#[test] -fn test_standalone_short_uses_previous_defined_custom_name() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(name = "option", short)] - foo_option: bool, - } - - assert_eq!( - Opt { foo_option: true }, - Opt::try_parse_from(&["test", "-o"]).unwrap() - ); -} - -#[test] -fn test_standalone_short_ignores_afterwards_defined_custom_name() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(short, name = "option")] - foo_option: bool, - } - - assert_eq!( - Opt { foo_option: true }, - Opt::try_parse_from(&["test", "-f"]).unwrap() - ); -} - -#[test] -fn test_standalone_long_uses_previous_defined_casing() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(rename_all = "screaming_snake", long)] - foo_option: bool, - } - - assert_eq!( - Opt { foo_option: true }, - Opt::try_parse_from(&["test", "--FOO_OPTION"]).unwrap() - ); -} - -#[test] -fn test_standalone_short_uses_previous_defined_casing() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(rename_all = "screaming_snake", short)] - foo_option: bool, - } - - assert_eq!( - Opt { foo_option: true }, - Opt::try_parse_from(&["test", "-F"]).unwrap() - ); -} - -#[test] -fn test_standalone_long_works_with_verbatim_casing() { - #[derive(Parser, Debug, PartialEq)] - #[allow(non_snake_case)] - struct Opt { - #[clap(rename_all = "verbatim", long)] - _fOO_oPtiON: bool, - } - - assert_eq!( - Opt { _fOO_oPtiON: true }, - Opt::try_parse_from(&["test", "--_fOO_oPtiON"]).unwrap() - ); -} - -#[test] -fn test_standalone_short_works_with_verbatim_casing() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(rename_all = "verbatim", short)] - _foo: bool, - } - - assert_eq!( - Opt { _foo: true }, - Opt::try_parse_from(&["test", "-_"]).unwrap() - ); -} - -#[test] -fn test_rename_all_is_propagated_from_struct_to_fields() { - #[derive(Parser, Debug, PartialEq)] - #[clap(rename_all = "screaming_snake")] - struct Opt { - #[clap(long)] - foo: bool, - } - - assert_eq!( - Opt { foo: true }, - Opt::try_parse_from(&["test", "--FOO"]).unwrap() - ); -} - -#[test] -fn test_rename_all_is_not_propagated_from_struct_into_flattened() { - #[derive(Parser, Debug, PartialEq)] - #[clap(rename_all = "screaming_snake")] - struct Opt { - #[clap(flatten)] - foo: Foo, - } - - #[derive(Parser, Debug, PartialEq)] - struct Foo { - #[clap(long)] - foo: bool, - } - - assert_eq!( - Opt { - foo: Foo { foo: true } - }, - Opt::try_parse_from(&["test", "--foo"]).unwrap() - ); -} - -#[test] -fn test_lower_is_renamed() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(rename_all = "lower", long)] - foo_option: bool, - } - - assert_eq!( - Opt { foo_option: true }, - Opt::try_parse_from(&["test", "--foooption"]).unwrap() - ); -} - -#[test] -fn test_upper_is_renamed() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(rename_all = "upper", long)] - foo_option: bool, - } - - assert_eq!( - Opt { foo_option: true }, - Opt::try_parse_from(&["test", "--FOOOPTION"]).unwrap() - ); -} - -#[test] -fn test_single_word_enum_variant_is_default_renamed_into_kebab_case() { - #[derive(Parser, Debug, PartialEq)] - enum Opt { - Command { foo: u32 }, - } - - assert_eq!( - Opt::Command { foo: 0 }, - Opt::try_parse_from(&["test", "command", "0"]).unwrap() - ); -} - -#[test] -fn test_multi_word_enum_variant_is_renamed() { - #[derive(Parser, Debug, PartialEq)] - enum Opt { - FirstCommand { foo: u32 }, - } - - assert_eq!( - Opt::FirstCommand { foo: 0 }, - Opt::try_parse_from(&["test", "first-command", "0"]).unwrap() - ); -} - -#[test] -fn test_rename_all_is_not_propagated_from_struct_into_subcommand() { - #[derive(Parser, Debug, PartialEq)] - #[clap(rename_all = "screaming_snake")] - struct Opt { - #[clap(subcommand)] - foo: Foo, - } - - #[derive(Parser, Debug, PartialEq)] - enum Foo { - Command { - #[clap(long)] - foo: bool, - }, - } - - assert_eq!( - Opt { - foo: Foo::Command { foo: true } - }, - Opt::try_parse_from(&["test", "command", "--foo"]).unwrap() - ); -} - -#[test] -fn test_rename_all_is_propagated_from_enum_to_variants() { - #[derive(Parser, Debug, PartialEq)] - #[clap(rename_all = "screaming_snake")] - enum Opt { - FirstVariant, - SecondVariant { - #[clap(long)] - foo: String, - }, - } - - assert_eq!( - Opt::FirstVariant, - Opt::try_parse_from(&["test", "FIRST_VARIANT"]).unwrap() - ); -} - -#[test] -fn test_rename_all_is_propagated_from_enum_to_variant_fields() { - #[derive(Parser, Debug, PartialEq)] - #[clap(rename_all = "screaming_snake")] - enum Opt { - FirstVariant, - SecondVariant { - #[clap(long)] - foo: String, - }, - } - - assert_eq!( - Opt::SecondVariant { - foo: "value".into() - }, - Opt::try_parse_from(&["test", "SECOND_VARIANT", "--FOO", "value"]).unwrap() - ); -} - -#[test] -fn test_rename_all_is_propagation_can_be_overridden() { - #[derive(Parser, Debug, PartialEq)] - #[clap(rename_all = "screaming_snake")] - enum Opt { - #[clap(rename_all = "kebab_case")] - FirstVariant { - #[clap(long)] - foo_option: bool, - }, - SecondVariant { - #[clap(rename_all = "kebab_case", long)] - foo_option: bool, - }, - } - - assert_eq!( - Opt::FirstVariant { foo_option: true }, - Opt::try_parse_from(&["test", "first-variant", "--foo-option"]).unwrap() - ); - - assert_eq!( - Opt::SecondVariant { foo_option: true }, - Opt::try_parse_from(&["test", "SECOND_VARIANT", "--foo-option"]).unwrap() - ); -} diff --git a/tests/derive/next/nested_subcommands.rs b/tests/derive/next/nested_subcommands.rs deleted file mode 100644 index e5e32bfff7a..00000000000 --- a/tests/derive/next/nested_subcommands.rs +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -use clap::{Parser, Subcommand}; - -#[derive(Parser, PartialEq, Debug)] -struct Opt { - #[clap(short, long)] - force: bool, - #[clap(short, long, action = clap::ArgAction::Count)] - verbose: u8, - #[clap(subcommand)] - cmd: Sub, -} - -#[derive(Subcommand, PartialEq, Debug)] -enum Sub { - Fetch {}, - Add {}, -} - -#[derive(Parser, PartialEq, Debug)] -struct Opt2 { - #[clap(short, long)] - force: bool, - #[clap(short, long, action = clap::ArgAction::Count)] - verbose: u8, - #[clap(subcommand)] - cmd: Option, -} - -#[test] -fn test_no_cmd() { - let result = Opt::try_parse_from(&["test"]); - assert!(result.is_err()); - - assert_eq!( - Opt2 { - force: false, - verbose: 0, - cmd: None - }, - Opt2::try_parse_from(&["test"]).unwrap() - ); -} - -#[test] -fn test_fetch() { - assert_eq!( - Opt { - force: false, - verbose: 3, - cmd: Sub::Fetch {} - }, - Opt::try_parse_from(&["test", "-vvv", "fetch"]).unwrap() - ); - assert_eq!( - Opt { - force: true, - verbose: 0, - cmd: Sub::Fetch {} - }, - Opt::try_parse_from(&["test", "--force", "fetch"]).unwrap() - ); -} - -#[test] -fn test_add() { - assert_eq!( - Opt { - force: false, - verbose: 0, - cmd: Sub::Add {} - }, - Opt::try_parse_from(&["test", "add"]).unwrap() - ); - assert_eq!( - Opt { - force: false, - verbose: 2, - cmd: Sub::Add {} - }, - Opt::try_parse_from(&["test", "-vv", "add"]).unwrap() - ); -} - -#[test] -fn test_badinput() { - let result = Opt::try_parse_from(&["test", "badcmd"]); - assert!(result.is_err()); - let result = Opt::try_parse_from(&["test", "add", "--verbose"]); - assert!(result.is_err()); - let result = Opt::try_parse_from(&["test", "--badopt", "add"]); - assert!(result.is_err()); - let result = Opt::try_parse_from(&["test", "add", "--badopt"]); - assert!(result.is_err()); -} - -#[derive(Parser, PartialEq, Debug)] -struct Opt3 { - #[clap(short, long)] - all: bool, - #[clap(subcommand)] - cmd: Sub2, -} - -#[derive(Subcommand, PartialEq, Debug)] -enum Sub2 { - Foo { - file: String, - #[clap(subcommand)] - cmd: Sub3, - }, - Bar {}, -} - -#[derive(Subcommand, PartialEq, Debug)] -enum Sub3 { - Baz {}, - Quux {}, -} - -#[test] -fn test_subsubcommand() { - assert_eq!( - Opt3 { - all: true, - cmd: Sub2::Foo { - file: "lib.rs".to_string(), - cmd: Sub3::Quux {} - } - }, - Opt3::try_parse_from(&["test", "--all", "foo", "lib.rs", "quux"]).unwrap() - ); -} - -#[derive(Parser, PartialEq, Debug)] -enum SubSubCmdWithOption { - Remote { - #[clap(subcommand)] - cmd: Option, - }, - Stash { - #[clap(subcommand)] - cmd: Stash, - }, -} -#[derive(Subcommand, PartialEq, Debug)] -enum Remote { - Add { name: String, url: String }, - Remove { name: String }, -} - -#[derive(Subcommand, PartialEq, Debug)] -enum Stash { - Save, - Pop, -} - -#[test] -fn sub_sub_cmd_with_option() { - fn make(args: &[&str]) -> Option { - SubSubCmdWithOption::try_parse_from(args).ok() - } - assert_eq!( - Some(SubSubCmdWithOption::Remote { cmd: None }), - make(&["", "remote"]) - ); - assert_eq!( - Some(SubSubCmdWithOption::Remote { - cmd: Some(Remote::Add { - name: "origin".into(), - url: "http".into() - }) - }), - make(&["", "remote", "add", "origin", "http"]) - ); - assert_eq!( - Some(SubSubCmdWithOption::Stash { cmd: Stash::Save }), - make(&["", "stash", "save"]) - ); - assert_eq!(None, make(&["", "stash"])); -} diff --git a/tests/derive/next/non_literal_attributes.rs b/tests/derive/next/non_literal_attributes.rs deleted file mode 100644 index 97879994418..00000000000 --- a/tests/derive/next/non_literal_attributes.rs +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -use clap::{ErrorKind, Parser}; -use std::num::ParseIntError; - -pub const DISPLAY_ORDER: usize = 2; - -// Check if the global settings compile -#[derive(Parser, Debug, PartialEq, Eq)] -#[clap(allow_hyphen_values = true)] -struct Opt { - #[clap( - long = "x", - display_order = DISPLAY_ORDER, - next_line_help = true, - default_value = "0", - require_equals = true, - )] - x: i32, - - #[clap(short = 'l', long = "level", aliases = &["set-level", "lvl"])] - level: String, - - #[clap(long("values"))] - values: Vec, - - #[clap(name = "FILE", requires_if("FILE", "values"))] - files: Vec, -} - -#[test] -fn test_slice() { - assert_eq!( - Opt { - x: 0, - level: "1".to_string(), - files: Vec::new(), - values: vec![], - }, - Opt::try_parse_from(&["test", "-l", "1"]).unwrap() - ); - assert_eq!( - Opt { - x: 0, - level: "1".to_string(), - files: Vec::new(), - values: vec![], - }, - Opt::try_parse_from(&["test", "--level", "1"]).unwrap() - ); - assert_eq!( - Opt { - x: 0, - level: "1".to_string(), - files: Vec::new(), - values: vec![], - }, - Opt::try_parse_from(&["test", "--set-level", "1"]).unwrap() - ); - assert_eq!( - Opt { - x: 0, - level: "1".to_string(), - files: Vec::new(), - values: vec![], - }, - Opt::try_parse_from(&["test", "--lvl", "1"]).unwrap() - ); -} - -#[test] -fn test_multi_args() { - assert_eq!( - Opt { - x: 0, - level: "1".to_string(), - files: vec!["file".to_string()], - values: vec![], - }, - Opt::try_parse_from(&["test", "-l", "1", "file"]).unwrap() - ); - assert_eq!( - Opt { - x: 0, - level: "1".to_string(), - files: vec!["FILE".to_string()], - values: vec![1], - }, - Opt::try_parse_from(&["test", "-l", "1", "--values", "1", "--", "FILE"]).unwrap() - ); -} - -#[test] -fn test_multi_args_fail() { - let result = Opt::try_parse_from(&["test", "-l", "1", "--", "FILE"]); - assert!(result.is_err()); -} - -#[test] -fn test_bool() { - assert_eq!( - Opt { - x: 1, - level: "1".to_string(), - files: vec![], - values: vec![], - }, - Opt::try_parse_from(&["test", "-l", "1", "--x=1"]).unwrap() - ); - let result = Opt::try_parse_from(&["test", "-l", "1", "--x", "1"]); - assert!(result.is_err()); - assert_eq!(result.unwrap_err().kind(), ErrorKind::NoEquals); -} - -fn parse_hex(input: &str) -> Result { - u64::from_str_radix(input, 16) -} - -#[derive(Parser, PartialEq, Debug)] -struct HexOpt { - #[clap(short, value_parser = parse_hex)] - number: u64, -} - -#[test] -fn test_parse_hex_function_path() { - assert_eq!( - HexOpt { number: 5 }, - HexOpt::try_parse_from(&["test", "-n", "5"]).unwrap() - ); - assert_eq!( - HexOpt { - number: 0x00ab_cdef - }, - HexOpt::try_parse_from(&["test", "-n", "abcdef"]).unwrap() - ); - - let err = HexOpt::try_parse_from(&["test", "-n", "gg"]).unwrap_err(); - assert!( - err.to_string().contains("invalid digit found in string"), - "{}", - err - ); -} diff --git a/tests/derive/next/options.rs b/tests/derive/next/options.rs deleted file mode 100644 index c15cf95057c..00000000000 --- a/tests/derive/next/options.rs +++ /dev/null @@ -1,520 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -#![allow(clippy::option_option)] - -use crate::utils; - -use clap::{Parser, Subcommand}; - -#[test] -fn required_option() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short, long)] - arg: i32, - } - assert_eq!( - Opt { arg: 42 }, - Opt::try_parse_from(&["test", "-a42"]).unwrap() - ); - assert_eq!( - Opt { arg: 42 }, - Opt::try_parse_from(&["test", "-a", "42"]).unwrap() - ); - assert_eq!( - Opt { arg: 42 }, - Opt::try_parse_from(&["test", "--arg", "42"]).unwrap() - ); - assert_eq!( - Opt { arg: 42 }, - Opt::try_parse_from(&["test", "--arg", "24", "--arg", "42"]).unwrap() - ); - assert!(Opt::try_parse_from(&["test"]).is_err()); -} - -#[test] -fn option_with_default() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short, default_value = "42")] - arg: i32, - } - assert_eq!( - Opt { arg: 24 }, - Opt::try_parse_from(&["test", "-a24"]).unwrap() - ); - assert_eq!( - Opt { arg: 42 }, - Opt::try_parse_from(&["test", "-a", "24", "-a", "42"]).unwrap() - ); - assert_eq!(Opt { arg: 42 }, Opt::try_parse_from(&["test"]).unwrap()); -} - -#[test] -fn option_with_raw_default() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short, default_value = "42")] - arg: i32, - } - assert_eq!( - Opt { arg: 24 }, - Opt::try_parse_from(&["test", "-a24"]).unwrap() - ); - assert_eq!( - Opt { arg: 42 }, - Opt::try_parse_from(&["test", "-a", "24", "-a", "42"]).unwrap() - ); - assert_eq!(Opt { arg: 42 }, Opt::try_parse_from(&["test"]).unwrap()); -} - -#[test] -fn option_from_str() { - #[derive(Clone, Debug, PartialEq)] - struct A; - - impl std::str::FromStr for A { - type Err = std::convert::Infallible; - - fn from_str(_: &str) -> Result { - Ok(A) - } - } - - #[derive(Debug, Parser, PartialEq)] - struct Opt { - a: Option, - } - - assert_eq!(Opt { a: None }, Opt::try_parse_from(&["test"]).unwrap()); - assert_eq!( - Opt { a: Some(A) }, - Opt::try_parse_from(&["test", "foo"]).unwrap() - ); -} - -#[test] -fn vec_from_str() { - #[derive(Clone, Debug, PartialEq)] - struct A; - - impl std::str::FromStr for A { - type Err = std::convert::Infallible; - - fn from_str(_: &str) -> Result { - Ok(A) - } - } - - #[derive(Debug, Parser, PartialEq)] - struct Opt { - a: Vec, - } - - assert_eq!( - Opt { a: Vec::new() }, - Opt::try_parse_from(&["test"]).unwrap() - ); - assert_eq!( - Opt { a: vec![A] }, - Opt::try_parse_from(&["test", "foo"]).unwrap() - ); -} - -#[test] -fn option_vec_from_str() { - #[derive(Clone, Debug, PartialEq)] - struct A; - - impl std::str::FromStr for A { - type Err = std::convert::Infallible; - - fn from_str(_: &str) -> Result { - Ok(A) - } - } - - #[derive(Debug, Parser, PartialEq)] - struct Opt { - #[clap(short)] - a: Option>, - } - - assert_eq!(Opt { a: None }, Opt::try_parse_from(&["test"]).unwrap()); - assert_eq!( - Opt { a: Some(vec![A]) }, - Opt::try_parse_from(&["test", "-a", "foo"]).unwrap() - ); -} - -#[test] -fn option_type_is_optional() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short)] - arg: Option, - } - assert_eq!( - Opt { arg: Some(42) }, - Opt::try_parse_from(&["test", "-a42"]).unwrap() - ); - assert_eq!( - Opt { arg: Some(42) }, - Opt::try_parse_from(&["test", "-a", "24", "-a", "42"]).unwrap() - ); - assert_eq!(Opt { arg: None }, Opt::try_parse_from(&["test"]).unwrap()); -} - -#[test] -fn required_with_option_type() { - #[derive(Debug, PartialEq, Eq, Parser)] - #[clap(subcommand_negates_reqs = true)] - struct Opt { - #[clap(required = true)] - req_str: Option, - - #[clap(subcommand)] - cmd: Option, - } - - #[derive(Debug, PartialEq, Eq, Subcommand)] - enum SubCommands { - ExSub { - #[clap(short, long, action = clap::ArgAction::Count)] - verbose: u8, - }, - } - - assert_eq!( - Opt { - req_str: Some(("arg").into()), - cmd: None, - }, - Opt::try_parse_from(&["test", "arg"]).unwrap() - ); - - assert_eq!( - Opt { - req_str: None, - cmd: Some(SubCommands::ExSub { verbose: 1 }), - }, - Opt::try_parse_from(&["test", "ex-sub", "-v"]).unwrap() - ); - - assert!(Opt::try_parse_from(&["test"]).is_err()); -} - -#[test] -fn ignore_qualified_option_type() { - fn parser(s: &str) -> Result, std::convert::Infallible> { - Ok(Some(s.to_string())) - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_parser = parser)] - arg: ::std::option::Option, - } - - assert_eq!( - Opt { - arg: Some("success".into()) - }, - Opt::try_parse_from(&["test", "success"]).unwrap() - ); -} - -#[test] -fn option_option_type_is_optional_value() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short)] - #[allow(clippy::option_option)] - arg: Option>, - } - assert_eq!( - Opt { - arg: Some(Some(42)) - }, - Opt::try_parse_from(&["test", "-a42"]).unwrap() - ); - assert_eq!( - Opt { arg: Some(None) }, - Opt::try_parse_from(&["test", "-a"]).unwrap() - ); - assert_eq!( - Opt { - arg: Some(Some(42)) - }, - Opt::try_parse_from(&["test", "-a", "24", "-a", "42"]).unwrap() - ); - assert_eq!(Opt { arg: None }, Opt::try_parse_from(&["test"]).unwrap()); -} - -#[test] -fn option_option_type_help() { - #[derive(Parser, Debug)] - struct Opt { - #[clap(long, value_name = "val")] - arg: Option>, - } - let help = utils::get_help::(); - assert!(help.contains("--arg []")); - assert!(!help.contains("--arg []...")); -} - -#[test] -fn two_option_option_types() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short)] - arg: Option>, - - #[clap(long)] - field: Option>, - } - assert_eq!( - Opt { - arg: Some(Some(42)), - field: Some(Some("f".into())) - }, - Opt::try_parse_from(&["test", "-a42", "--field", "f"]).unwrap() - ); - assert_eq!( - Opt { - arg: Some(Some(42)), - field: Some(None) - }, - Opt::try_parse_from(&["test", "-a42", "--field"]).unwrap() - ); - assert_eq!( - Opt { - arg: Some(None), - field: Some(None) - }, - Opt::try_parse_from(&["test", "-a", "--field"]).unwrap() - ); - assert_eq!( - Opt { - arg: Some(None), - field: Some(Some("f".into())) - }, - Opt::try_parse_from(&["test", "-a", "--field", "f"]).unwrap() - ); - assert_eq!( - Opt { - arg: None, - field: Some(None) - }, - Opt::try_parse_from(&["test", "--field"]).unwrap() - ); - assert_eq!( - Opt { - arg: None, - field: None - }, - Opt::try_parse_from(&["test"]).unwrap() - ); -} - -#[test] -fn vec_type_is_multiple_occurrences() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short, long)] - arg: Vec, - } - assert_eq!( - Opt { arg: vec![24] }, - Opt::try_parse_from(&["test", "-a24"]).unwrap() - ); - assert_eq!(Opt { arg: vec![] }, Opt::try_parse_from(&["test"]).unwrap()); - assert_eq!( - Opt { arg: vec![24, 42] }, - Opt::try_parse_from(&["test", "-a", "24", "-a", "42"]).unwrap() - ); -} - -#[test] -fn vec_type_with_required() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short, long, required = true)] - arg: Vec, - } - assert_eq!( - Opt { arg: vec![24] }, - Opt::try_parse_from(&["test", "-a24"]).unwrap() - ); - assert!(Opt::try_parse_from(&["test"]).is_err()); - assert_eq!( - Opt { arg: vec![24, 42] }, - Opt::try_parse_from(&["test", "-a", "24", "-a", "42"]).unwrap() - ); -} - -#[test] -fn vec_type_with_multiple_values_only() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short, long, multiple_values(true))] - arg: Vec, - } - assert_eq!( - Opt { arg: vec![24] }, - Opt::try_parse_from(&["test", "-a24"]).unwrap() - ); - assert_eq!(Opt { arg: vec![] }, Opt::try_parse_from(&["test"]).unwrap()); - assert_eq!( - Opt { arg: vec![24, 42] }, - Opt::try_parse_from(&["test", "-a", "24", "42"]).unwrap() - ); -} - -#[test] -fn ignore_qualified_vec_type() { - fn parser(s: &str) -> Result, std::convert::Infallible> { - Ok(vec![s.to_string()]) - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_parser = parser)] - arg: ::std::vec::Vec, - } - - assert_eq!( - Opt { - arg: vec!["success".into()] - }, - Opt::try_parse_from(&["test", "success"]).unwrap() - ); -} - -#[test] -fn option_vec_type() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short)] - arg: Option>, - } - assert_eq!( - Opt { arg: Some(vec![1]) }, - Opt::try_parse_from(&["test", "-a", "1"]).unwrap() - ); - - assert_eq!( - Opt { - arg: Some(vec![1, 2]) - }, - Opt::try_parse_from(&["test", "-a", "1", "-a", "2"]).unwrap() - ); - - assert_eq!(Opt { arg: None }, Opt::try_parse_from(&["test"]).unwrap()); -} - -#[test] -fn option_vec_type_structopt_behavior() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short, long, multiple_values(true), min_values(0))] - arg: Option>, - } - assert_eq!( - Opt { arg: Some(vec![1]) }, - Opt::try_parse_from(&["test", "-a", "1"]).unwrap() - ); - - assert_eq!( - Opt { - arg: Some(vec![1, 2]) - }, - Opt::try_parse_from(&["test", "-a", "1", "2"]).unwrap() - ); - - assert_eq!( - Opt { arg: Some(vec![]) }, - Opt::try_parse_from(&["test", "-a"]).unwrap() - ); - - assert_eq!(Opt { arg: None }, Opt::try_parse_from(&["test"]).unwrap()); -} - -#[test] -fn two_option_vec_types() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short)] - arg: Option>, - - #[clap(short)] - b: Option>, - } - - assert_eq!( - Opt { - arg: Some(vec![1]), - b: None, - }, - Opt::try_parse_from(&["test", "-a", "1"]).unwrap() - ); - - assert_eq!( - Opt { - arg: Some(vec![1]), - b: Some(vec![1]) - }, - Opt::try_parse_from(&["test", "-a", "1", "-b", "1"]).unwrap() - ); - - assert_eq!( - Opt { - arg: Some(vec![1, 2]), - b: Some(vec![1, 2]) - }, - Opt::try_parse_from(&["test", "-a", "1", "-a", "2", "-b", "1", "-b", "2"]).unwrap() - ); - - assert_eq!( - Opt { arg: None, b: None }, - Opt::try_parse_from(&["test"]).unwrap() - ); -} - -#[test] -fn explicit_value_parser() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(long, value_parser = clap::value_parser!(i32))] - arg: i32, - } - assert_eq!( - Opt { arg: 42 }, - Opt::try_parse_from(&["test", "--arg", "42"]).unwrap() - ); -} - -#[test] -fn implicit_value_parser() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(long)] - arg: i32, - } - assert_eq!( - Opt { arg: 42 }, - Opt::try_parse_from(&["test", "--arg", "42"]).unwrap() - ); -} diff --git a/tests/derive/next/privacy.rs b/tests/derive/next/privacy.rs deleted file mode 100644 index c8f66127b2d..00000000000 --- a/tests/derive/next/privacy.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -mod options { - use clap::Parser; - - #[derive(Debug, Parser)] - pub struct Options { - #[clap(subcommand)] - pub subcommand: super::subcommands::SubCommand, - } -} - -mod subcommands { - use clap::Subcommand; - - #[derive(Debug, Subcommand)] - pub enum SubCommand { - /// foo - Foo { - /// foo - bars: String, - }, - } -} diff --git a/tests/derive/next/raw_bool_literal.rs b/tests/derive/next/raw_bool_literal.rs deleted file mode 100644 index 0e572aa8c67..00000000000 --- a/tests/derive/next/raw_bool_literal.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use clap::Parser; - -#[test] -fn raw_bool_literal() { - #[derive(Parser, Debug, PartialEq)] - #[clap(name = "raw_bool")] - struct Opt { - #[clap(raw(false))] - a: String, - #[clap(raw(true))] - b: String, - } - - assert_eq!( - Opt { - a: "one".into(), - b: "--help".into() - }, - Opt::try_parse_from(&["test", "one", "--", "--help"]).unwrap() - ); -} diff --git a/tests/derive/next/raw_idents.rs b/tests/derive/next/raw_idents.rs deleted file mode 100644 index 12c5d1658f0..00000000000 --- a/tests/derive/next/raw_idents.rs +++ /dev/null @@ -1,24 +0,0 @@ -use clap::Parser; - -#[test] -fn raw_idents() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(short, long)] - r#type: String, - } - - assert_eq!( - Opt { - r#type: "long".into() - }, - Opt::try_parse_from(&["test", "--type", "long"]).unwrap() - ); - - assert_eq!( - Opt { - r#type: "short".into() - }, - Opt::try_parse_from(&["test", "-t", "short"]).unwrap() - ); -} diff --git a/tests/derive/next/rename_all_env.rs b/tests/derive/next/rename_all_env.rs deleted file mode 100644 index 20d4f40c728..00000000000 --- a/tests/derive/next/rename_all_env.rs +++ /dev/null @@ -1,47 +0,0 @@ -#![cfg(feature = "env")] - -use crate::utils; - -use clap::Parser; - -#[test] -fn it_works() { - #[derive(Debug, PartialEq, Parser)] - #[clap(rename_all_env = "kebab")] - struct BehaviorModel { - #[clap(env)] - be_nice: String, - } - - let help = utils::get_help::(); - assert!(help.contains("[env: be-nice=]")); -} - -#[test] -fn default_is_screaming() { - #[derive(Debug, PartialEq, Parser)] - struct BehaviorModel { - #[clap(env)] - be_nice: String, - } - - let help = utils::get_help::(); - assert!(help.contains("[env: BE_NICE=]")); -} - -#[test] -fn overridable() { - #[derive(Debug, PartialEq, Parser)] - #[clap(rename_all_env = "kebab")] - struct BehaviorModel { - #[clap(env)] - be_nice: String, - - #[clap(rename_all_env = "pascal", env)] - be_aggressive: String, - } - - let help = utils::get_help::(); - assert!(help.contains("[env: be-nice=]")); - assert!(help.contains("[env: BeAggressive=]")); -} diff --git a/tests/derive/next/skip.rs b/tests/derive/next/skip.rs deleted file mode 100644 index 160b0578f72..00000000000 --- a/tests/derive/next/skip.rs +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use clap::Parser; - -#[test] -fn skip_1() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(short)] - x: u32, - #[clap(skip)] - s: u32, - } - - assert!(Opt::try_parse_from(&["test", "-x", "10", "20"]).is_err()); - - let mut opt = Opt::try_parse_from(&["test", "-x", "10"]).unwrap(); - assert_eq!( - opt, - Opt { - x: 10, - s: 0, // default - } - ); - opt.s = 42; - - opt.update_from(&["test", "-x", "22"]); - - assert_eq!(opt, Opt { x: 22, s: 42 }); -} - -#[test] -fn skip_2() { - #[derive(Parser, Debug, PartialEq)] - struct Opt { - #[clap(short)] - x: u32, - #[clap(skip)] - ss: String, - #[clap(skip)] - sn: u8, - - y: u32, - #[clap(skip)] - sz: u16, - - t: u32, - } - - assert_eq!( - Opt::try_parse_from(&["test", "-x", "10", "20", "30"]).unwrap(), - Opt { - x: 10, - ss: String::from(""), - sn: 0, - y: 20, - sz: 0, - t: 30, - } - ); -} - -#[test] -fn skip_enum() { - #[derive(Debug, PartialEq)] - #[allow(unused)] - enum Kind { - A, - B, - } - - impl Default for Kind { - fn default() -> Self { - Kind::B - } - } - - #[derive(Parser, Debug, PartialEq)] - pub struct Opt { - #[clap(long, short)] - number: u32, - #[clap(skip)] - k: Kind, - #[clap(skip)] - v: Vec, - } - - assert_eq!( - Opt::try_parse_from(&["test", "-n", "10"]).unwrap(), - Opt { - number: 10, - k: Kind::B, - v: vec![], - } - ); -} - -#[test] -fn skip_help_doc_comments() { - #[derive(Parser, Debug, PartialEq)] - pub struct Opt { - #[clap(skip, help = "internal_stuff")] - a: u32, - - #[clap(skip, long_help = "internal_stuff\ndo not touch")] - b: u32, - - /// Not meant to be used by clap. - /// - /// I want a default here. - #[clap(skip)] - c: u32, - - #[clap(short)] - n: u32, - } - - assert_eq!( - Opt::try_parse_from(&["test", "-n", "10"]).unwrap(), - Opt { - n: 10, - a: 0, - b: 0, - c: 0, - } - ); -} - -#[test] -fn skip_val() { - #[derive(Parser, Debug, PartialEq)] - pub struct Opt { - #[clap(long, short)] - number: u32, - - #[clap(skip = "key")] - k: String, - - #[clap(skip = vec![1, 2, 3])] - v: Vec, - } - - assert_eq!( - Opt::try_parse_from(&["test", "-n", "10"]).unwrap(), - Opt { - number: 10, - k: "key".to_string(), - v: vec![1, 2, 3] - } - ); -} diff --git a/tests/derive/next/subcommands.rs b/tests/derive/next/subcommands.rs deleted file mode 100644 index 9b3a69bef18..00000000000 --- a/tests/derive/next/subcommands.rs +++ /dev/null @@ -1,609 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// This work was derived from Structopt (https://github.com/TeXitoi/structopt) -// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the -// MIT/Apache 2.0 license. - -use crate::utils; - -use clap::{Args, Parser, Subcommand}; - -#[derive(Parser, PartialEq, Debug)] -enum Opt { - /// Fetch stuff from GitHub - Fetch { - #[clap(long)] - all: bool, - /// Overwrite local branches. - #[clap(short, long)] - force: bool, - - repo: String, - }, - - Add { - #[clap(short, long)] - interactive: bool, - #[clap(short, long)] - verbose: bool, - }, -} - -#[test] -fn test_fetch() { - assert_eq!( - Opt::Fetch { - all: true, - force: false, - repo: "origin".to_string() - }, - Opt::try_parse_from(&["test", "fetch", "--all", "origin"]).unwrap() - ); - assert_eq!( - Opt::Fetch { - all: false, - force: true, - repo: "origin".to_string() - }, - Opt::try_parse_from(&["test", "fetch", "-f", "origin"]).unwrap() - ); -} - -#[test] -fn test_add() { - assert_eq!( - Opt::Add { - interactive: false, - verbose: false - }, - Opt::try_parse_from(&["test", "add"]).unwrap() - ); - assert_eq!( - Opt::Add { - interactive: true, - verbose: true - }, - Opt::try_parse_from(&["test", "add", "-i", "-v"]).unwrap() - ); -} - -#[test] -fn test_no_parse() { - let result = Opt::try_parse_from(&["test", "badcmd", "-i", "-v"]); - assert!(result.is_err()); - - let result = Opt::try_parse_from(&["test", "add", "--badoption"]); - assert!(result.is_err()); - - let result = Opt::try_parse_from(&["test"]); - assert!(result.is_err()); -} - -#[derive(Parser, PartialEq, Debug)] -enum Opt2 { - DoSomething { arg: String }, -} - -#[test] -/// This test is specifically to make sure that hyphenated subcommands get -/// processed correctly. -fn test_hyphenated_subcommands() { - assert_eq!( - Opt2::DoSomething { - arg: "blah".to_string() - }, - Opt2::try_parse_from(&["test", "do-something", "blah"]).unwrap() - ); -} - -#[derive(Parser, PartialEq, Debug)] -enum Opt3 { - Add, - Init, - Fetch, -} - -#[test] -fn test_null_commands() { - assert_eq!(Opt3::Add, Opt3::try_parse_from(&["test", "add"]).unwrap()); - assert_eq!(Opt3::Init, Opt3::try_parse_from(&["test", "init"]).unwrap()); - assert_eq!( - Opt3::Fetch, - Opt3::try_parse_from(&["test", "fetch"]).unwrap() - ); -} - -#[derive(Parser, PartialEq, Debug)] -#[clap(about = "Not shown")] -struct Add { - file: String, -} -/// Not shown -#[derive(Parser, PartialEq, Debug)] -struct Fetch { - remote: String, -} -#[derive(Parser, PartialEq, Debug)] -enum Opt4 { - // Not shown - /// Add a file - Add(Add), - Init, - /// download history from remote - Fetch(Fetch), -} - -#[test] -fn test_tuple_commands() { - assert_eq!( - Opt4::Add(Add { - file: "f".to_string() - }), - Opt4::try_parse_from(&["test", "add", "f"]).unwrap() - ); - assert_eq!(Opt4::Init, Opt4::try_parse_from(&["test", "init"]).unwrap()); - assert_eq!( - Opt4::Fetch(Fetch { - remote: "origin".to_string() - }), - Opt4::try_parse_from(&["test", "fetch", "origin"]).unwrap() - ); - - let output = utils::get_long_help::(); - - assert!(output.contains("download history from remote")); - assert!(output.contains("Add a file")); - assert!(!output.contains("Not shown")); -} - -#[test] -fn global_passed_down() { - #[derive(Debug, PartialEq, Parser)] - struct Opt { - #[clap(global = true, long)] - other: bool, - #[clap(subcommand)] - sub: Subcommands, - } - - #[derive(Debug, PartialEq, Subcommand)] - enum Subcommands { - Add, - Global(GlobalCmd), - } - - #[derive(Debug, PartialEq, Args)] - struct GlobalCmd { - #[clap(from_global)] - other: bool, - } - - assert_eq!( - Opt::try_parse_from(&["test", "global"]).unwrap(), - Opt { - other: false, - sub: Subcommands::Global(GlobalCmd { other: false }) - } - ); - - assert_eq!( - Opt::try_parse_from(&["test", "global", "--other"]).unwrap(), - Opt { - other: true, - sub: Subcommands::Global(GlobalCmd { other: true }) - } - ); -} - -#[test] -fn external_subcommand() { - #[derive(Debug, PartialEq, Parser)] - struct Opt { - #[clap(subcommand)] - sub: Subcommands, - } - - #[derive(Debug, PartialEq, Subcommand)] - enum Subcommands { - Add, - Remove, - #[clap(external_subcommand)] - Other(Vec), - } - - assert_eq!( - Opt::try_parse_from(&["test", "add"]).unwrap(), - Opt { - sub: Subcommands::Add - } - ); - - assert_eq!( - Opt::try_parse_from(&["test", "remove"]).unwrap(), - Opt { - sub: Subcommands::Remove - } - ); - - assert!(Opt::try_parse_from(&["test"]).is_err()); - - assert_eq!( - Opt::try_parse_from(&["test", "git", "status"]).unwrap(), - Opt { - sub: Subcommands::Other(vec!["git".into(), "status".into()]) - } - ); -} - -#[test] -fn external_subcommand_os_string() { - use std::ffi::OsString; - - #[derive(Debug, PartialEq, Parser)] - struct Opt { - #[clap(subcommand)] - sub: Subcommands, - } - - #[derive(Debug, PartialEq, Subcommand)] - enum Subcommands { - #[clap(external_subcommand)] - Other(Vec), - } - - assert_eq!( - Opt::try_parse_from(&["test", "git", "status"]).unwrap(), - Opt { - sub: Subcommands::Other(vec!["git".into(), "status".into()]) - } - ); - - assert!(Opt::try_parse_from(&["test"]).is_err()); -} - -#[test] -fn external_subcommand_optional() { - #[derive(Debug, PartialEq, Parser)] - struct Opt { - #[clap(subcommand)] - sub: Option, - } - - #[derive(Debug, PartialEq, Subcommand)] - enum Subcommands { - #[clap(external_subcommand)] - Other(Vec), - } - - assert_eq!( - Opt::try_parse_from(&["test", "git", "status"]).unwrap(), - Opt { - sub: Some(Subcommands::Other(vec!["git".into(), "status".into()])) - } - ); - - assert_eq!(Opt::try_parse_from(&["test"]).unwrap(), Opt { sub: None }); -} - -#[test] -fn enum_in_enum_subsubcommand() { - #[derive(Parser, Debug, PartialEq)] - pub enum Opt { - #[clap(alias = "l")] - List, - #[clap(subcommand, alias = "d")] - Daemon(DaemonCommand), - } - - #[derive(Subcommand, Debug, PartialEq)] - pub enum DaemonCommand { - Start, - Stop, - } - - let result = Opt::try_parse_from(&["test"]); - assert!(result.is_err()); - - let result = Opt::try_parse_from(&["test", "list"]).unwrap(); - assert_eq!(Opt::List, result); - - let result = Opt::try_parse_from(&["test", "l"]).unwrap(); - assert_eq!(Opt::List, result); - - let result = Opt::try_parse_from(&["test", "daemon"]); - assert!(result.is_err()); - - let result = Opt::try_parse_from(&["test", "daemon", "start"]).unwrap(); - assert_eq!(Opt::Daemon(DaemonCommand::Start), result); - - let result = Opt::try_parse_from(&["test", "d", "start"]).unwrap(); - assert_eq!(Opt::Daemon(DaemonCommand::Start), result); -} - -#[test] -fn update_subcommands() { - #[derive(Parser, PartialEq, Debug)] - enum Opt { - Command1(Command1), - Command2(Command2), - } - - #[derive(Parser, PartialEq, Debug)] - struct Command1 { - arg1: i32, - - arg2: i32, - } - - #[derive(Parser, PartialEq, Debug)] - struct Command2 { - arg2: i32, - } - - // Full subcommand update - let mut opt = Opt::Command1(Command1 { arg1: 12, arg2: 14 }); - opt.try_update_from(&["test", "command1", "42", "44"]) - .unwrap(); - assert_eq!( - Opt::try_parse_from(&["test", "command1", "42", "44"]).unwrap(), - opt - ); - - // Partial subcommand update - let mut opt = Opt::Command1(Command1 { arg1: 12, arg2: 14 }); - opt.try_update_from(&["test", "command1", "42"]).unwrap(); - assert_eq!( - Opt::try_parse_from(&["test", "command1", "42", "14"]).unwrap(), - opt - ); - - // Change subcommand - let mut opt = Opt::Command1(Command1 { arg1: 12, arg2: 14 }); - opt.try_update_from(&["test", "command2", "43"]).unwrap(); - assert_eq!( - Opt::try_parse_from(&["test", "command2", "43"]).unwrap(), - opt - ); -} - -#[test] -fn update_sub_subcommands() { - #[derive(Parser, PartialEq, Debug)] - enum Opt { - #[clap(subcommand)] - Child1(Child1), - #[clap(subcommand)] - Child2(Child2), - } - - #[derive(Subcommand, PartialEq, Debug)] - enum Child1 { - Command1(Command1), - Command2(Command2), - } - - #[derive(Subcommand, PartialEq, Debug)] - enum Child2 { - Command1(Command1), - Command2(Command2), - } - - #[derive(Args, PartialEq, Debug)] - struct Command1 { - arg1: i32, - - arg2: i32, - } - - #[derive(Args, PartialEq, Debug)] - struct Command2 { - arg2: i32, - } - - // Full subcommand update - let mut opt = Opt::Child1(Child1::Command1(Command1 { arg1: 12, arg2: 14 })); - opt.try_update_from(&["test", "child1", "command1", "42", "44"]) - .unwrap(); - assert_eq!( - Opt::try_parse_from(&["test", "child1", "command1", "42", "44"]).unwrap(), - opt - ); - - // Partial subcommand update - let mut opt = Opt::Child1(Child1::Command1(Command1 { arg1: 12, arg2: 14 })); - opt.try_update_from(&["test", "child1", "command1", "42"]) - .unwrap(); - assert_eq!( - Opt::try_parse_from(&["test", "child1", "command1", "42", "14"]).unwrap(), - opt - ); - - // Partial subcommand update - let mut opt = Opt::Child1(Child1::Command1(Command1 { arg1: 12, arg2: 14 })); - opt.try_update_from(&["test", "child1", "command2", "43"]) - .unwrap(); - assert_eq!( - Opt::try_parse_from(&["test", "child1", "command2", "43"]).unwrap(), - opt - ); - - // Change subcommand - let mut opt = Opt::Child1(Child1::Command1(Command1 { arg1: 12, arg2: 14 })); - opt.try_update_from(&["test", "child2", "command2", "43"]) - .unwrap(); - assert_eq!( - Opt::try_parse_from(&["test", "child2", "command2", "43"]).unwrap(), - opt - ); -} - -#[test] -fn update_ext_subcommand() { - #[derive(Parser, PartialEq, Debug)] - enum Opt { - Command1(Command1), - Command2(Command2), - #[clap(external_subcommand)] - Ext(Vec), - } - - #[derive(Args, PartialEq, Debug)] - struct Command1 { - arg1: i32, - - arg2: i32, - } - - #[derive(Args, PartialEq, Debug)] - struct Command2 { - arg2: i32, - } - - // Full subcommand update - let mut opt = Opt::Ext(vec!["12".into(), "14".into()]); - opt.try_update_from(&["test", "ext", "42", "44"]).unwrap(); - assert_eq!( - Opt::try_parse_from(&["test", "ext", "42", "44"]).unwrap(), - opt - ); - - // No partial subcommand update - let mut opt = Opt::Ext(vec!["12".into(), "14".into()]); - opt.try_update_from(&["test", "ext", "42"]).unwrap(); - assert_eq!(Opt::try_parse_from(&["test", "ext", "42"]).unwrap(), opt); - - // Change subcommand - let mut opt = Opt::Ext(vec!["12".into(), "14".into()]); - opt.try_update_from(&["test", "command2", "43"]).unwrap(); - assert_eq!( - Opt::try_parse_from(&["test", "command2", "43"]).unwrap(), - opt - ); - - let mut opt = Opt::Command1(Command1 { arg1: 12, arg2: 14 }); - opt.try_update_from(&["test", "ext", "42", "44"]).unwrap(); - assert_eq!( - Opt::try_parse_from(&["test", "ext", "42", "44"]).unwrap(), - opt - ); -} -#[test] -fn subcommand_name_not_literal() { - fn get_name() -> &'static str { - "renamed" - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(subcommand)] - subcmd: SubCmd, - } - - #[derive(Subcommand, PartialEq, Debug)] - enum SubCmd { - #[clap(name = get_name())] - SubCmd1, - } - - assert!(Opt::try_parse_from(&["test", "renamed"]).is_ok()); -} - -#[test] -fn skip_subcommand() { - #[derive(Debug, PartialEq, Parser)] - struct Opt { - #[clap(subcommand)] - sub: Subcommands, - } - - #[derive(Debug, PartialEq, Subcommand)] - enum Subcommands { - Add, - Remove, - - #[allow(dead_code)] - #[clap(skip)] - Skip, - } - - assert_eq!( - Opt::try_parse_from(&["test", "add"]).unwrap(), - Opt { - sub: Subcommands::Add - } - ); - - assert_eq!( - Opt::try_parse_from(&["test", "remove"]).unwrap(), - Opt { - sub: Subcommands::Remove - } - ); - - let res = Opt::try_parse_from(&["test", "skip"]); - assert_eq!(res.unwrap_err().kind(), clap::ErrorKind::UnknownArgument,); -} - -#[test] -#[cfg(feature = "unstable-v4")] -fn built_in_subcommand_escaped() { - #[derive(Debug, PartialEq, Parser)] - enum Command { - Install { - arg: Option, - }, - #[clap(external_subcommand)] - Custom(Vec), - } - - assert_eq!( - Command::try_parse_from(&["test", "install", "arg"]).unwrap(), - Command::Install { - arg: Some(String::from("arg")) - } - ); - assert_eq!( - Command::try_parse_from(&["test", "--", "install"]).unwrap(), - Command::Custom(vec![String::from("install")]) - ); - assert_eq!( - Command::try_parse_from(&["test", "--", "install", "arg"]).unwrap(), - Command::Custom(vec![String::from("install"), String::from("arg")]) - ); -} - -#[test] -#[cfg(not(feature = "unstable-v4"))] -fn built_in_subcommand_escaped() { - #[derive(Debug, PartialEq, Parser)] - enum Command { - Install { - arg: Option, - }, - #[clap(external_subcommand)] - Custom(Vec), - } - - assert_eq!( - Command::try_parse_from(&["test", "install", "arg"]).unwrap(), - Command::Install { - arg: Some(String::from("arg")) - } - ); - assert_eq!( - Command::try_parse_from(&["test", "--", "install"]).unwrap(), - Command::Install { arg: None } - ); - assert_eq!( - Command::try_parse_from(&["test", "--", "install", "arg"]).unwrap(), - Command::Install { arg: None } - ); -} diff --git a/tests/derive/next/type_alias_regressions.rs b/tests/derive/next/type_alias_regressions.rs deleted file mode 100644 index a66f4fa8bae..00000000000 --- a/tests/derive/next/type_alias_regressions.rs +++ /dev/null @@ -1,35 +0,0 @@ -//! Regression test to ensure that type aliases do not cause compilation failures. -#![allow(deprecated)] - -use clap::{Parser, Subcommand, ValueEnum}; - -// Result type alias -#[allow(dead_code)] -type Result = std::result::Result>; - -type Option = std::option::Option; - -#[derive(Parser)] -pub struct Opts { - another_string: String, - #[clap(subcommand)] - command: Command, - #[clap(short, long, value_enum)] - choice: ArgChoice, -} - -#[derive(Subcommand, PartialEq, Debug)] -enum Command { - DoSomething { arg: Option }, -} - -#[derive(ValueEnum, PartialEq, Debug, Clone)] -enum ArgChoice { - Foo, - Bar, -} - -#[test] -fn type_alias_regressions() { - Opts::try_parse_from(["test", "value", "--choice=foo", "do-something"]).unwrap(); -} diff --git a/tests/derive/next/utf8.rs b/tests/derive/next/utf8.rs deleted file mode 100644 index dac3b45f903..00000000000 --- a/tests/derive/next/utf8.rs +++ /dev/null @@ -1,225 +0,0 @@ -#![cfg(not(windows))] - -use clap::{ErrorKind, Parser}; -use std::ffi::OsString; -use std::os::unix::ffi::OsStringExt; - -#[derive(Parser, Debug, PartialEq, Eq)] -struct Positional { - arg: String, -} - -#[derive(Parser, Debug, PartialEq, Eq)] -struct Named { - #[clap(short, long)] - arg: String, -} - -#[test] -fn invalid_utf8_strict_positional() { - let m = Positional::try_parse_from(vec![OsString::from(""), OsString::from_vec(vec![0xe9])]); - assert!(m.is_err()); - assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8); -} - -#[test] -fn invalid_utf8_strict_option_short_space() { - let m = Named::try_parse_from(vec![ - OsString::from(""), - OsString::from("-a"), - OsString::from_vec(vec![0xe9]), - ]); - assert!(m.is_err()); - assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8); -} - -#[test] -fn invalid_utf8_strict_option_short_equals() { - let m = Named::try_parse_from(vec![ - OsString::from(""), - OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9]), - ]); - assert!(m.is_err()); - assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8); -} - -#[test] -fn invalid_utf8_strict_option_short_no_space() { - let m = Named::try_parse_from(vec![ - OsString::from(""), - OsString::from_vec(vec![0x2d, 0x61, 0xe9]), - ]); - assert!(m.is_err()); - assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8); -} - -#[test] -fn invalid_utf8_strict_option_long_space() { - let m = Named::try_parse_from(vec![ - OsString::from(""), - OsString::from("--arg"), - OsString::from_vec(vec![0xe9]), - ]); - assert!(m.is_err()); - assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8); -} - -#[test] -fn invalid_utf8_strict_option_long_equals() { - let m = Named::try_parse_from(vec![ - OsString::from(""), - OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9]), - ]); - assert!(m.is_err()); - assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8); -} - -#[derive(Parser, Debug, PartialEq, Eq)] -struct PositionalOs { - arg: OsString, -} - -#[derive(Parser, Debug, PartialEq, Eq)] -struct NamedOs { - #[clap(short, long)] - arg: OsString, -} - -#[test] -fn invalid_utf8_positional() { - let r = PositionalOs::try_parse_from(vec![OsString::from(""), OsString::from_vec(vec![0xe9])]); - assert_eq!( - r.unwrap(), - PositionalOs { - arg: OsString::from_vec(vec![0xe9]) - } - ); -} - -#[test] -fn invalid_utf8_option_short_space() { - let r = NamedOs::try_parse_from(vec![ - OsString::from(""), - OsString::from("-a"), - OsString::from_vec(vec![0xe9]), - ]); - assert_eq!( - r.unwrap(), - NamedOs { - arg: OsString::from_vec(vec![0xe9]) - } - ); -} - -#[test] -fn invalid_utf8_option_short_equals() { - let r = NamedOs::try_parse_from(vec![ - OsString::from(""), - OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9]), - ]); - assert_eq!( - r.unwrap(), - NamedOs { - arg: OsString::from_vec(vec![0xe9]) - } - ); -} - -#[test] -fn invalid_utf8_option_short_no_space() { - let r = NamedOs::try_parse_from(vec![ - OsString::from(""), - OsString::from_vec(vec![0x2d, 0x61, 0xe9]), - ]); - assert_eq!( - r.unwrap(), - NamedOs { - arg: OsString::from_vec(vec![0xe9]) - } - ); -} - -#[test] -fn invalid_utf8_option_long_space() { - let r = NamedOs::try_parse_from(vec![ - OsString::from(""), - OsString::from("--arg"), - OsString::from_vec(vec![0xe9]), - ]); - assert_eq!( - r.unwrap(), - NamedOs { - arg: OsString::from_vec(vec![0xe9]) - } - ); -} - -#[test] -fn invalid_utf8_option_long_equals() { - let r = NamedOs::try_parse_from(vec![ - OsString::from(""), - OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9]), - ]); - assert_eq!( - r.unwrap(), - NamedOs { - arg: OsString::from_vec(vec![0xe9]) - } - ); -} - -#[derive(Debug, PartialEq, Parser)] -enum External { - #[clap(external_subcommand)] - Other(Vec), -} - -#[test] -fn refuse_invalid_utf8_subcommand_with_allow_external_subcommands() { - let m = External::try_parse_from(vec![ - OsString::from(""), - OsString::from_vec(vec![0xe9]), - OsString::from("normal"), - ]); - assert!(m.is_err()); - assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8); -} - -#[test] -fn refuse_invalid_utf8_subcommand_args_with_allow_external_subcommands() { - let m = External::try_parse_from(vec![ - OsString::from(""), - OsString::from("subcommand"), - OsString::from("normal"), - OsString::from_vec(vec![0xe9]), - OsString::from("--another_normal"), - ]); - assert!(m.is_err()); - assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8); -} - -#[derive(Debug, PartialEq, Parser)] -enum ExternalOs { - #[clap(external_subcommand)] - Other(Vec), -} - -#[test] -fn allow_invalid_utf8_subcommand_args_with_allow_external_subcommands() { - let m = ExternalOs::try_parse_from(vec![ - OsString::from(""), - OsString::from("subcommand"), - OsString::from("normal"), - OsString::from_vec(vec![0xe9]), - OsString::from("--another_normal"), - ]); - assert_eq!( - m.unwrap(), - ExternalOs::Other(vec![ - OsString::from("subcommand"), - OsString::from("normal"), - OsString::from_vec(vec![0xe9]), - OsString::from("--another_normal"), - ]) - ); -} diff --git a/tests/derive/next/utils.rs b/tests/derive/next/utils.rs deleted file mode 100644 index 6b649c3e07c..00000000000 --- a/tests/derive/next/utils.rs +++ /dev/null @@ -1,56 +0,0 @@ -// Hi, future me (or whoever you are)! -// -// Yes, we do need this attr. -// No, the warnings cannot be fixed otherwise. -// Accept and endure. Do not touch. -#![allow(unused)] - -use clap::CommandFactory; - -pub fn get_help() -> String { - let mut output = Vec::new(); - ::command() - .write_help(&mut output) - .unwrap(); - let output = String::from_utf8(output).unwrap(); - - eprintln!("\n%%% HELP %%%:=====\n{}\n=====\n", output); - eprintln!("\n%%% HELP (DEBUG) %%%:=====\n{:?}\n=====\n", output); - - output -} - -pub fn get_long_help() -> String { - let mut output = Vec::new(); - ::command() - .write_long_help(&mut output) - .unwrap(); - let output = String::from_utf8(output).unwrap(); - - eprintln!("\n%%% LONG_HELP %%%:=====\n{}\n=====\n", output); - eprintln!("\n%%% LONG_HELP (DEBUG) %%%:=====\n{:?}\n=====\n", output); - - output -} - -pub fn get_subcommand_long_help(subcmd: &str) -> String { - let mut output = Vec::new(); - ::command() - .get_subcommands_mut() - .find(|s| s.get_name() == subcmd) - .unwrap() - .write_long_help(&mut output) - .unwrap(); - let output = String::from_utf8(output).unwrap(); - - eprintln!( - "\n%%% SUBCOMMAND `{}` HELP %%%:=====\n{}\n=====\n", - subcmd, output - ); - eprintln!( - "\n%%% SUBCOMMAND `{}` HELP (DEBUG) %%%:=====\n{:?}\n=====\n", - subcmd, output - ); - - output -} diff --git a/tests/derive/next/value_enum.rs b/tests/derive/next/value_enum.rs deleted file mode 100644 index ca9faaa52ca..00000000000 --- a/tests/derive/next/value_enum.rs +++ /dev/null @@ -1,526 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) , -// Kevin Knapp (@kbknapp) , and -// Ana Hobden (@hoverbear) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -use clap::Parser; - -#[test] -fn basic() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - Foo, - Bar, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum)] - arg: ArgChoice, - } - - assert_eq!( - Opt { - arg: ArgChoice::Foo - }, - Opt::try_parse_from(&["", "foo"]).unwrap() - ); - assert_eq!( - Opt { - arg: ArgChoice::Bar - }, - Opt::try_parse_from(&["", "bar"]).unwrap() - ); - assert!(Opt::try_parse_from(&["", "fOo"]).is_err()); -} - -#[test] -fn default_value() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - Foo, - Bar, - } - - impl Default for ArgChoice { - fn default() -> Self { - Self::Bar - } - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum, default_value_t)] - arg: ArgChoice, - } - - assert_eq!( - Opt { - arg: ArgChoice::Foo - }, - Opt::try_parse_from(&["", "foo"]).unwrap() - ); - assert_eq!( - Opt { - arg: ArgChoice::Bar - }, - Opt::try_parse_from(&["", "bar"]).unwrap() - ); - assert_eq!( - Opt { - arg: ArgChoice::Bar - }, - Opt::try_parse_from(&[""]).unwrap() - ); -} - -#[test] -fn multi_word_is_renamed_kebab() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - #[allow(non_camel_case_types)] - enum ArgChoice { - FooBar, - BAR_BAZ, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum)] - arg: ArgChoice, - } - - assert_eq!( - Opt { - arg: ArgChoice::FooBar - }, - Opt::try_parse_from(&["", "foo-bar"]).unwrap() - ); - assert_eq!( - Opt { - arg: ArgChoice::BAR_BAZ - }, - Opt::try_parse_from(&["", "bar-baz"]).unwrap() - ); - assert!(Opt::try_parse_from(&["", "FooBar"]).is_err()); -} - -#[test] -fn variant_with_defined_casing() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - #[clap(rename_all = "screaming_snake")] - FooBar, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum)] - arg: ArgChoice, - } - - assert_eq!( - Opt { - arg: ArgChoice::FooBar - }, - Opt::try_parse_from(&["", "FOO_BAR"]).unwrap() - ); - assert!(Opt::try_parse_from(&["", "FooBar"]).is_err()); -} - -#[test] -fn casing_is_propagated_from_parent() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - #[clap(rename_all = "screaming_snake")] - enum ArgChoice { - FooBar, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum)] - arg: ArgChoice, - } - - assert_eq!( - Opt { - arg: ArgChoice::FooBar - }, - Opt::try_parse_from(&["", "FOO_BAR"]).unwrap() - ); - assert!(Opt::try_parse_from(&["", "FooBar"]).is_err()); -} - -#[test] -fn casing_propagation_is_overridden() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - #[clap(rename_all = "screaming_snake")] - enum ArgChoice { - #[clap(rename_all = "camel")] - FooBar, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum)] - arg: ArgChoice, - } - - assert_eq!( - Opt { - arg: ArgChoice::FooBar - }, - Opt::try_parse_from(&["", "fooBar"]).unwrap() - ); - assert!(Opt::try_parse_from(&["", "FooBar"]).is_err()); - assert!(Opt::try_parse_from(&["", "FOO_BAR"]).is_err()); -} - -#[test] -fn ignore_case() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - Foo, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum, ignore_case(true))] - arg: ArgChoice, - } - - assert_eq!( - Opt { - arg: ArgChoice::Foo - }, - Opt::try_parse_from(&["", "foo"]).unwrap() - ); - assert_eq!( - Opt { - arg: ArgChoice::Foo - }, - Opt::try_parse_from(&["", "fOo"]).unwrap() - ); -} - -#[test] -fn ignore_case_set_to_false() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - Foo, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum, ignore_case(false))] - arg: ArgChoice, - } - - assert_eq!( - Opt { - arg: ArgChoice::Foo - }, - Opt::try_parse_from(&["", "foo"]).unwrap() - ); - assert!(Opt::try_parse_from(&["", "fOo"]).is_err()); -} - -#[test] -fn alias() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - #[clap(alias = "TOTP")] - Totp, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum, ignore_case(false))] - arg: ArgChoice, - } - - assert_eq!( - Opt { - arg: ArgChoice::Totp - }, - Opt::try_parse_from(&["", "totp"]).unwrap() - ); - assert_eq!( - Opt { - arg: ArgChoice::Totp - }, - Opt::try_parse_from(&["", "TOTP"]).unwrap() - ); -} - -#[test] -fn multiple_alias() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - #[clap(alias = "TOTP", alias = "t")] - Totp, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum, ignore_case(false))] - arg: ArgChoice, - } - - assert_eq!( - Opt { - arg: ArgChoice::Totp - }, - Opt::try_parse_from(&["", "totp"]).unwrap() - ); - assert_eq!( - Opt { - arg: ArgChoice::Totp - }, - Opt::try_parse_from(&["", "TOTP"]).unwrap() - ); - assert_eq!( - Opt { - arg: ArgChoice::Totp - }, - Opt::try_parse_from(&["", "t"]).unwrap() - ); -} - -#[test] -fn skip_variant() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - #[allow(dead_code)] // silence warning about `Baz` being unused - enum ArgChoice { - Foo, - Bar, - #[clap(skip)] - Baz, - } - - assert_eq!( - ::value_variants() - .iter() - .map(clap::ValueEnum::to_possible_value) - .map(Option::unwrap) - .collect::>(), - vec![ - clap::PossibleValue::new("foo"), - clap::PossibleValue::new("bar") - ] - ); - - { - use clap::ValueEnum; - assert!(ArgChoice::from_str("foo", true).is_ok()); - assert!(ArgChoice::from_str("bar", true).is_ok()); - assert!(ArgChoice::from_str("baz", true).is_err()); - } -} - -#[test] -fn skip_non_unit_variant() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - #[allow(dead_code)] // silence warning about `Baz` being unused - enum ArgChoice { - Foo, - Bar, - #[clap(skip)] - Baz(usize), - } - - assert_eq!( - ::value_variants() - .iter() - .map(clap::ValueEnum::to_possible_value) - .map(Option::unwrap) - .collect::>(), - vec![ - clap::PossibleValue::new("foo"), - clap::PossibleValue::new("bar") - ] - ); - - { - use clap::ValueEnum; - assert!(ArgChoice::from_str("foo", true).is_ok()); - assert!(ArgChoice::from_str("bar", true).is_ok()); - assert!(ArgChoice::from_str("baz", true).is_err()); - } -} - -#[test] -fn from_str_invalid() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - Foo, - } - - { - use clap::ValueEnum; - assert!(ArgChoice::from_str("bar", true).is_err()); - } -} - -#[test] -fn option_type() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - Foo, - Bar, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum)] - arg: Option, - } - - assert_eq!(Opt { arg: None }, Opt::try_parse_from(&[""]).unwrap()); - assert_eq!( - Opt { - arg: Some(ArgChoice::Foo) - }, - Opt::try_parse_from(&["", "foo"]).unwrap() - ); - assert_eq!( - Opt { - arg: Some(ArgChoice::Bar) - }, - Opt::try_parse_from(&["", "bar"]).unwrap() - ); - assert!(Opt::try_parse_from(&["", "fOo"]).is_err()); -} - -#[test] -fn option_option_type() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - Foo, - Bar, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum, long)] - arg: Option>, - } - - assert_eq!(Opt { arg: None }, Opt::try_parse_from(&[""]).unwrap()); - assert_eq!( - Opt { arg: Some(None) }, - Opt::try_parse_from(&["", "--arg"]).unwrap() - ); - assert_eq!( - Opt { - arg: Some(Some(ArgChoice::Foo)) - }, - Opt::try_parse_from(&["", "--arg", "foo"]).unwrap() - ); - assert_eq!( - Opt { - arg: Some(Some(ArgChoice::Bar)) - }, - Opt::try_parse_from(&["", "--arg", "bar"]).unwrap() - ); - assert!(Opt::try_parse_from(&["", "--arg", "fOo"]).is_err()); -} - -#[test] -fn vec_type() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - Foo, - Bar, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum, short, long)] - arg: Vec, - } - - assert_eq!(Opt { arg: vec![] }, Opt::try_parse_from(&[""]).unwrap()); - assert_eq!( - Opt { - arg: vec![ArgChoice::Foo] - }, - Opt::try_parse_from(&["", "-a", "foo"]).unwrap() - ); - assert_eq!( - Opt { - arg: vec![ArgChoice::Foo, ArgChoice::Bar] - }, - Opt::try_parse_from(&["", "-a", "foo", "-a", "bar"]).unwrap() - ); - assert!(Opt::try_parse_from(&["", "-a", "fOo"]).is_err()); -} - -#[test] -fn option_vec_type() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - Foo, - Bar, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(value_enum, short, long)] - arg: Option>, - } - - assert_eq!(Opt { arg: None }, Opt::try_parse_from(&[""]).unwrap()); - assert_eq!( - Opt { - arg: Some(vec![ArgChoice::Foo]) - }, - Opt::try_parse_from(&["", "-a", "foo"]).unwrap() - ); - assert_eq!( - Opt { - arg: Some(vec![ArgChoice::Foo, ArgChoice::Bar]) - }, - Opt::try_parse_from(&["", "-a", "foo", "-a", "bar"]).unwrap() - ); - assert!(Opt::try_parse_from(&["", "-a", "fOo"]).is_err()); -} - -#[test] -fn vec_type_default_value() { - #[derive(clap::ValueEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - Foo, - Bar, - Baz, - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap( - value_enum, - short, - long, - default_value = "foo,bar", - value_delimiter = ',' - )] - arg: Vec, - } - - assert_eq!( - Opt { - arg: vec![ArgChoice::Foo, ArgChoice::Bar] - }, - Opt::try_parse_from(&[""]).unwrap() - ); - - assert_eq!( - Opt { - arg: vec![ArgChoice::Foo, ArgChoice::Baz] - }, - Opt::try_parse_from(&["", "-a", "foo,baz"]).unwrap() - ); -} diff --git a/tests/derive/non_literal_attributes.rs b/tests/derive/non_literal_attributes.rs index bf950fb7baa..97879994418 100644 --- a/tests/derive/non_literal_attributes.rs +++ b/tests/derive/non_literal_attributes.rs @@ -27,17 +27,16 @@ struct Opt { next_line_help = true, default_value = "0", require_equals = true, - value_parser )] x: i32, - #[clap(short = 'l', long = "level", value_parser, aliases = &["set-level", "lvl"])] + #[clap(short = 'l', long = "level", aliases = &["set-level", "lvl"])] level: String, - #[clap(long("values"), value_parser)] + #[clap(long("values"))] values: Vec, - #[clap(name = "FILE", value_parser, requires_if("FILE", "values"))] + #[clap(name = "FILE", requires_if("FILE", "values"))] files: Vec, } diff --git a/tests/derive/options.rs b/tests/derive/options.rs index f55dd8805e9..c15cf95057c 100644 --- a/tests/derive/options.rs +++ b/tests/derive/options.rs @@ -22,7 +22,7 @@ use clap::{Parser, Subcommand}; fn required_option() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, long, value_parser)] + #[clap(short, long)] arg: i32, } assert_eq!( @@ -48,7 +48,7 @@ fn required_option() { fn option_with_default() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, value_parser, default_value = "42")] + #[clap(short, default_value = "42")] arg: i32, } assert_eq!( @@ -66,7 +66,7 @@ fn option_with_default() { fn option_with_raw_default() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, value_parser, default_value = "42")] + #[clap(short, default_value = "42")] arg: i32, } assert_eq!( @@ -95,7 +95,6 @@ fn option_from_str() { #[derive(Debug, Parser, PartialEq)] struct Opt { - #[clap(value_parser)] a: Option, } @@ -121,7 +120,6 @@ fn vec_from_str() { #[derive(Debug, Parser, PartialEq)] struct Opt { - #[clap(value_parser)] a: Vec, } @@ -150,7 +148,7 @@ fn option_vec_from_str() { #[derive(Debug, Parser, PartialEq)] struct Opt { - #[clap(short, value_parser)] + #[clap(short)] a: Option>, } @@ -165,7 +163,7 @@ fn option_vec_from_str() { fn option_type_is_optional() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, value_parser)] + #[clap(short)] arg: Option, } assert_eq!( @@ -184,7 +182,7 @@ fn required_with_option_type() { #[derive(Debug, PartialEq, Eq, Parser)] #[clap(subcommand_negates_reqs = true)] struct Opt { - #[clap(value_parser, required = true)] + #[clap(required = true)] req_str: Option, #[clap(subcommand)] @@ -242,7 +240,7 @@ fn ignore_qualified_option_type() { fn option_option_type_is_optional_value() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, value_parser)] + #[clap(short)] #[allow(clippy::option_option)] arg: Option>, } @@ -269,7 +267,7 @@ fn option_option_type_is_optional_value() { fn option_option_type_help() { #[derive(Parser, Debug)] struct Opt { - #[clap(long, value_name = "val", value_parser)] + #[clap(long, value_name = "val")] arg: Option>, } let help = utils::get_help::(); @@ -281,10 +279,10 @@ fn option_option_type_help() { fn two_option_option_types() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, value_parser)] + #[clap(short)] arg: Option>, - #[clap(long, value_parser)] + #[clap(long)] field: Option>, } assert_eq!( @@ -335,7 +333,7 @@ fn two_option_option_types() { fn vec_type_is_multiple_occurrences() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, long, value_parser)] + #[clap(short, long)] arg: Vec, } assert_eq!( @@ -353,7 +351,7 @@ fn vec_type_is_multiple_occurrences() { fn vec_type_with_required() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, long, required = true, value_parser)] + #[clap(short, long, required = true)] arg: Vec, } assert_eq!( @@ -371,7 +369,7 @@ fn vec_type_with_required() { fn vec_type_with_multiple_values_only() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, long, multiple_values(true), value_parser)] + #[clap(short, long, multiple_values(true))] arg: Vec, } assert_eq!( @@ -409,7 +407,7 @@ fn ignore_qualified_vec_type() { fn option_vec_type() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, value_parser)] + #[clap(short)] arg: Option>, } assert_eq!( @@ -431,7 +429,7 @@ fn option_vec_type() { fn option_vec_type_structopt_behavior() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, long, multiple_values(true), min_values(0), value_parser)] + #[clap(short, long, multiple_values(true), min_values(0))] arg: Option>, } assert_eq!( @@ -458,10 +456,10 @@ fn option_vec_type_structopt_behavior() { fn two_option_vec_types() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short, value_parser)] + #[clap(short)] arg: Option>, - #[clap(short, value_parser)] + #[clap(short)] b: Option>, } @@ -512,7 +510,7 @@ fn explicit_value_parser() { fn implicit_value_parser() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(long, value_parser)] + #[clap(long)] arg: i32, } assert_eq!( diff --git a/tests/derive/privacy.rs b/tests/derive/privacy.rs index 224a23a4cc1..c8f66127b2d 100644 --- a/tests/derive/privacy.rs +++ b/tests/derive/privacy.rs @@ -30,7 +30,6 @@ mod subcommands { /// foo Foo { /// foo - #[clap(value_parser)] bars: String, }, } diff --git a/tests/derive/raw_bool_literal.rs b/tests/derive/raw_bool_literal.rs index 7dd3618a7d0..0e572aa8c67 100644 --- a/tests/derive/raw_bool_literal.rs +++ b/tests/derive/raw_bool_literal.rs @@ -13,9 +13,9 @@ fn raw_bool_literal() { #[derive(Parser, Debug, PartialEq)] #[clap(name = "raw_bool")] struct Opt { - #[clap(raw(false), value_parser)] + #[clap(raw(false))] a: String, - #[clap(raw(true), value_parser)] + #[clap(raw(true))] b: String, } diff --git a/tests/derive/raw_idents.rs b/tests/derive/raw_idents.rs index 25762c0e6bb..12c5d1658f0 100644 --- a/tests/derive/raw_idents.rs +++ b/tests/derive/raw_idents.rs @@ -4,7 +4,7 @@ use clap::Parser; fn raw_idents() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(short, long, value_parser)] + #[clap(short, long)] r#type: String, } diff --git a/tests/derive/rename_all_env.rs b/tests/derive/rename_all_env.rs index 46327c12ff0..20d4f40c728 100644 --- a/tests/derive/rename_all_env.rs +++ b/tests/derive/rename_all_env.rs @@ -9,7 +9,7 @@ fn it_works() { #[derive(Debug, PartialEq, Parser)] #[clap(rename_all_env = "kebab")] struct BehaviorModel { - #[clap(env, value_parser)] + #[clap(env)] be_nice: String, } @@ -21,7 +21,7 @@ fn it_works() { fn default_is_screaming() { #[derive(Debug, PartialEq, Parser)] struct BehaviorModel { - #[clap(env, value_parser)] + #[clap(env)] be_nice: String, } @@ -34,10 +34,10 @@ fn overridable() { #[derive(Debug, PartialEq, Parser)] #[clap(rename_all_env = "kebab")] struct BehaviorModel { - #[clap(env, value_parser)] + #[clap(env)] be_nice: String, - #[clap(rename_all_env = "pascal", env, value_parser)] + #[clap(rename_all_env = "pascal", env)] be_aggressive: String, } diff --git a/tests/derive/skip.rs b/tests/derive/skip.rs index d2e3b7ec086..160b0578f72 100644 --- a/tests/derive/skip.rs +++ b/tests/derive/skip.rs @@ -12,7 +12,7 @@ use clap::Parser; fn skip_1() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(short, value_parser)] + #[clap(short)] x: u32, #[clap(skip)] s: u32, @@ -39,17 +39,17 @@ fn skip_1() { fn skip_2() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(short, value_parser)] + #[clap(short)] x: u32, #[clap(skip)] ss: String, #[clap(skip)] sn: u8, - #[clap(value_parser)] + y: u32, #[clap(skip)] sz: u16, - #[clap(value_parser)] + t: u32, } @@ -83,7 +83,7 @@ fn skip_enum() { #[derive(Parser, Debug, PartialEq)] pub struct Opt { - #[clap(long, short, value_parser)] + #[clap(long, short)] number: u32, #[clap(skip)] k: Kind, @@ -117,7 +117,7 @@ fn skip_help_doc_comments() { #[clap(skip)] c: u32, - #[clap(short, value_parser)] + #[clap(short)] n: u32, } @@ -136,7 +136,7 @@ fn skip_help_doc_comments() { fn skip_val() { #[derive(Parser, Debug, PartialEq)] pub struct Opt { - #[clap(long, short, value_parser)] + #[clap(long, short)] number: u32, #[clap(skip = "key")] diff --git a/tests/derive/subcommands.rs b/tests/derive/subcommands.rs index 2dcb897643f..47ae63759d1 100644 --- a/tests/derive/subcommands.rs +++ b/tests/derive/subcommands.rs @@ -20,19 +20,19 @@ use clap::{Args, Parser, Subcommand}; enum Opt { /// Fetch stuff from GitHub Fetch { - #[clap(long, action)] + #[clap(long)] all: bool, /// Overwrite local branches. - #[clap(short, long, action)] + #[clap(short, long)] force: bool, - #[clap(value_parser)] + repo: String, }, Add { - #[clap(short, long, action)] + #[clap(short, long)] interactive: bool, - #[clap(short, long, action)] + #[clap(short, long)] verbose: bool, }, } @@ -89,10 +89,7 @@ fn test_no_parse() { #[derive(Parser, PartialEq, Debug)] enum Opt2 { - DoSomething { - #[clap(value_parser)] - arg: String, - }, + DoSomething { arg: String }, } #[test] @@ -127,13 +124,11 @@ fn test_null_commands() { #[derive(Parser, PartialEq, Debug)] #[clap(about = "Not shown")] struct Add { - #[clap(value_parser)] file: String, } /// Not shown #[derive(Parser, PartialEq, Debug)] struct Fetch { - #[clap(value_parser)] remote: String, } #[derive(Parser, PartialEq, Debug)] @@ -173,7 +168,7 @@ fn test_tuple_commands() { fn global_passed_down() { #[derive(Debug, PartialEq, Parser)] struct Opt { - #[clap(global = true, long, action)] + #[clap(global = true, long)] other: bool, #[clap(subcommand)] sub: Subcommands, @@ -187,7 +182,7 @@ fn global_passed_down() { #[derive(Debug, PartialEq, Args)] struct GlobalCmd { - #[clap(from_global, action)] + #[clap(from_global)] other: bool, } @@ -343,15 +338,13 @@ fn update_subcommands() { #[derive(Parser, PartialEq, Debug)] struct Command1 { - #[clap(value_parser)] arg1: i32, - #[clap(value_parser)] + arg2: i32, } #[derive(Parser, PartialEq, Debug)] struct Command2 { - #[clap(value_parser)] arg2: i32, } @@ -405,15 +398,13 @@ fn update_sub_subcommands() { #[derive(Args, PartialEq, Debug)] struct Command1 { - #[clap(value_parser)] arg1: i32, - #[clap(value_parser)] + arg2: i32, } #[derive(Args, PartialEq, Debug)] struct Command2 { - #[clap(value_parser)] arg2: i32, } @@ -466,15 +457,13 @@ fn update_ext_subcommand() { #[derive(Args, PartialEq, Debug)] struct Command1 { - #[clap(value_parser)] arg1: i32, - #[clap(value_parser)] + arg2: i32, } #[derive(Args, PartialEq, Debug)] struct Command2 { - #[clap(value_parser)] arg2: i32, } @@ -564,12 +553,10 @@ fn skip_subcommand() { } #[test] -#[cfg(feature = "unstable-v4")] fn built_in_subcommand_escaped() { #[derive(Debug, PartialEq, Parser)] enum Command { Install { - #[clap(value_parser)] arg: Option, }, #[clap(external_subcommand)] @@ -591,32 +578,3 @@ fn built_in_subcommand_escaped() { Command::Custom(vec![String::from("install"), String::from("arg")]) ); } - -#[test] -#[cfg(not(feature = "unstable-v4"))] -fn built_in_subcommand_escaped() { - #[derive(Debug, PartialEq, Parser)] - enum Command { - Install { - #[clap(value_parser)] - arg: Option, - }, - #[clap(external_subcommand)] - Custom(Vec), - } - - assert_eq!( - Command::try_parse_from(&["test", "install", "arg"]).unwrap(), - Command::Install { - arg: Some(String::from("arg")) - } - ); - assert_eq!( - Command::try_parse_from(&["test", "--", "install"]).unwrap(), - Command::Install { arg: None } - ); - assert_eq!( - Command::try_parse_from(&["test", "--", "install", "arg"]).unwrap(), - Command::Install { arg: None } - ); -} diff --git a/tests/derive/type_alias_regressions.rs b/tests/derive/type_alias_regressions.rs index 32292aa2528..a66f4fa8bae 100644 --- a/tests/derive/type_alias_regressions.rs +++ b/tests/derive/type_alias_regressions.rs @@ -11,20 +11,16 @@ type Option = std::option::Option; #[derive(Parser)] pub struct Opts { - #[clap(value_parser)] another_string: String, #[clap(subcommand)] command: Command, - #[clap(short, long, value_enum, value_parser)] + #[clap(short, long, value_enum)] choice: ArgChoice, } #[derive(Subcommand, PartialEq, Debug)] enum Command { - DoSomething { - #[clap(value_parser)] - arg: Option, - }, + DoSomething { arg: Option }, } #[derive(ValueEnum, PartialEq, Debug, Clone)] diff --git a/tests/derive/utf8.rs b/tests/derive/utf8.rs index 6389ef67168..dac3b45f903 100644 --- a/tests/derive/utf8.rs +++ b/tests/derive/utf8.rs @@ -6,13 +6,12 @@ use std::os::unix::ffi::OsStringExt; #[derive(Parser, Debug, PartialEq, Eq)] struct Positional { - #[clap(value_parser)] arg: String, } #[derive(Parser, Debug, PartialEq, Eq)] struct Named { - #[clap(short, long, value_parser)] + #[clap(short, long)] arg: String, } @@ -77,13 +76,12 @@ fn invalid_utf8_strict_option_long_equals() { #[derive(Parser, Debug, PartialEq, Eq)] struct PositionalOs { - #[clap(value_parser)] arg: OsString, } #[derive(Parser, Debug, PartialEq, Eq)] struct NamedOs { - #[clap(short, long, value_parser)] + #[clap(short, long)] arg: OsString, } diff --git a/tests/derive/value_enum.rs b/tests/derive/value_enum.rs index 4f93f57d1ba..ca9faaa52ca 100644 --- a/tests/derive/value_enum.rs +++ b/tests/derive/value_enum.rs @@ -19,7 +19,7 @@ fn basic() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, value_parser)] + #[clap(value_enum)] arg: ArgChoice, } @@ -54,7 +54,7 @@ fn default_value() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, value_parser, default_value_t)] + #[clap(value_enum, default_value_t)] arg: ArgChoice, } @@ -89,7 +89,7 @@ fn multi_word_is_renamed_kebab() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, value_parser)] + #[clap(value_enum)] arg: ArgChoice, } @@ -118,7 +118,7 @@ fn variant_with_defined_casing() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, value_parser)] + #[clap(value_enum)] arg: ArgChoice, } @@ -141,7 +141,7 @@ fn casing_is_propagated_from_parent() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, value_parser)] + #[clap(value_enum)] arg: ArgChoice, } @@ -165,7 +165,7 @@ fn casing_propagation_is_overridden() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, value_parser)] + #[clap(value_enum)] arg: ArgChoice, } @@ -188,7 +188,7 @@ fn ignore_case() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, value_parser, ignore_case(true))] + #[clap(value_enum, ignore_case(true))] arg: ArgChoice, } @@ -215,7 +215,7 @@ fn ignore_case_set_to_false() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, ignore_case(false), value_parser)] + #[clap(value_enum, ignore_case(false))] arg: ArgChoice, } @@ -238,7 +238,7 @@ fn alias() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, ignore_case(false), value_parser)] + #[clap(value_enum, ignore_case(false))] arg: ArgChoice, } @@ -266,7 +266,7 @@ fn multiple_alias() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, ignore_case(false), value_parser)] + #[clap(value_enum, ignore_case(false))] arg: ArgChoice, } @@ -375,7 +375,7 @@ fn option_type() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, value_parser)] + #[clap(value_enum)] arg: Option, } @@ -405,7 +405,7 @@ fn option_option_type() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, long, value_parser)] + #[clap(value_enum, long)] arg: Option>, } @@ -439,7 +439,7 @@ fn vec_type() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, short, long, value_parser)] + #[clap(value_enum, short, long)] arg: Vec, } @@ -469,7 +469,7 @@ fn option_vec_type() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(value_enum, short, long, value_parser)] + #[clap(value_enum, short, long)] arg: Option>, } @@ -505,8 +505,7 @@ fn vec_type_default_value() { short, long, default_value = "foo,bar", - value_delimiter = ',', - value_parser + value_delimiter = ',' )] arg: Vec, } diff --git a/tests/derive_ui.rs b/tests/derive_ui.rs index c06d34df17b..283bd3ac5fc 100644 --- a/tests/derive_ui.rs +++ b/tests/derive_ui.rs @@ -11,8 +11,4 @@ fn ui() { let t = trybuild::TestCases::new(); t.compile_fail("tests/derive_ui/*.rs"); - #[cfg(feature = "unstable-v4")] - t.compile_fail("tests/derive_ui/next/*.rs"); - #[cfg(not(feature = "unstable-v4"))] - t.compile_fail("tests/derive_ui/stable/*.rs"); } diff --git a/tests/derive_ui/next/bool_value_enum.rs b/tests/derive_ui/bool_value_enum.rs similarity index 100% rename from tests/derive_ui/next/bool_value_enum.rs rename to tests/derive_ui/bool_value_enum.rs diff --git a/tests/derive_ui/next/bool_value_enum.stderr b/tests/derive_ui/bool_value_enum.stderr similarity index 89% rename from tests/derive_ui/next/bool_value_enum.stderr rename to tests/derive_ui/bool_value_enum.stderr index d6dd2073ecc..7590517c4e1 100644 --- a/tests/derive_ui/next/bool_value_enum.stderr +++ b/tests/derive_ui/bool_value_enum.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `bool: ValueEnum` is not satisfied - --> tests/derive_ui/next/bool_value_enum.rs:6:31 + --> tests/derive_ui/bool_value_enum.rs:6:31 | 6 | #[clap(short, value_enum, default_value_t)] | ^^^^^^^^^^^^^^^ the trait `ValueEnum` is not implemented for `bool` diff --git a/tests/derive_ui/next/non_existent_attr.rs b/tests/derive_ui/non_existent_attr.rs similarity index 100% rename from tests/derive_ui/next/non_existent_attr.rs rename to tests/derive_ui/non_existent_attr.rs diff --git a/tests/derive_ui/next/non_existent_attr.stderr b/tests/derive_ui/non_existent_attr.stderr similarity index 81% rename from tests/derive_ui/next/non_existent_attr.stderr rename to tests/derive_ui/non_existent_attr.stderr index 881d15a372c..6869dab1c42 100644 --- a/tests/derive_ui/next/non_existent_attr.stderr +++ b/tests/derive_ui/non_existent_attr.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `non_existing_attribute` found for struct `Arg` in the current scope - --> tests/derive_ui/next/non_existent_attr.rs:14:19 + --> tests/derive_ui/non_existent_attr.rs:14:19 | 14 | #[clap(short, non_existing_attribute = 1)] | ^^^^^^^^^^^^^^^^^^^^^^ method not found in `Arg<'_>` diff --git a/tests/derive_ui/stable/bool_value_enum.rs b/tests/derive_ui/stable/bool_value_enum.rs deleted file mode 100644 index f98d507bd49..00000000000 --- a/tests/derive_ui/stable/bool_value_enum.rs +++ /dev/null @@ -1,13 +0,0 @@ -use clap::Parser; - -#[derive(Parser, Debug)] -#[clap(name = "basic")] -struct Opt { - #[clap(short, value_enum)] - opts: bool, -} - -fn main() { - let opt = Opt::parse(); - println!("{:?}", opt); -} diff --git a/tests/derive_ui/stable/bool_value_enum.stderr b/tests/derive_ui/stable/bool_value_enum.stderr deleted file mode 100644 index 8d3c8934c47..00000000000 --- a/tests/derive_ui/stable/bool_value_enum.stderr +++ /dev/null @@ -1,40 +0,0 @@ -error[E0277]: the trait bound `bool: ValueEnum` is not satisfied - --> tests/derive_ui/stable/bool_value_enum.rs:7:11 - | -7 | opts: bool, - | ^^^^ the trait `ValueEnum` is not implemented for `bool` - | -note: required by `clap::ValueEnum::from_str` - --> src/derive.rs - | - | fn from_str(input: &str, ignore_case: bool) -> Result { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0618]: expected function, found enum variant `bool` - --> tests/derive_ui/stable/bool_value_enum.rs:7:11 - | -7 | opts: bool, - | ^^^^ call expression requires function - | -help: `bool` is a unit variant, you need to write it without the parenthesis - | -7 | opts: bool, - | ~~~~ - -error[E0599]: no method named `possible_values` found for struct `Arg` in the current scope - --> tests/derive_ui/stable/bool_value_enum.rs:7:11 - | -7 | opts: bool, - | ^^^^ help: there is an associated function with a similar name: `hide_possible_values` - -error[E0277]: the trait bound `bool: ValueEnum` is not satisfied - --> tests/derive_ui/stable/bool_value_enum.rs:7:11 - | -7 | opts: bool, - | ^^^^ the trait `ValueEnum` is not implemented for `bool` - | -note: required by `value_variants` - --> src/derive.rs - | - | fn value_variants<'a>() -> &'a [Self]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/derive_ui/stable/non_existent_attr.rs b/tests/derive_ui/stable/non_existent_attr.rs deleted file mode 100644 index 5275b446cac..00000000000 --- a/tests/derive_ui/stable/non_existent_attr.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use clap::Parser; - -#[derive(Parser, Debug)] -#[clap(name = "basic")] -struct Opt { - #[clap(short, non_existing_attribute = 1)] - debug: bool, -} - -fn main() { - let opt = Opt::parse(); - println!("{:?}", opt); -} diff --git a/tests/derive_ui/stable/non_existent_attr.stderr b/tests/derive_ui/stable/non_existent_attr.stderr deleted file mode 100644 index 673f9e28b9d..00000000000 --- a/tests/derive_ui/stable/non_existent_attr.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error[E0599]: no method named `non_existing_attribute` found for struct `Arg` in the current scope - --> tests/derive_ui/stable/non_existent_attr.rs:14:19 - | -14 | #[clap(short, non_existing_attribute = 1)] - | ^^^^^^^^^^^^^^^^^^^^^^ method not found in `Arg<'_>` diff --git a/tests/derive_ui/stable/tuple_struct.rs b/tests/derive_ui/stable/tuple_struct.rs deleted file mode 100644 index 18da78b9267..00000000000 --- a/tests/derive_ui/stable/tuple_struct.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2018 Guillaume Pinot (@TeXitoi) -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use clap::Parser; - -#[derive(Parser, Debug)] -#[clap(name = "basic")] -struct Opt(u32); - -fn main() { - let opt = Opt::parse(); - println!("{:?}", opt); -} diff --git a/tests/derive_ui/stable/tuple_struct.stderr b/tests/derive_ui/stable/tuple_struct.stderr deleted file mode 100644 index bd9a5ba1fcd..00000000000 --- a/tests/derive_ui/stable/tuple_struct.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error: `#[derive(Parser)]` only supports non-tuple structs and enums - --> tests/derive_ui/stable/tuple_struct.rs:11:10 - | -11 | #[derive(Parser, Debug)] - | ^^^^^^ - | - = note: this error originates in the derive macro `Parser` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0599]: no function or associated item named `parse` found for struct `Opt` in the current scope - --> tests/derive_ui/stable/tuple_struct.rs:16:20 - | -13 | struct Opt(u32); - | ---------------- function or associated item `parse` not found for this -... -16 | let opt = Opt::parse(); - | ^^^^^ function or associated item not found in `Opt` - | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following traits define an item `parse`, perhaps you need to implement one of them: - candidate #1: `Parser` - candidate #2: `TypedValueParser` diff --git a/tests/derive_ui/next/tuple_struct.rs b/tests/derive_ui/tuple_struct.rs similarity index 100% rename from tests/derive_ui/next/tuple_struct.rs rename to tests/derive_ui/tuple_struct.rs diff --git a/tests/derive_ui/next/tuple_struct.stderr b/tests/derive_ui/tuple_struct.stderr similarity index 89% rename from tests/derive_ui/next/tuple_struct.stderr rename to tests/derive_ui/tuple_struct.stderr index 1f5f9086520..ed835fac9e9 100644 --- a/tests/derive_ui/next/tuple_struct.stderr +++ b/tests/derive_ui/tuple_struct.stderr @@ -1,5 +1,5 @@ error: `#[derive(Parser)]` only supports non-tuple structs and enums - --> tests/derive_ui/next/tuple_struct.rs:11:10 + --> tests/derive_ui/tuple_struct.rs:11:10 | 11 | #[derive(Parser, Debug)] | ^^^^^^ @@ -7,7 +7,7 @@ error: `#[derive(Parser)]` only supports non-tuple structs and enums = note: this error originates in the derive macro `Parser` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0599]: no function or associated item named `parse` found for struct `Opt` in the current scope - --> tests/derive_ui/next/tuple_struct.rs:16:20 + --> tests/derive_ui/tuple_struct.rs:16:20 | 13 | struct Opt(u32); | ---------------- function or associated item `parse` not found for this