mirror of
https://github.com/clap-rs/clap
synced 2024-12-14 14:52:33 +00:00
Merge pull request #3963 from epage/deprecated
fix!: Remove deprecated APIs
This commit is contained in:
commit
017b87abb0
139 changed files with 291 additions and 28541 deletions
28
Cargo.lock
generated
28
Cargo.lock
generated
|
@ -17,15 +17,6 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
|
@ -138,7 +129,6 @@ dependencies = [
|
|||
"humantime",
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"rustversion",
|
||||
"shlex",
|
||||
"snapbox",
|
||||
|
@ -150,7 +140,6 @@ dependencies = [
|
|||
"trybuild",
|
||||
"trycmd",
|
||||
"unicase",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -494,12 +483,6 @@ version = "0.2.126"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
|
@ -722,8 +705,6 @@ version = "1.6.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
|
@ -1124,15 +1105,6 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
version = "0.5.1"
|
||||
|
|
|
@ -60,7 +60,7 @@ default = [
|
|||
"suggestions",
|
||||
]
|
||||
debug = ["clap_derive/debug", "backtrace"] # Enables debug messages
|
||||
unstable-doc = ["derive", "cargo", "wrap_help", "yaml", "env", "unicode", "regex", "unstable-replace", "unstable-grouped"] # for docs.rs
|
||||
unstable-doc = ["derive", "cargo", "wrap_help", "env", "unicode", "unstable-replace", "unstable-grouped"] # for docs.rs
|
||||
|
||||
# Used in default
|
||||
std = ["indexmap/std"] # support for no_std in a backwards-compatible way
|
||||
|
@ -73,7 +73,6 @@ deprecated = ["clap_derive/deprecated"] # Guided experience to prepare for next
|
|||
derive = ["clap_derive", "once_cell"]
|
||||
cargo = ["once_cell"] # Disable if you're not using Cargo, enables Cargo-env-var-dependent macros
|
||||
wrap_help = ["terminal_size", "textwrap/terminal_size"]
|
||||
yaml = ["yaml-rust"]
|
||||
env = [] # Use environment variables during arg parsing
|
||||
unicode = ["textwrap/unicode-width", "unicase"] # Support for unicode characters in arguments and help messages
|
||||
|
||||
|
@ -94,16 +93,13 @@ textwrap = { version = "0.15.0", default-features = false, features = [] }
|
|||
unicase = { version = "2.6", optional = true }
|
||||
indexmap = "1.0"
|
||||
strsim = { version = "0.10", optional = true }
|
||||
yaml-rust = { version = "0.4.1", optional = true }
|
||||
atty = { version = "0.2", optional = true }
|
||||
termcolor = { version = "1.1.1", optional = true }
|
||||
terminal_size = { version = "0.1.12", optional = true }
|
||||
regex = { version = "1.0", optional = true }
|
||||
backtrace = { version = "0.3", optional = true }
|
||||
once_cell = { version = "1.12.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
regex = "1.0"
|
||||
trybuild = "1.0.18"
|
||||
rustversion = "1"
|
||||
# Cutting out `filesystem` feature
|
||||
|
|
4
Makefile
4
Makefile
|
@ -15,8 +15,8 @@ MSRV?=1.56.1
|
|||
_FEATURES = minimal default wasm full debug release
|
||||
_FEATURES_minimal = --no-default-features --features "std"
|
||||
_FEATURES_default =
|
||||
_FEATURES_wasm = --features "deprecated derive cargo env unicode yaml regex unstable-replace unstable-grouped"
|
||||
_FEATURES_full = --features "deprecated derive cargo env unicode yaml regex unstable-replace unstable-grouped wrap_help"
|
||||
_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_debug = ${_FEATURES_full} --features debug
|
||||
_FEATURES_release = ${_FEATURES_full} --release
|
||||
|
|
|
@ -224,7 +224,7 @@ complete OPTIONS -F _clap_complete_NAME EXECUTABLES
|
|||
Menu,
|
||||
}
|
||||
|
||||
impl clap::ArgEnum for CompType {
|
||||
impl clap::ValueEnum for CompType {
|
||||
fn value_variants<'a>() -> &'a [Self] {
|
||||
&[
|
||||
Self::Normal,
|
||||
|
|
|
@ -128,13 +128,8 @@ pub fn flags<'help>(p: &Command<'help>) -> Vec<Arg<'help>> {
|
|||
|
||||
/// Get the possible values for completion
|
||||
pub fn possible_values<'help>(a: &Arg<'help>) -> Option<Vec<clap::PossibleValue<'help>>> {
|
||||
#![allow(deprecated)]
|
||||
if !a.is_takes_value_set() {
|
||||
None
|
||||
} else if let Some(pvs) = a.get_possible_values() {
|
||||
// Check old first in case the user explicitly set possible values and the derive inferred
|
||||
// a `ValueParser` with some.
|
||||
Some(pvs.to_vec())
|
||||
} else {
|
||||
a.get_value_parser()
|
||||
.possible_values()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::fmt::Display;
|
||||
use std::str::FromStr;
|
||||
|
||||
use clap::{ArgEnum, PossibleValue};
|
||||
use clap::{PossibleValue, ValueEnum};
|
||||
|
||||
use crate::shells;
|
||||
use crate::Generator;
|
||||
|
@ -22,16 +22,6 @@ pub enum Shell {
|
|||
Zsh,
|
||||
}
|
||||
|
||||
impl Shell {
|
||||
/// Deprecated, replaced with [`EnumValueParser`][clap::builder::EnumValueParser]
|
||||
#[deprecated(since = "3.2.0", note = "Replaced with `EnumValueParser`")]
|
||||
pub fn possible_values() -> impl Iterator<Item = PossibleValue<'static>> {
|
||||
Shell::value_variants()
|
||||
.iter()
|
||||
.filter_map(ArgEnum::to_possible_value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Shell {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.to_possible_value()
|
||||
|
@ -55,7 +45,7 @@ impl FromStr for Shell {
|
|||
}
|
||||
|
||||
// Hand-rolled so it can work even when `derive` feature is disabled
|
||||
impl ArgEnum for Shell {
|
||||
impl ValueEnum for Shell {
|
||||
fn value_variants<'a>() -> &'a [Self] {
|
||||
&[
|
||||
Shell::Bash,
|
||||
|
|
|
@ -56,14 +56,13 @@ pub fn gen_for_struct(
|
|||
clippy::suspicious_else_formatting,
|
||||
)]
|
||||
#[deny(clippy::correctness)]
|
||||
#[allow(deprecated)]
|
||||
impl #impl_generics clap::CommandFactory for #struct_name #ty_generics #where_clause {
|
||||
fn into_app<'b>() -> clap::Command<'b> {
|
||||
fn command<'b>() -> clap::Command<'b> {
|
||||
let #app_var = clap::Command::new(#name);
|
||||
<Self as clap::Args>::augment_args(#app_var)
|
||||
}
|
||||
|
||||
fn into_app_for_update<'b>() -> clap::Command<'b> {
|
||||
fn command_for_update<'b>() -> clap::Command<'b> {
|
||||
let #app_var = clap::Command::new(#name);
|
||||
<Self as clap::Args>::augment_args_for_update(#app_var)
|
||||
}
|
||||
|
@ -103,14 +102,14 @@ pub fn gen_for_enum(enum_name: &Ident, generics: &Generics, attrs: &[Attribute])
|
|||
)]
|
||||
#[deny(clippy::correctness)]
|
||||
impl #impl_generics clap::CommandFactory for #enum_name #ty_generics #where_clause {
|
||||
fn into_app<'b>() -> clap::Command<'b> {
|
||||
fn command<'b>() -> clap::Command<'b> {
|
||||
#[allow(deprecated)]
|
||||
let #app_var = clap::Command::new(#name)
|
||||
.setting(clap::AppSettings::SubcommandRequiredElseHelp);
|
||||
<Self as clap::Subcommand>::augment_subcommands(#app_var)
|
||||
}
|
||||
|
||||
fn into_app_for_update<'b>() -> clap::Command<'b> {
|
||||
fn command_for_update<'b>() -> clap::Command<'b> {
|
||||
let #app_var = clap::Command::new(#name);
|
||||
<Self as clap::Subcommand>::augment_subcommands_for_update(#app_var)
|
||||
}
|
||||
|
|
|
@ -18,12 +18,11 @@ pub fn parser_enum(name: &Ident) {
|
|||
|
||||
pub fn into_app(name: &Ident) {
|
||||
append_dummy(quote! {
|
||||
#[allow(deprecated)]
|
||||
impl clap::CommandFactory for #name {
|
||||
fn into_app<'b>() -> clap::Command<'b> {
|
||||
fn command<'b>() -> clap::Command<'b> {
|
||||
unimplemented!()
|
||||
}
|
||||
fn into_app_for_update<'b>() -> clap::Command<'b> {
|
||||
fn command_for_update<'b>() -> clap::Command<'b> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
See the documentation for [`Command::multicall`][crate::App::multicall] for rationale.
|
||||
See the documentation for [`Command::multicall`][crate::Command::multicall] for rationale.
|
||||
|
||||
This example omits every command except true and false,
|
||||
which are the most trivial to implement,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
See the documentation for [`Command::multicall`][crate::App::multicall] for rationale.
|
||||
See the documentation for [`Command::multicall`][crate::Command::multicall] for rationale.
|
||||
|
||||
This example omits the implementation of displaying address config
|
||||
|
||||
|
|
|
@ -199,7 +199,7 @@
|
|||
//!
|
||||
//! clap reports most development errors as `debug_assert!`s. Rather than checking every
|
||||
//! subcommand, you should have a test that calls
|
||||
//! [`Command::debug_assert`][crate::App::debug_assert]:
|
||||
//! [`Command::debug_assert`][crate::Command::debug_assert]:
|
||||
//! ```rust,no_run
|
||||
#![doc = include_str!("../../examples/tutorial_derive/05_01_assert.rs")]
|
||||
//! ```
|
||||
|
|
|
@ -137,25 +137,25 @@
|
|||
//! - e.g. `#[clap(arg_required_else_help(true))]` would translate to `cmd.arg_required_else_help(true)`
|
||||
//!
|
||||
//! **Magic attributes:**
|
||||
//! - `name = <expr>`: [`Command::name`][crate::App::name]
|
||||
//! - `name = <expr>`: [`Command::name`][crate::Command::name]
|
||||
//! - When not present: [crate `name`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field) (if on [`Parser`][crate::Parser] container), variant name (if on [`Subcommand`][crate::Subcommand] variant)
|
||||
//! - `version [= <expr>]`: [`Command::version`][crate::App::version]
|
||||
//! - `version [= <expr>]`: [`Command::version`][crate::Command::version]
|
||||
//! - When not present: no version set
|
||||
//! - Without `<expr>`: defaults to [crate `version`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field)
|
||||
//! - `author [= <expr>]`: [`Command::author`][crate::App::author]
|
||||
//! - `author [= <expr>]`: [`Command::author`][crate::Command::author]
|
||||
//! - When not present: no author set
|
||||
//! - Without `<expr>`: defaults to [crate `authors`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field)
|
||||
//! - `about [= <expr>]`: [`Command::about`][crate::App::about]
|
||||
//! - `about [= <expr>]`: [`Command::about`][crate::Command::about]
|
||||
//! - When not present: [Doc comment summary](#doc-comments)
|
||||
//! - Without `<expr>`: [crate `description`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-description-field) ([`Parser`][crate::Parser] container)
|
||||
//! - **TIP:** When a doc comment is also present, you most likely want to add
|
||||
//! `#[clap(long_about = None)]` to clear the doc comment so only [`about`][crate::App::about]
|
||||
//! `#[clap(long_about = None)]` to clear the doc comment so only [`about`][crate::Command::about]
|
||||
//! gets shown with both `-h` and `--help`.
|
||||
//! - `long_about = <expr>`: [`Command::long_about`][crate::App::long_about]
|
||||
//! - `long_about = <expr>`: [`Command::long_about`][crate::Command::long_about]
|
||||
//! - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing
|
||||
//! - `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to [`about`][crate::App::about] / [`long_about`][crate::App::long_about]
|
||||
//! - `next_display_order`: [`Command::next_display_order`][crate::App::next_display_order]
|
||||
//! - `next_help_heading`: [`Command::next_help_heading`][crate::App::next_help_heading]
|
||||
//! - `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to [`about`][crate::Command::about] / [`long_about`][crate::Command::long_about]
|
||||
//! - `next_display_order`: [`Command::next_display_order`][crate::Command::next_display_order]
|
||||
//! - `next_help_heading`: [`Command::next_help_heading`][crate::Command::next_help_heading]
|
||||
//! - When `flatten`ing [`Args`][crate::Args], this is scoped to just the args in this struct and any struct `flatten`ed into it
|
||||
//! - `rename_all = <string_literal>`: Override default field / variant name case conversion for [`Command::name`][crate::Command::name] / [`Arg::id`][crate::Arg::id]
|
||||
//! - When not present: `"kebab-case"`
|
||||
|
@ -170,7 +170,7 @@
|
|||
//! [`Subcommand`][crate::Subcommand])
|
||||
//! - `subcommand`: Nest subcommands under the current set of subcommands (must implement
|
||||
//! [`Subcommand`][crate::Subcommand])
|
||||
//! - `external_subcommand`: [`Command::allow_external_subcommand(true)`][crate::App::allow_external_subcommands]
|
||||
//! - `external_subcommand`: [`Command::allow_external_subcommand(true)`][crate::Command::allow_external_subcommands]
|
||||
//! - Variant must be either `Variant(Vec<String>)` or `Variant(Vec<OsString>)`
|
||||
//!
|
||||
//! ### Arg Attributes
|
||||
|
@ -216,7 +216,7 @@
|
|||
//! [`Subcommand`][crate::Subcommand])
|
||||
//! - When `Option<T>`, the subcommand becomes optional
|
||||
//! - `from_global`: Read a [`Arg::global`][crate::Arg::global] argument (raw attribute), regardless of what subcommand you are in
|
||||
//! - `parse(<kind> [= <function>])`: [`Arg::validator`][crate::Arg::validator] and [`ArgMatches::values_of_t`][crate::ArgMatches::values_of_t]
|
||||
//! - `parse(<kind> [= <function>])`: `Arg::validator` and `ArgMatches::values_of_t`
|
||||
//! - **Deprecated:**
|
||||
//! - Use `value_parser(...)` for `from_str`, `try_from_str`, `from_os_str`, and `try_from_os_str`
|
||||
//! - Use `action(ArgAction::Count` for `from_occurrences`
|
||||
|
@ -305,7 +305,7 @@
|
|||
//! ## Doc Comments
|
||||
//!
|
||||
//! In clap, help messages for the whole binary can be specified
|
||||
//! via [`Command::about`][crate::App::about] and [`Command::long_about`][crate::App::long_about] while help messages
|
||||
//! via [`Command::about`][crate::Command::about] and [`Command::long_about`][crate::Command::long_about] while help messages
|
||||
//! for individual arguments can be specified via [`Arg::help`][crate::Arg::help] and [`Arg::long_help`][crate::Arg::long_help].
|
||||
//!
|
||||
//! `long_*` variants are used when user calls the program with
|
||||
|
@ -488,7 +488,7 @@
|
|||
//! [`CommandFactory::command`][crate::CommandFactory::command] (implemented when deriving
|
||||
//! [`Parser`][crate::Parser])
|
||||
//! - Proactively check for bad [`Command`][crate::Command] configurations by calling
|
||||
//! [`Command::debug_assert`][crate::App::debug_assert] in a test
|
||||
//! [`Command::debug_assert`][crate::Command::debug_assert] in a test
|
||||
//! ([example](../tutorial_derive/05_01_assert.rs))
|
||||
|
||||
pub mod _tutorial;
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
//! * **derive**: Enables the custom derive (i.e. `#[derive(Parser)]`). Without this you must use one of the other methods of creating a `clap` CLI listed above.
|
||||
//! * **cargo**: Turns on macros that read values from [`CARGO_*` environment variables](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates).
|
||||
//! * **env**: Turns on the usage of environment variables during parsing.
|
||||
//! * **regex**: Enables regex validators.
|
||||
//! * **unicode**: Turns on support for unicode characters (including emoji) in arguments and help messages.
|
||||
//! * **wrap_help**: Turns on the help text wrapping feature, based on the terminal size.
|
||||
//!
|
||||
|
|
|
@ -198,7 +198,7 @@
|
|||
//!
|
||||
//! clap reports most development errors as `debug_assert!`s. Rather than checking every
|
||||
//! subcommand, you should have a test that calls
|
||||
//! [`Command::debug_assert`][crate::App::debug_assert]:
|
||||
//! [`Command::debug_assert`][crate::Command::debug_assert]:
|
||||
//! ```rust,no_run
|
||||
#![doc = include_str!("../examples/tutorial_builder/05_01_assert.rs")]
|
||||
//! ```
|
||||
|
|
|
@ -196,9 +196,9 @@ pub enum ArgAction {
|
|||
/// );
|
||||
/// ```
|
||||
Count,
|
||||
/// When encountered, display [`Command::print_help`][super::App::print_help]
|
||||
/// When encountered, display [`Command::print_help`][super::Command::print_help]
|
||||
///
|
||||
/// Depending on the flag, [`Command::print_long_help`][super::App::print_long_help] may be shown
|
||||
/// Depending on the flag, [`Command::print_long_help`][super::Command::print_long_help] may be shown
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -221,9 +221,9 @@ pub enum ArgAction {
|
|||
/// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp);
|
||||
/// ```
|
||||
Help,
|
||||
/// When encountered, display [`Command::version`][super::App::version]
|
||||
/// When encountered, display [`Command::version`][super::Command::version]
|
||||
///
|
||||
/// Depending on the flag, [`Command::long_version`][super::App::long_version] may be shown
|
||||
/// Depending on the flag, [`Command::long_version`][super::Command::long_version] may be shown
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
// Std
|
||||
use std::ops::BitOr;
|
||||
#[cfg(feature = "yaml")]
|
||||
use std::str::FromStr;
|
||||
|
||||
#[allow(unused)]
|
||||
use crate::Arg;
|
||||
|
@ -39,46 +37,6 @@ pub enum AppSettings {
|
|||
)]
|
||||
IgnoreErrors,
|
||||
|
||||
/// Deprecated, replace
|
||||
/// ```rust,no_run
|
||||
/// let cmd = clap::Command::new("cmd")
|
||||
/// .global_setting(clap::AppSettings::WaitOnError)
|
||||
/// .arg(clap::arg!(--flag));
|
||||
/// let m = cmd.get_matches();
|
||||
/// ```
|
||||
/// with
|
||||
/// ```rust
|
||||
/// let cmd = clap::Command::new("cmd")
|
||||
/// .arg(clap::arg!(--flag));
|
||||
/// let m = match cmd.try_get_matches() {
|
||||
/// Ok(m) => m,
|
||||
/// Err(err) => {
|
||||
/// if err.use_stderr() {
|
||||
/// let _ = err.print();
|
||||
///
|
||||
/// eprintln!("\nPress [ENTER] / [RETURN] to continue...");
|
||||
/// use std::io::BufRead;
|
||||
/// let mut s = String::new();
|
||||
/// let i = std::io::stdin();
|
||||
/// i.lock().read_line(&mut s).unwrap();
|
||||
///
|
||||
/// std::process::exit(2);
|
||||
/// } else {
|
||||
/// let _ = err.print();
|
||||
/// std::process::exit(0);
|
||||
/// }
|
||||
/// }
|
||||
/// };
|
||||
/// ```
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "See documentation for how to hand-implement this"
|
||||
)
|
||||
)]
|
||||
WaitOnError,
|
||||
|
||||
/// Deprecated, replaced with [`Command::allow_hyphen_values`] and
|
||||
/// [`Arg::is_allow_hyphen_values_set`]
|
||||
#[cfg_attr(
|
||||
|
@ -101,13 +59,6 @@ pub enum AppSettings {
|
|||
)]
|
||||
AllowNegativeNumbers,
|
||||
|
||||
/// Deprecated, replaced with [`Command::args_override_self`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.1.0", note = "Replaced with `Command::args_override_self`")
|
||||
)]
|
||||
AllArgsOverrideSelf,
|
||||
|
||||
/// Deprecated, replaced with [`Command::allow_missing_positional`] and
|
||||
/// [`Command::is_allow_missing_positional_set`]
|
||||
#[cfg_attr(
|
||||
|
@ -400,41 +351,6 @@ pub enum AppSettings {
|
|||
)]
|
||||
NoAutoVersion,
|
||||
|
||||
/// Deprecated, replaced with [`Command::allow_hyphen_values`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "Replaced with `Command::allow_hyphen_values`")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
AllowLeadingHyphen,
|
||||
|
||||
/// Deprecated, replaced with [`Command::allow_invalid_utf8_for_external_subcommands`] and [`Command::is_allow_invalid_utf8_for_external_subcommands_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Replaced with `Command::allow_invalid_utf8_for_external_subcommands` and `Command::is_allow_invalid_utf8_for_external_subcommands_set`"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
StrictUtf8,
|
||||
|
||||
/// Deprecated, this is now the default
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "This is now the default")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
UnifiedHelpMessage,
|
||||
|
||||
/// Deprecated, this is now the default
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "This is now the default")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
ColoredHelp,
|
||||
|
||||
/// Deprecated, see [`Command::color`][crate::Command::color]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
|
@ -459,60 +375,6 @@ pub enum AppSettings {
|
|||
#[doc(hidden)]
|
||||
ColorNever,
|
||||
|
||||
/// Deprecated, replaced with [`Command::disable_help_flag`] and [`Command::is_disable_help_flag_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Replaced with `Command::disable_help_flag` and `Command::is_disable_help_flag_set`"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
DisableHelpFlags,
|
||||
|
||||
/// Deprecated, replaced with [`Command::disable_version_flag`] and
|
||||
/// [`Command::is_disable_version_flag_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Replaced with `Command::disable_version_flag` and `Command::is_disable_version_flag_set`"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
DisableVersion,
|
||||
|
||||
/// Deprecated, replaced with [`Command::propagate_version`] and [`Command::is_propagate_version_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Replaced with `Command::propagate_version` and `Command::is_propagate_version_set`"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
GlobalVersion,
|
||||
|
||||
/// Deprecated, replaced with [`Command::hide_possible_values`] and
|
||||
/// [`Arg::is_hide_possible_values_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Replaced with `Command::hide_possible_values` and `Arg::is_hide_possible_values_set`"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
HidePossibleValuesInHelp,
|
||||
|
||||
/// Deprecated, this is now the default
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "This is now the default")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
UnifiedHelp,
|
||||
|
||||
/// If the cmd is already built, used for caching.
|
||||
#[doc(hidden)]
|
||||
Built,
|
||||
|
@ -560,7 +422,6 @@ bitflags! {
|
|||
const VALID_ARG_FOUND = 1 << 35;
|
||||
const INFER_SUBCOMMANDS = 1 << 36;
|
||||
const CONTAINS_LAST = 1 << 37;
|
||||
const ARGS_OVERRIDE_SELF = 1 << 38;
|
||||
const HELP_REQUIRED = 1 << 39;
|
||||
const SUBCOMMAND_PRECEDENCE_OVER_ARG = 1 << 40;
|
||||
const DISABLE_HELP_FLAG = 1 << 41;
|
||||
|
@ -581,22 +442,14 @@ impl_settings! { AppSettings, AppFlags,
|
|||
=> Flags::ARGS_NEGATE_SCS,
|
||||
AllowExternalSubcommands
|
||||
=> Flags::ALLOW_UNK_SC,
|
||||
StrictUtf8
|
||||
=> Flags::NO_OP,
|
||||
AllowInvalidUtf8ForExternalSubcommands
|
||||
=> Flags::SC_UTF8_NONE,
|
||||
AllowHyphenValues
|
||||
=> Flags::LEADING_HYPHEN,
|
||||
AllowLeadingHyphen
|
||||
=> Flags::LEADING_HYPHEN,
|
||||
AllowNegativeNumbers
|
||||
=> Flags::ALLOW_NEG_NUMS,
|
||||
AllowMissingPositional
|
||||
=> Flags::ALLOW_MISSING_POS,
|
||||
UnifiedHelpMessage
|
||||
=> Flags::NO_OP,
|
||||
ColoredHelp
|
||||
=> Flags::NO_OP,
|
||||
ColorAlways
|
||||
=> Flags::COLOR_ALWAYS,
|
||||
ColorAuto
|
||||
|
@ -615,20 +468,12 @@ impl_settings! { AppSettings, AppFlags,
|
|||
=> Flags::DISABLE_HELP_SC,
|
||||
DisableHelpFlag
|
||||
=> Flags::DISABLE_HELP_FLAG,
|
||||
DisableHelpFlags
|
||||
=> Flags::DISABLE_HELP_FLAG,
|
||||
DisableVersionFlag
|
||||
=> Flags::DISABLE_VERSION_FLAG,
|
||||
DisableVersion
|
||||
=> Flags::DISABLE_VERSION_FLAG,
|
||||
PropagateVersion
|
||||
=> Flags::PROPAGATE_VERSION,
|
||||
GlobalVersion
|
||||
=> Flags::PROPAGATE_VERSION,
|
||||
HidePossibleValues
|
||||
=> Flags::NO_POS_VALUES,
|
||||
HidePossibleValuesInHelp
|
||||
=> Flags::NO_POS_VALUES,
|
||||
HelpExpected
|
||||
=> Flags::HELP_REQUIRED,
|
||||
Hidden
|
||||
|
@ -651,214 +496,16 @@ impl_settings! { AppSettings, AppFlags,
|
|||
=> Flags::USE_LONG_FORMAT_FOR_HELP_SC,
|
||||
TrailingVarArg
|
||||
=> Flags::TRAILING_VARARG,
|
||||
UnifiedHelp => Flags::NO_OP,
|
||||
NextLineHelp
|
||||
=> Flags::NEXT_LINE_HELP,
|
||||
IgnoreErrors
|
||||
=> Flags::IGNORE_ERRORS,
|
||||
WaitOnError
|
||||
=> Flags::WAIT_ON_ERROR,
|
||||
Built
|
||||
=> Flags::BUILT,
|
||||
BinNameBuilt
|
||||
=> Flags::BIN_NAME_BUILT,
|
||||
InferSubcommands
|
||||
=> Flags::INFER_SUBCOMMANDS,
|
||||
AllArgsOverrideSelf
|
||||
=> Flags::ARGS_OVERRIDE_SELF,
|
||||
InferLongArgs
|
||||
=> Flags::INFER_LONG_ARGS
|
||||
}
|
||||
|
||||
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
|
||||
#[cfg(feature = "yaml")]
|
||||
impl FromStr for AppSettings {
|
||||
type Err = String;
|
||||
fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
|
||||
#[allow(deprecated)]
|
||||
#[allow(unreachable_patterns)]
|
||||
match &*s.to_ascii_lowercase() {
|
||||
"argrequiredelsehelp" => Ok(AppSettings::ArgRequiredElseHelp),
|
||||
"subcommandprecedenceoverarg" => Ok(AppSettings::SubcommandPrecedenceOverArg),
|
||||
"argsnegatesubcommands" => Ok(AppSettings::ArgsNegateSubcommands),
|
||||
"allowexternalsubcommands" => Ok(AppSettings::AllowExternalSubcommands),
|
||||
"strictutf8" => Ok(AppSettings::StrictUtf8),
|
||||
"allowinvalidutf8forexternalsubcommands" => {
|
||||
Ok(AppSettings::AllowInvalidUtf8ForExternalSubcommands)
|
||||
}
|
||||
"allowhyphenvalues" => Ok(AppSettings::AllowHyphenValues),
|
||||
"allowleadinghyphen" => Ok(AppSettings::AllowLeadingHyphen),
|
||||
"allownegativenumbers" => Ok(AppSettings::AllowNegativeNumbers),
|
||||
"allowmissingpositional" => Ok(AppSettings::AllowMissingPositional),
|
||||
"unifiedhelpmessage" => Ok(AppSettings::UnifiedHelpMessage),
|
||||
"coloredhelp" => Ok(AppSettings::ColoredHelp),
|
||||
"coloralways" => Ok(AppSettings::ColorAlways),
|
||||
"colorauto" => Ok(AppSettings::ColorAuto),
|
||||
"colornever" => Ok(AppSettings::ColorNever),
|
||||
"dontdelimittrailingvalues" => Ok(AppSettings::DontDelimitTrailingValues),
|
||||
"dontcollapseargsinusage" => Ok(AppSettings::DontCollapseArgsInUsage),
|
||||
"derivedisplayorder" => Ok(AppSettings::DeriveDisplayOrder),
|
||||
"disablecoloredhelp" => Ok(AppSettings::DisableColoredHelp),
|
||||
"disablehelpsubcommand" => Ok(AppSettings::DisableHelpSubcommand),
|
||||
"disablehelpflag" => Ok(AppSettings::DisableHelpFlag),
|
||||
"disablehelpflags" => Ok(AppSettings::DisableHelpFlags),
|
||||
"disableversionflag" => Ok(AppSettings::DisableVersionFlag),
|
||||
"disableversion" => Ok(AppSettings::DisableVersion),
|
||||
"propagateversion" => Ok(AppSettings::PropagateVersion),
|
||||
"propagateversion" => Ok(AppSettings::GlobalVersion),
|
||||
"hidepossiblevalues" => Ok(AppSettings::HidePossibleValues),
|
||||
"hidepossiblevaluesinhelp" => Ok(AppSettings::HidePossibleValuesInHelp),
|
||||
"helpexpected" => Ok(AppSettings::HelpExpected),
|
||||
"hidden" => Ok(AppSettings::Hidden),
|
||||
"noautohelp" => Ok(AppSettings::NoAutoHelp),
|
||||
"noautoversion" => Ok(AppSettings::NoAutoVersion),
|
||||
"nobinaryname" => Ok(AppSettings::NoBinaryName),
|
||||
"subcommandsnegatereqs" => Ok(AppSettings::SubcommandsNegateReqs),
|
||||
"subcommandrequired" => Ok(AppSettings::SubcommandRequired),
|
||||
"subcommandrequiredelsehelp" => Ok(AppSettings::SubcommandRequiredElseHelp),
|
||||
"uselongformatforhelpsubcommand" => Ok(AppSettings::UseLongFormatForHelpSubcommand),
|
||||
"trailingvararg" => Ok(AppSettings::TrailingVarArg),
|
||||
"unifiedhelp" => Ok(AppSettings::UnifiedHelp),
|
||||
"nextlinehelp" => Ok(AppSettings::NextLineHelp),
|
||||
"ignoreerrors" => Ok(AppSettings::IgnoreErrors),
|
||||
"waitonerror" => Ok(AppSettings::WaitOnError),
|
||||
"built" => Ok(AppSettings::Built),
|
||||
"binnamebuilt" => Ok(AppSettings::BinNameBuilt),
|
||||
"infersubcommands" => Ok(AppSettings::InferSubcommands),
|
||||
"allargsoverrideself" => Ok(AppSettings::AllArgsOverrideSelf),
|
||||
"inferlongargs" => Ok(AppSettings::InferLongArgs),
|
||||
_ => Err(format!("unknown AppSetting: `{}`", s)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
#[test]
|
||||
#[cfg(feature = "yaml")]
|
||||
fn app_settings_fromstr() {
|
||||
use super::AppSettings;
|
||||
|
||||
assert_eq!(
|
||||
"disablehelpflag".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::DisableHelpFlag
|
||||
);
|
||||
assert_eq!(
|
||||
"argsnegatesubcommands".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::ArgsNegateSubcommands
|
||||
);
|
||||
assert_eq!(
|
||||
"argrequiredelsehelp".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::ArgRequiredElseHelp
|
||||
);
|
||||
assert_eq!(
|
||||
"subcommandprecedenceoverarg"
|
||||
.parse::<AppSettings>()
|
||||
.unwrap(),
|
||||
AppSettings::SubcommandPrecedenceOverArg
|
||||
);
|
||||
assert_eq!(
|
||||
"allowexternalsubcommands".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::AllowExternalSubcommands
|
||||
);
|
||||
assert_eq!(
|
||||
"allowinvalidutf8forexternalsubcommands"
|
||||
.parse::<AppSettings>()
|
||||
.unwrap(),
|
||||
AppSettings::AllowInvalidUtf8ForExternalSubcommands
|
||||
);
|
||||
assert_eq!(
|
||||
"allowhyphenvalues".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::AllowHyphenValues
|
||||
);
|
||||
assert_eq!(
|
||||
"allownegativenumbers".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::AllowNegativeNumbers
|
||||
);
|
||||
assert_eq!(
|
||||
"disablehelpsubcommand".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::DisableHelpSubcommand
|
||||
);
|
||||
assert_eq!(
|
||||
"disableversionflag".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::DisableVersionFlag
|
||||
);
|
||||
assert_eq!(
|
||||
"dontcollapseargsinusage".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::DontCollapseArgsInUsage
|
||||
);
|
||||
assert_eq!(
|
||||
"dontdelimittrailingvalues".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::DontDelimitTrailingValues
|
||||
);
|
||||
assert_eq!(
|
||||
"derivedisplayorder".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::DeriveDisplayOrder
|
||||
);
|
||||
assert_eq!(
|
||||
"disablecoloredhelp".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::DisableColoredHelp
|
||||
);
|
||||
assert_eq!(
|
||||
"propagateversion".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::PropagateVersion
|
||||
);
|
||||
assert_eq!(
|
||||
"hidden".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::Hidden
|
||||
);
|
||||
assert_eq!(
|
||||
"hidepossiblevalues".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::HidePossibleValues
|
||||
);
|
||||
assert_eq!(
|
||||
"helpexpected".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::HelpExpected
|
||||
);
|
||||
assert_eq!(
|
||||
"nobinaryname".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::NoBinaryName
|
||||
);
|
||||
assert_eq!(
|
||||
"nextlinehelp".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::NextLineHelp
|
||||
);
|
||||
assert_eq!(
|
||||
"subcommandsnegatereqs".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::SubcommandsNegateReqs
|
||||
);
|
||||
assert_eq!(
|
||||
"subcommandrequired".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::SubcommandRequired
|
||||
);
|
||||
assert_eq!(
|
||||
"subcommandrequiredelsehelp".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::SubcommandRequiredElseHelp
|
||||
);
|
||||
assert_eq!(
|
||||
"uselongformatforhelpsubcommand"
|
||||
.parse::<AppSettings>()
|
||||
.unwrap(),
|
||||
AppSettings::UseLongFormatForHelpSubcommand
|
||||
);
|
||||
assert_eq!(
|
||||
"trailingvararg".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::TrailingVarArg
|
||||
);
|
||||
assert_eq!(
|
||||
"waitonerror".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::WaitOnError
|
||||
);
|
||||
assert_eq!("built".parse::<AppSettings>().unwrap(), AppSettings::Built);
|
||||
assert_eq!(
|
||||
"binnamebuilt".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::BinNameBuilt
|
||||
);
|
||||
assert_eq!(
|
||||
"infersubcommands".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::InferSubcommands
|
||||
);
|
||||
assert!("hahahaha".parse::<AppSettings>().is_err());
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,9 +1,6 @@
|
|||
// Internal
|
||||
use crate::util::{Id, Key};
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
use yaml_rust::Yaml;
|
||||
|
||||
/// Family of related [arguments].
|
||||
///
|
||||
/// By placing arguments in a logical group, you can create easier requirement and
|
||||
|
@ -118,7 +115,7 @@ impl<'help> ArgGroup<'help> {
|
|||
///
|
||||
/// ```rust
|
||||
/// # use clap::{Command, ArgGroup};
|
||||
/// ArgGroup::default().name("config")
|
||||
/// ArgGroup::default().id("config")
|
||||
/// # ;
|
||||
/// ```
|
||||
#[must_use]
|
||||
|
@ -128,15 +125,6 @@ impl<'help> ArgGroup<'help> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgGroup::id`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.1.0", note = "Replaced with `ArgGroup::id`")
|
||||
)]
|
||||
pub fn name<S: Into<&'help str>>(self, n: S) -> Self {
|
||||
self.id(n)
|
||||
}
|
||||
|
||||
/// Adds an [argument] to this group by name
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -434,30 +422,6 @@ impl<'help> ArgGroup<'help> {
|
|||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgGroup::new`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "Replaced with `ArgGroup::new`")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
pub fn with_name<S: Into<&'help str>>(n: S) -> Self {
|
||||
Self::new(n)
|
||||
}
|
||||
|
||||
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
|
||||
#[cfg(feature = "yaml")]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Maybe clap::Parser would fit your use case? (Issue #3087)"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
pub fn from_yaml(yaml: &'help Yaml) -> Self {
|
||||
Self::from(yaml)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'help> From<&'_ ArgGroup<'help>> for ArgGroup<'help> {
|
||||
|
@ -474,65 +438,23 @@ impl<'help> From<&'_ ArgGroup<'help>> for ArgGroup<'help> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
|
||||
#[cfg(feature = "yaml")]
|
||||
impl<'help> From<&'help Yaml> for ArgGroup<'help> {
|
||||
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
|
||||
fn from(y: &'help Yaml) -> Self {
|
||||
let b = y.as_hash().expect("ArgGroup::from::<Yaml> expects a table");
|
||||
// We WANT this to panic on error...so expect() is good.
|
||||
let mut a = ArgGroup::default();
|
||||
let group_settings = if b.len() == 1 {
|
||||
let name_yaml = b.keys().next().expect("failed to get name");
|
||||
let name_str = name_yaml
|
||||
.as_str()
|
||||
.expect("failed to convert arg YAML name to str");
|
||||
a.name = name_str;
|
||||
a.id = Id::from(&a.name);
|
||||
b.get(name_yaml)
|
||||
.expect("failed to get name_str")
|
||||
.as_hash()
|
||||
.expect("failed to convert to a hash")
|
||||
} else {
|
||||
b
|
||||
};
|
||||
|
||||
for (k, v) in group_settings {
|
||||
a = match k.as_str().unwrap() {
|
||||
"required" => a.required(v.as_bool().unwrap()),
|
||||
"multiple" => a.multiple(v.as_bool().unwrap()),
|
||||
"args" => yaml_vec_or_str!(a, v, arg),
|
||||
"arg" => {
|
||||
if let Some(ys) = v.as_str() {
|
||||
a = a.arg(ys);
|
||||
}
|
||||
a
|
||||
}
|
||||
"requires" => yaml_vec_or_str!(a, v, requires),
|
||||
"conflicts_with" => yaml_vec_or_str!(a, v, conflicts_with),
|
||||
"name" => {
|
||||
if let Some(ys) = v.as_str() {
|
||||
a = a.id(ys);
|
||||
}
|
||||
a
|
||||
}
|
||||
s => panic!(
|
||||
"Unknown ArgGroup setting '{}' in YAML file for \
|
||||
ArgGroup '{}'",
|
||||
s, a.name
|
||||
),
|
||||
}
|
||||
impl Clone for ArgGroup<'_> {
|
||||
fn clone(&self) -> Self {
|
||||
ArgGroup {
|
||||
id: self.id.clone(),
|
||||
name: self.name,
|
||||
required: self.required,
|
||||
args: self.args.clone(),
|
||||
requires: self.requires.clone(),
|
||||
conflicts: self.conflicts.clone(),
|
||||
multiple: self.multiple,
|
||||
}
|
||||
|
||||
a
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::ArgGroup;
|
||||
#[cfg(feature = "yaml")]
|
||||
use yaml_rust::YamlLoader;
|
||||
|
||||
#[test]
|
||||
fn groups() {
|
||||
|
@ -581,35 +503,6 @@ mod test {
|
|||
assert_eq!(g2.conflicts, confs);
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
#[test]
|
||||
fn test_yaml() {
|
||||
let g_yaml = "name: test
|
||||
args:
|
||||
- a1
|
||||
- a4
|
||||
- a2
|
||||
- a3
|
||||
conflicts_with:
|
||||
- c1
|
||||
- c2
|
||||
- c3
|
||||
- c4
|
||||
requires:
|
||||
- r1
|
||||
- r2
|
||||
- r3
|
||||
- r4";
|
||||
let yaml = &YamlLoader::load_from_str(g_yaml).expect("failed to load YAML file")[0];
|
||||
let g = ArgGroup::from(yaml);
|
||||
let args = vec!["a1".into(), "a4".into(), "a2".into(), "a3".into()];
|
||||
let reqs = vec!["r1".into(), "r2".into(), "r3".into(), "r4".into()];
|
||||
let confs = vec!["c1".into(), "c2".into(), "c3".into(), "c4".into()];
|
||||
assert_eq!(g.args, args);
|
||||
assert_eq!(g.requires, reqs);
|
||||
assert_eq!(g.conflicts, confs);
|
||||
}
|
||||
|
||||
// This test will *fail to compile* if ArgGroup is not Send + Sync
|
||||
#[test]
|
||||
fn arg_group_send_sync() {
|
||||
|
@ -617,17 +510,3 @@ requires:
|
|||
foo(ArgGroup::new("test"))
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for ArgGroup<'_> {
|
||||
fn clone(&self) -> Self {
|
||||
ArgGroup {
|
||||
id: self.id.clone(),
|
||||
name: self.name,
|
||||
required: self.required,
|
||||
args: self.args.clone(),
|
||||
requires: self.requires.clone(),
|
||||
conflicts: self.conflicts.clone(),
|
||||
multiple: self.multiple,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
// Std
|
||||
use std::ops::BitOr;
|
||||
#[cfg(feature = "yaml")]
|
||||
use std::str::FromStr;
|
||||
|
||||
// Third party
|
||||
use bitflags::bitflags;
|
||||
|
@ -11,9 +9,8 @@ use bitflags::bitflags;
|
|||
#[allow(unused)]
|
||||
use crate::Arg;
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct ArgFlags(Flags);
|
||||
pub(crate) struct ArgFlags(Flags);
|
||||
|
||||
impl Default for ArgFlags {
|
||||
fn default() -> Self {
|
||||
|
@ -31,239 +28,28 @@ impl Default for ArgFlags {
|
|||
/// [`Arg::is_set`]: crate::Arg::is_set()
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub enum ArgSettings {
|
||||
/// Deprecated, replaced with [`Arg::required`] and [`Arg::is_required_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::required` and `Arg::is_required_set`"
|
||||
)
|
||||
)]
|
||||
pub(crate) enum ArgSettings {
|
||||
Required,
|
||||
/// Deprecated, replaced with [`Arg::multiple_values`] and [`Arg::is_multiple_values_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::multiple_values` and `Arg::`is_multiple_values_set`"
|
||||
)
|
||||
)]
|
||||
MultipleValues,
|
||||
/// Deprecated, replaced with [`Arg::action`] ([Issue #3772](https://github.com/clap-rs/clap/issues/3772))
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.1.0", note = "Replaced with `Arg::action` (Issue #3772)")
|
||||
)]
|
||||
MultipleOccurrences,
|
||||
/// Deprecated, see [`ArgSettings::MultipleOccurrences`] (most likely what you want) and
|
||||
/// [`ArgSettings::MultipleValues`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Split into `Arg::multiple_occurrences` (most likely what you want) and `Arg::multiple_values`"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
Multiple,
|
||||
/// Deprecated, replaced with [`Arg::value_parser(NonEmptyStringValueParser::new())`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::value_parser(NonEmptyStringValueParser::new())`"
|
||||
)
|
||||
)]
|
||||
ForbidEmptyValues,
|
||||
/// Deprecated, replaced with [`Arg::global`] and [`Arg::is_global_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::global` and `Arg::is_global_set`"
|
||||
)
|
||||
)]
|
||||
Global,
|
||||
/// Deprecated, replaced with [`Arg::hide`] and [`Arg::is_hide_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::hide` and `Arg::is_hide_set`"
|
||||
)
|
||||
)]
|
||||
Hidden,
|
||||
/// Deprecated, replaced with [`Arg::takes_value`] and [`Arg::is_takes_value_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::takes_value` and `Arg::is_takes_value_set`"
|
||||
)
|
||||
)]
|
||||
TakesValue,
|
||||
/// Deprecated, replaced with [`Arg::use_value_delimiter`] and
|
||||
/// [`Arg::is_use_value_delimiter_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::use_value_delimiter` and `Arg::is_use_value_delimiter_set`"
|
||||
)
|
||||
)]
|
||||
UseValueDelimiter,
|
||||
/// Deprecated, replaced with [`Arg::next_line_help`] and [`Arg::is_next_line_help_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::next_line_help` and `Arg::is_next_line_help_set`"
|
||||
)
|
||||
)]
|
||||
NextLineHelp,
|
||||
/// Deprecated, replaced with [`Arg::require_value_delimiter`] and
|
||||
/// [`Arg::is_require_value_delimiter_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::require_value_delimiter` and `Arg::is_require_value_delimiter_set`"
|
||||
)
|
||||
)]
|
||||
RequireDelimiter,
|
||||
/// Deprecated, replaced with [`Arg::hide_possible_values`] and
|
||||
/// [`Arg::is_hide_possible_values_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::hide_possible_values` and `Arg::is_hide_possible_values_set`"
|
||||
)
|
||||
)]
|
||||
HidePossibleValues,
|
||||
/// Deprecated, replaced with [`Arg::allow_hyphen_values`] and
|
||||
/// [`Arg::is_allow_hyphen_values_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::allow_hyphen_values` and `Arg::is_allow_hyphen_values_set`"
|
||||
)
|
||||
)]
|
||||
AllowHyphenValues,
|
||||
/// Deprecated, replaced with [`Arg::allow_hyphen_values`] and
|
||||
/// [`Arg::is_allow_hyphen_values_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Replaced with `Arg::allow_hyphen_values` and `Arg::is_allow_hyphen_values_set`"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
AllowLeadingHyphen,
|
||||
/// Deprecated, replaced with [`Arg::require_equals`] and [`Arg::is_require_equals_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::require_equals` and `Arg::is_require_equals_set`"
|
||||
)
|
||||
)]
|
||||
RequireEquals,
|
||||
/// Deprecated, replaced with [`Arg::last`] and [`Arg::is_last_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::last` and `Arg::is_last_set`"
|
||||
)
|
||||
)]
|
||||
Last,
|
||||
/// Deprecated, replaced with [`Arg::hide_default_value`] and [`Arg::is_hide_default_value_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::hide_default_value` and `Arg::is_hide_default_value_set`"
|
||||
)
|
||||
)]
|
||||
HideDefaultValue,
|
||||
/// Deprecated, replaced with [`Arg::ignore_case`] and [`Arg::is_ignore_case_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::ignore_case` and `Arg::is_ignore_case_set`"
|
||||
)
|
||||
)]
|
||||
IgnoreCase,
|
||||
/// Deprecated, replaced with [`Arg::ignore_case`] and [`Arg::is_ignore_case_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Replaced with `Arg::ignore_case` and `Arg::is_ignore_case_set`"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
CaseInsensitive,
|
||||
/// Deprecated, replaced with [`Arg::hide_env`] and [`Arg::is_hide_env_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::hide_env` and `Arg::is_hide_env_set`"
|
||||
)
|
||||
)]
|
||||
#[cfg(feature = "env")]
|
||||
HideEnv,
|
||||
/// Deprecated, replaced with [`Arg::hide_env_values`] and [`Arg::is_hide_env_values_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::hide_env_values` and `Arg::is_hide_env_values_set`"
|
||||
)
|
||||
)]
|
||||
#[cfg(feature = "env")]
|
||||
HideEnvValues,
|
||||
/// Deprecated, replaced with [`Arg::hide_short_help`] and [`Arg::is_hide_short_help_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::hide_short_help` and `Arg::is_hide_short_help_set`"
|
||||
)
|
||||
)]
|
||||
HiddenShortHelp,
|
||||
/// Deprecated, replaced with [`Arg::hide_long_help`] and [`Arg::is_hide_long_help_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::hide_long_help` and `Arg::is_hide_long_help_set`"
|
||||
)
|
||||
)]
|
||||
HiddenLongHelp,
|
||||
/// Deprecated, replaced with [`Arg::allow_invalid_utf8`] and [`Arg::is_allow_invalid_utf8_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::allow_invalid_utf8` and `Arg::is_allow_invalid_utf8_set`"
|
||||
)
|
||||
)]
|
||||
AllowInvalidUtf8,
|
||||
/// Deprecated, replaced with [`Arg::exclusive`] and [`Arg::is_exclusive_set`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `Arg::exclusive` and `Arg::is_exclusive_set`"
|
||||
)
|
||||
)]
|
||||
Exclusive,
|
||||
}
|
||||
|
||||
|
@ -271,7 +57,6 @@ bitflags! {
|
|||
struct Flags: u32 {
|
||||
const REQUIRED = 1;
|
||||
const MULTIPLE_OCC = 1 << 1;
|
||||
const NO_EMPTY_VALS = 1 << 2;
|
||||
const GLOBAL = 1 << 3;
|
||||
const HIDDEN = 1 << 4;
|
||||
const TAKES_VAL = 1 << 5;
|
||||
|
@ -293,7 +78,6 @@ bitflags! {
|
|||
const MULTIPLE = Self::MULTIPLE_OCC.bits | Self::MULTIPLE_VALS.bits;
|
||||
#[cfg(feature = "env")]
|
||||
const HIDE_ENV = 1 << 21;
|
||||
const UTF8_NONE = 1 << 22;
|
||||
const EXCLUSIVE = 1 << 23;
|
||||
const NO_OP = 0;
|
||||
}
|
||||
|
@ -303,8 +87,6 @@ impl_settings! { ArgSettings, ArgFlags,
|
|||
Required => Flags::REQUIRED,
|
||||
MultipleOccurrences => Flags::MULTIPLE_OCC,
|
||||
MultipleValues => Flags::MULTIPLE_VALS,
|
||||
Multiple => Flags::MULTIPLE,
|
||||
ForbidEmptyValues => Flags::NO_EMPTY_VALS,
|
||||
Global => Flags::GLOBAL,
|
||||
Hidden => Flags::HIDDEN,
|
||||
TakesValue => Flags::TAKES_VAL,
|
||||
|
@ -313,11 +95,9 @@ impl_settings! { ArgSettings, ArgFlags,
|
|||
RequireDelimiter => Flags::REQ_DELIM,
|
||||
HidePossibleValues => Flags::HIDE_POS_VALS,
|
||||
AllowHyphenValues => Flags::ALLOW_TAC_VALS,
|
||||
AllowLeadingHyphen => Flags::ALLOW_TAC_VALS,
|
||||
RequireEquals => Flags::REQUIRE_EQUALS,
|
||||
Last => Flags::LAST,
|
||||
IgnoreCase => Flags::CASE_INSENSITIVE,
|
||||
CaseInsensitive => Flags::CASE_INSENSITIVE,
|
||||
#[cfg(feature = "env")]
|
||||
HideEnv => Flags::HIDE_ENV,
|
||||
#[cfg(feature = "env")]
|
||||
|
@ -325,132 +105,53 @@ impl_settings! { ArgSettings, ArgFlags,
|
|||
HideDefaultValue => Flags::HIDE_DEFAULT_VAL,
|
||||
HiddenShortHelp => Flags::HIDDEN_SHORT_H,
|
||||
HiddenLongHelp => Flags::HIDDEN_LONG_H,
|
||||
AllowInvalidUtf8 => Flags::UTF8_NONE,
|
||||
Exclusive => Flags::EXCLUSIVE
|
||||
}
|
||||
|
||||
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
|
||||
#[cfg(feature = "yaml")]
|
||||
impl FromStr for ArgSettings {
|
||||
type Err = String;
|
||||
fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
|
||||
#[allow(deprecated)]
|
||||
#[allow(unreachable_patterns)]
|
||||
match &*s.to_ascii_lowercase() {
|
||||
"required" => Ok(ArgSettings::Required),
|
||||
"multipleoccurrences" => Ok(ArgSettings::MultipleOccurrences),
|
||||
"multiplevalues" => Ok(ArgSettings::MultipleValues),
|
||||
"multiple" => Ok(ArgSettings::Multiple),
|
||||
"forbidemptyvalues" => Ok(ArgSettings::ForbidEmptyValues),
|
||||
"global" => Ok(ArgSettings::Global),
|
||||
"hidden" => Ok(ArgSettings::Hidden),
|
||||
"takesvalue" => Ok(ArgSettings::TakesValue),
|
||||
"usevaluedelimiter" => Ok(ArgSettings::UseValueDelimiter),
|
||||
"nextlinehelp" => Ok(ArgSettings::NextLineHelp),
|
||||
"requiredelimiter" => Ok(ArgSettings::RequireDelimiter),
|
||||
"hidepossiblevalues" => Ok(ArgSettings::HidePossibleValues),
|
||||
"allowhyphenvalues" => Ok(ArgSettings::AllowHyphenValues),
|
||||
"allowleadinghypyhen" => Ok(ArgSettings::AllowLeadingHyphen),
|
||||
"requireequals" => Ok(ArgSettings::RequireEquals),
|
||||
"last" => Ok(ArgSettings::Last),
|
||||
"ignorecase" => Ok(ArgSettings::IgnoreCase),
|
||||
"caseinsensitive" => Ok(ArgSettings::CaseInsensitive),
|
||||
#[cfg(feature = "env")]
|
||||
"hideenv" => Ok(ArgSettings::HideEnv),
|
||||
#[cfg(feature = "env")]
|
||||
"hideenvvalues" => Ok(ArgSettings::HideEnvValues),
|
||||
"hidedefaultvalue" => Ok(ArgSettings::HideDefaultValue),
|
||||
"hiddenshorthelp" => Ok(ArgSettings::HiddenShortHelp),
|
||||
"hiddenlonghelp" => Ok(ArgSettings::HiddenLongHelp),
|
||||
"allowinvalidutf8" => Ok(ArgSettings::AllowInvalidUtf8),
|
||||
"exclusive" => Ok(ArgSettings::Exclusive),
|
||||
_ => Err(format!("unknown AppSetting: `{}`", s)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
#[cfg(feature = "yaml")]
|
||||
fn arg_settings_fromstr() {
|
||||
use super::ArgSettings;
|
||||
use super::*;
|
||||
use crate::Arg;
|
||||
|
||||
assert_eq!(
|
||||
"allowhyphenvalues".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::AllowHyphenValues
|
||||
);
|
||||
assert_eq!(
|
||||
"forbidemptyvalues".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::ForbidEmptyValues
|
||||
);
|
||||
assert_eq!(
|
||||
"hidepossiblevalues".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::HidePossibleValues
|
||||
);
|
||||
assert_eq!(
|
||||
"hidden".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::Hidden
|
||||
);
|
||||
assert_eq!(
|
||||
"nextlinehelp".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::NextLineHelp
|
||||
);
|
||||
assert_eq!(
|
||||
"requiredelimiter".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::RequireDelimiter
|
||||
);
|
||||
assert_eq!(
|
||||
"required".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::Required
|
||||
);
|
||||
assert_eq!(
|
||||
"takesvalue".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::TakesValue
|
||||
);
|
||||
assert_eq!(
|
||||
"usevaluedelimiter".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::UseValueDelimiter
|
||||
);
|
||||
assert_eq!(
|
||||
"requireequals".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::RequireEquals
|
||||
);
|
||||
assert_eq!("last".parse::<ArgSettings>().unwrap(), ArgSettings::Last);
|
||||
assert_eq!(
|
||||
"hidedefaultvalue".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::HideDefaultValue
|
||||
);
|
||||
assert_eq!(
|
||||
"ignorecase".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::IgnoreCase
|
||||
);
|
||||
#[cfg(feature = "env")]
|
||||
assert_eq!(
|
||||
"hideenv".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::HideEnv
|
||||
);
|
||||
#[cfg(feature = "env")]
|
||||
assert_eq!(
|
||||
"hideenvvalues".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::HideEnvValues
|
||||
);
|
||||
assert_eq!(
|
||||
"hiddenshorthelp".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::HiddenShortHelp
|
||||
);
|
||||
assert_eq!(
|
||||
"hiddenlonghelp".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::HiddenLongHelp
|
||||
);
|
||||
assert_eq!(
|
||||
"allowinvalidutf8".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::AllowInvalidUtf8
|
||||
);
|
||||
assert_eq!(
|
||||
"exclusive".parse::<ArgSettings>().unwrap(),
|
||||
ArgSettings::Exclusive
|
||||
);
|
||||
assert!("hahahaha".parse::<ArgSettings>().is_err());
|
||||
#[test]
|
||||
fn setting() {
|
||||
let m = Arg::new("setting").setting(ArgSettings::Required);
|
||||
assert!(m.is_required_set());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unset_setting() {
|
||||
let m = Arg::new("unset_setting").setting(ArgSettings::Required);
|
||||
assert!(m.is_required_set());
|
||||
|
||||
let m = m.unset_setting(ArgSettings::Required);
|
||||
assert!(!m.is_required_set(), "{:#?}", m);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setting_bitor() {
|
||||
let m = Arg::new("setting_bitor")
|
||||
.setting(ArgSettings::Required | ArgSettings::Hidden | ArgSettings::Last);
|
||||
|
||||
assert!(m.is_required_set());
|
||||
assert!(m.is_hide_set());
|
||||
assert!(m.is_last_set());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unset_setting_bitor() {
|
||||
let m = Arg::new("unset_setting_bitor")
|
||||
.setting(ArgSettings::Required)
|
||||
.setting(ArgSettings::Hidden)
|
||||
.setting(ArgSettings::Last);
|
||||
|
||||
assert!(m.is_required_set());
|
||||
assert!(m.is_hide_set());
|
||||
assert!(m.is_last_set());
|
||||
|
||||
let m = m.unset_setting(ArgSettings::Required | ArgSettings::Hidden | ArgSettings::Last);
|
||||
assert!(!m.is_required_set(), "{:#?}", m);
|
||||
assert!(!m.is_hide_set(), "{:#?}", m);
|
||||
assert!(!m.is_last_set(), "{:#?}", m);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -265,14 +265,6 @@ pub(crate) fn assert_app(cmd: &Command) {
|
|||
arg.name
|
||||
);
|
||||
|
||||
// validators
|
||||
assert!(
|
||||
arg.validator.is_none() || arg.validator_os.is_none(),
|
||||
"Command {}: Argument '{}' has both `validator` and `validator_os` set which is not allowed",
|
||||
cmd.get_name(),
|
||||
arg.name
|
||||
);
|
||||
|
||||
if arg.get_value_hint() == ValueHint::CommandWithArguments {
|
||||
assert!(
|
||||
arg.is_positional(),
|
||||
|
@ -745,11 +737,6 @@ fn assert_arg_flags(arg: &Arg) {
|
|||
checker!(is_hide_default_value_set requires is_takes_value_set);
|
||||
checker!(is_multiple_values_set requires is_takes_value_set);
|
||||
checker!(is_ignore_case_set requires is_takes_value_set);
|
||||
{
|
||||
#![allow(deprecated)]
|
||||
checker!(is_forbid_empty_values_set requires is_takes_value_set);
|
||||
checker!(is_allow_invalid_utf8_set requires is_takes_value_set);
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_defaults<'d>(
|
||||
|
@ -758,73 +745,6 @@ fn assert_defaults<'d>(
|
|||
defaults: impl IntoIterator<Item = &'d std::ffi::OsStr>,
|
||||
) {
|
||||
for default_os in defaults {
|
||||
if let Some(default_s) = default_os.to_str() {
|
||||
if !arg.possible_vals.is_empty() {
|
||||
if let Some(delim) = arg.get_value_delimiter() {
|
||||
for part in default_s.split(delim) {
|
||||
assert!(
|
||||
arg.possible_vals.iter().any(|possible_val| {
|
||||
possible_val.matches(part, arg.is_ignore_case_set())
|
||||
}),
|
||||
"Argument `{}`'s {}={} doesn't match possible values",
|
||||
arg.name,
|
||||
field,
|
||||
part
|
||||
)
|
||||
}
|
||||
} else {
|
||||
assert!(
|
||||
arg.possible_vals.iter().any(|possible_val| {
|
||||
possible_val.matches(default_s, arg.is_ignore_case_set())
|
||||
}),
|
||||
"Argument `{}`'s {}={} doesn't match possible values",
|
||||
arg.name,
|
||||
field,
|
||||
default_s
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(validator) = arg.validator.as_ref() {
|
||||
let mut validator = validator.lock().unwrap();
|
||||
if let Some(delim) = arg.get_value_delimiter() {
|
||||
for part in default_s.split(delim) {
|
||||
if let Err(err) = validator(part) {
|
||||
panic!(
|
||||
"Argument `{}`'s {}={} failed validation: {}",
|
||||
arg.name, field, part, err
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if let Err(err) = validator(default_s) {
|
||||
panic!(
|
||||
"Argument `{}`'s {}={} failed validation: {}",
|
||||
arg.name, field, default_s, err
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(validator) = arg.validator_os.as_ref() {
|
||||
let mut validator = validator.lock().unwrap();
|
||||
if let Some(delim) = arg.get_value_delimiter() {
|
||||
let default_os = RawOsStr::new(default_os);
|
||||
for part in default_os.split(delim) {
|
||||
if let Err(err) = validator(&part.to_os_str()) {
|
||||
panic!(
|
||||
"Argument `{}`'s {}={:?} failed validation: {}",
|
||||
arg.name, field, part, err
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if let Err(err) = validator(default_os) {
|
||||
panic!(
|
||||
"Argument `{}`'s {}={:?} failed validation: {}",
|
||||
arg.name, field, default_os, err
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let value_parser = arg.get_value_parser();
|
||||
let assert_cmd = Command::new("assert");
|
||||
if let Some(delim) = arg.get_value_delimiter() {
|
||||
|
|
|
@ -1,180 +0,0 @@
|
|||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_tuple2 {
|
||||
($a:ident, $v:ident, $c:ident) => {{
|
||||
if let Some(vec) = $v.as_vec() {
|
||||
for ys in vec {
|
||||
if let Some(tup) = ys.as_vec() {
|
||||
debug_assert_eq!(2, tup.len());
|
||||
$a = $a.$c(yaml_str!(tup[0]), yaml_str!(tup[1]));
|
||||
} else {
|
||||
panic!("Failed to convert YAML value to vec");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic!("Failed to convert YAML value to vec");
|
||||
}
|
||||
$a
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_tuple3 {
|
||||
($a:ident, $v:ident, $c:ident) => {{
|
||||
if let Some(vec) = $v.as_vec() {
|
||||
for ys in vec {
|
||||
if let Some(tup) = ys.as_vec() {
|
||||
debug_assert_eq!(3, tup.len());
|
||||
$a = $a.$c(
|
||||
yaml_str!(tup[0]),
|
||||
yaml_opt_str!(tup[1]),
|
||||
yaml_opt_str!(tup[2]),
|
||||
);
|
||||
} else {
|
||||
panic!("Failed to convert YAML value to vec");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic!("Failed to convert YAML value to vec");
|
||||
}
|
||||
$a
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_vec_or_str {
|
||||
($a:ident, $v:ident, $c:ident) => {{
|
||||
let maybe_vec = $v.as_vec();
|
||||
if let Some(vec) = maybe_vec {
|
||||
for ys in vec {
|
||||
if let Some(s) = ys.as_str() {
|
||||
$a = $a.$c(s);
|
||||
} else {
|
||||
panic!("Failed to convert YAML value {:?} to a string", ys);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let Some(s) = $v.as_str() {
|
||||
$a = $a.$c(s);
|
||||
} else {
|
||||
panic!(
|
||||
"Failed to convert YAML value {:?} to either a vec or string",
|
||||
$v
|
||||
);
|
||||
}
|
||||
}
|
||||
$a
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_vec {
|
||||
($a:ident, $v:ident, $c:ident) => {{
|
||||
let maybe_vec = $v.as_vec();
|
||||
if let Some(vec) = maybe_vec {
|
||||
let content = vec.into_iter().map(|ys| {
|
||||
if let Some(s) = ys.as_str() {
|
||||
s
|
||||
} else {
|
||||
panic!("Failed to convert YAML value {:?} to a string", ys);
|
||||
}
|
||||
});
|
||||
$a = $a.$c(content)
|
||||
} else {
|
||||
panic!("Failed to convert YAML value {:?} to a vec", $v);
|
||||
}
|
||||
$a
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_opt_str {
|
||||
($v:expr) => {{
|
||||
if !$v.is_null() {
|
||||
Some(
|
||||
$v.as_str()
|
||||
.unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v)),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_char {
|
||||
($v:expr) => {{
|
||||
$v.as_str()
|
||||
.unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v))
|
||||
.chars()
|
||||
.next()
|
||||
.unwrap_or_else(|| panic!("Expected char"))
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_str {
|
||||
($v:expr) => {{
|
||||
$v.as_str()
|
||||
.unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v))
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_to_char {
|
||||
($a:ident, $v:ident, $c:ident) => {{
|
||||
$a.$c(yaml_char!($v))
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_to_str {
|
||||
($a:ident, $v:ident, $c:ident) => {{
|
||||
$a.$c(yaml_str!($v))
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_to_bool {
|
||||
($a:ident, $v:ident, $c:ident) => {{
|
||||
$a.$c($v
|
||||
.as_bool()
|
||||
.unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v)))
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_to_usize {
|
||||
($a:ident, $v:ident, $c:ident) => {{
|
||||
$a.$c($v
|
||||
.as_i64()
|
||||
.unwrap_or_else(|| panic!("failed to convert YAML {:?} value to a string", $v))
|
||||
as usize)
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_to_setting {
|
||||
($a:ident, $v:ident, $c:ident, $s:ident, $t:literal, $n:expr) => {{
|
||||
if let Some(v) = $v.as_vec() {
|
||||
for ys in v {
|
||||
if let Some(s) = ys.as_str() {
|
||||
$a = $a.$c(s.parse::<$s>().unwrap_or_else(|_| {
|
||||
panic!("Unknown {} '{}' found in YAML file for {}", $t, s, $n)
|
||||
}));
|
||||
} else {
|
||||
panic!(
|
||||
"Failed to convert YAML {:?} value to an array of strings",
|
||||
$v
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if let Some(v) = $v.as_str() {
|
||||
$a = $a.$c(v
|
||||
.parse::<$s>()
|
||||
.unwrap_or_else(|_| panic!("Unknown {} '{}' found in YAML file for {}", $t, v, $n)))
|
||||
} else {
|
||||
panic!("Failed to convert YAML {:?} value to a string", $v);
|
||||
}
|
||||
$a
|
||||
}};
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
//! Define [`Command`] line [arguments][`Arg`]
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
mod action;
|
||||
mod app_settings;
|
||||
mod arg;
|
||||
|
@ -11,13 +8,9 @@ mod arg_predicate;
|
|||
mod arg_settings;
|
||||
mod command;
|
||||
mod possible_value;
|
||||
mod usage_parser;
|
||||
mod value_hint;
|
||||
mod value_parser;
|
||||
|
||||
#[cfg(feature = "regex")]
|
||||
mod regex;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
mod debug_asserts;
|
||||
|
||||
|
@ -28,7 +21,6 @@ pub use action::ArgAction;
|
|||
pub use app_settings::{AppFlags, AppSettings};
|
||||
pub use arg::Arg;
|
||||
pub use arg_group::ArgGroup;
|
||||
pub use arg_settings::{ArgFlags, ArgSettings};
|
||||
pub use command::Command;
|
||||
pub use possible_value::PossibleValue;
|
||||
pub use value_hint::ValueHint;
|
||||
|
@ -50,12 +42,7 @@ pub use value_parser::NonEmptyStringValueParser;
|
|||
pub use value_parser::OsStringValueParser;
|
||||
pub use value_parser::PathBufValueParser;
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub use command::App;
|
||||
|
||||
#[cfg(feature = "regex")]
|
||||
pub use self::regex::RegexRef;
|
||||
|
||||
pub(crate) use action::CountType;
|
||||
pub(crate) use arg::display_arg_val;
|
||||
pub(crate) use arg_predicate::ArgPredicate;
|
||||
pub(crate) use arg_settings::{ArgFlags, ArgSettings};
|
||||
|
|
|
@ -50,7 +50,7 @@ impl<'help> PossibleValue<'help> {
|
|||
/// # ;
|
||||
/// ```
|
||||
/// [hidden]: PossibleValue::hide
|
||||
/// [possible value]: crate::Arg::possible_values
|
||||
/// [possible value]: crate::builder::PossibleValuesParser
|
||||
/// [`Arg::hide_possible_values(true)`]: crate::Arg::hide_possible_values()
|
||||
pub fn new(name: &'help str) -> Self {
|
||||
PossibleValue {
|
||||
|
@ -162,16 +162,6 @@ impl<'help> PossibleValue<'help> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`PossibleValue::is_hide_set`]
|
||||
#[inline]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.1.0", note = "Replaced with `PossibleValue::is_hide_set`")
|
||||
)]
|
||||
pub fn is_hidden(&self) -> bool {
|
||||
self.is_hide_set()
|
||||
}
|
||||
|
||||
/// Report if [`PossibleValue::hide`] is set
|
||||
#[inline]
|
||||
pub fn is_hide_set(&self) -> bool {
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
use ::regex::{Error, Regex, RegexSet};
|
||||
|
||||
use core::{convert::TryFrom, ops::Deref, str::FromStr};
|
||||
use std::borrow::Cow;
|
||||
|
||||
/// Contains either a regular expression or a set of them or a reference to one.
|
||||
///
|
||||
/// See [Arg::validator_regex(][crate::Arg::validator_regex] to set this on an argument.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum RegexRef<'a> {
|
||||
/// Used if the underlying is a regex set
|
||||
RegexSet(Cow<'a, RegexSet>),
|
||||
/// Used if the underlying is a regex
|
||||
Regex(Cow<'a, Regex>),
|
||||
}
|
||||
|
||||
impl<'a> RegexRef<'a> {
|
||||
pub(crate) fn is_match(&self, text: &str) -> bool {
|
||||
match self {
|
||||
Self::Regex(r) => r.deref().is_match(text),
|
||||
Self::RegexSet(r) => r.deref().is_match(text),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Regex> for RegexRef<'a> {
|
||||
fn from(r: &'a Regex) -> Self {
|
||||
Self::Regex(Cow::Borrowed(r))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<Regex> for RegexRef<'a> {
|
||||
fn from(r: Regex) -> Self {
|
||||
Self::Regex(Cow::Owned(r))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a RegexSet> for RegexRef<'a> {
|
||||
fn from(r: &'a RegexSet) -> Self {
|
||||
Self::RegexSet(Cow::Borrowed(r))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<RegexSet> for RegexRef<'a> {
|
||||
fn from(r: RegexSet) -> Self {
|
||||
Self::RegexSet(Cow::Owned(r))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<&'a str> for RegexRef<'a> {
|
||||
type Error = <Self as FromStr>::Err;
|
||||
|
||||
fn try_from(r: &'a str) -> Result<Self, Self::Error> {
|
||||
Self::from_str(r)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromStr for RegexRef<'a> {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Regex::from_str(s).map(|v| Self::Regex(Cow::Owned(v)))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use core::convert::TryInto;
|
||||
|
||||
#[test]
|
||||
fn test_try_from_with_valid_string() {
|
||||
let t: Result<RegexRef, _> = "^Hello, World$".try_into();
|
||||
assert!(t.is_ok())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_from_with_invalid_string() {
|
||||
let t: Result<RegexRef, _> = "^Hello, World)$".try_into();
|
||||
assert!(t.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str() {
|
||||
let t: Result<RegexRef, _> = RegexRef::from_str("^Hello, World");
|
||||
assert!(t.is_ok());
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
131
src/derive.rs
131
src/derive.rs
|
@ -36,10 +36,10 @@ use std::ffi::OsString;
|
|||
/// #[clap(name = "demo")]
|
||||
/// struct Context {
|
||||
/// /// More verbose output
|
||||
/// #[clap(long)]
|
||||
/// #[clap(long, value_parser)]
|
||||
/// verbose: bool,
|
||||
/// /// An optional name
|
||||
/// #[clap(short, long)]
|
||||
/// #[clap(short, long, value_parser)]
|
||||
/// name: Option<String>,
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -153,95 +153,6 @@ pub trait Parser: FromArgMatches + CommandFactory + Sized {
|
|||
<Self as FromArgMatches>::update_from_arg_matches_mut(self, &mut matches)
|
||||
.map_err(format_error::<Self>)
|
||||
}
|
||||
|
||||
/// Deprecated, `StructOpt::clap` replaced with [`CommandFactory::command`] (derive as part of
|
||||
/// [`Parser`])
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "`StructOpt::clap` is replaced with `CommandFactory::command` (derived as part of `Parser`)"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
fn clap<'help>() -> Command<'help> {
|
||||
<Self as CommandFactory>::command()
|
||||
}
|
||||
|
||||
/// Deprecated, `StructOpt::from_clap` replaced with [`FromArgMatches::from_arg_matches_mut`] (derive as part of
|
||||
/// [`Parser`])
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "`StructOpt::from_clap` is replaced with `FromArgMatches::from_arg_matches_mut` (derived as part of `Parser`)"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
fn from_clap(matches: &ArgMatches) -> Self {
|
||||
<Self as FromArgMatches>::from_arg_matches(matches).unwrap()
|
||||
}
|
||||
|
||||
/// Deprecated, `StructOpt::from_args` replaced with `Parser::parse` (note the change in derives)
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "`StructOpt::from_args` is replaced with `Parser::parse` (note the change in derives)"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
fn from_args() -> Self {
|
||||
Self::parse()
|
||||
}
|
||||
|
||||
/// Deprecated, `StructOpt::from_args_safe` replaced with `Parser::try_parse` (note the change in derives)
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "`StructOpt::from_args_safe` is replaced with `Parser::try_parse` (note the change in derives)"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
fn from_args_safe() -> Result<Self, Error> {
|
||||
Self::try_parse()
|
||||
}
|
||||
|
||||
/// Deprecated, `StructOpt::from_iter` replaced with `Parser::parse_from` (note the change in derives)
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "`StructOpt::from_iter` is replaced with `Parser::parse_from` (note the change in derives)"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
fn from_iter<I, T>(itr: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
T: Into<OsString> + Clone,
|
||||
{
|
||||
Self::parse_from(itr)
|
||||
}
|
||||
|
||||
/// Deprecated, `StructOpt::from_iter_safe` replaced with `Parser::try_parse_from` (note the
|
||||
/// change in derives)
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "`StructOpt::from_iter_safe` is replaced with `Parser::try_parse_from` (note the change in derives)"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
fn from_iter_safe<I, T>(itr: I) -> Result<Self, Error>
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
T: Into<OsString> + Clone,
|
||||
{
|
||||
Self::try_parse_from(itr)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a [`Command`] relevant for a user-defined container.
|
||||
|
@ -251,32 +162,11 @@ pub trait CommandFactory: Sized {
|
|||
/// Build a [`Command`] that can instantiate `Self`.
|
||||
///
|
||||
/// See [`FromArgMatches::from_arg_matches_mut`] for instantiating `Self`.
|
||||
fn command<'help>() -> Command<'help> {
|
||||
#[allow(deprecated)]
|
||||
Self::into_app()
|
||||
}
|
||||
/// Deprecated, replaced with `CommandFactory::command`
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.1.0", note = "Replaced with `CommandFactory::command")
|
||||
)]
|
||||
fn into_app<'help>() -> Command<'help>;
|
||||
fn command<'help>() -> Command<'help>;
|
||||
/// Build a [`Command`] that can update `self`.
|
||||
///
|
||||
/// See [`FromArgMatches::update_from_arg_matches_mut`] for updating `self`.
|
||||
fn command_for_update<'help>() -> Command<'help> {
|
||||
#[allow(deprecated)]
|
||||
Self::into_app_for_update()
|
||||
}
|
||||
/// Deprecated, replaced with `CommandFactory::command_for_update`
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.1.0",
|
||||
note = "Replaced with `CommandFactory::command_for_update"
|
||||
)
|
||||
)]
|
||||
fn into_app_for_update<'help>() -> Command<'help>;
|
||||
fn command_for_update<'help>() -> Command<'help>;
|
||||
}
|
||||
|
||||
/// Converts an instance of [`ArgMatches`] to a user-defined container.
|
||||
|
@ -451,7 +341,7 @@ pub trait Subcommand: FromArgMatches + Sized {
|
|||
///
|
||||
/// When deriving [`Parser`], a field whose type implements `ValueEnum` can have the attribute
|
||||
/// `#[clap(value_enum)]` which will
|
||||
/// - Call [`Arg::possible_values`][crate::Arg::possible_values]
|
||||
/// - Call [EnumValueParser`][crate::builder::EnumValueParser]`
|
||||
/// - Allowing using the `#[clap(default_value_t)]` attribute without implementing `Display`.
|
||||
///
|
||||
/// See the [derive reference](crate::_derive) for attributes and best practices.
|
||||
|
@ -464,7 +354,7 @@ pub trait Subcommand: FromArgMatches + Sized {
|
|||
#[cfg_attr(feature = "derive", doc = " ```")]
|
||||
/// #[derive(clap::Parser)]
|
||||
/// struct Args {
|
||||
/// #[clap(value_enum)]
|
||||
/// #[clap(value_enum, value_parser)]
|
||||
/// level: Level,
|
||||
/// }
|
||||
///
|
||||
|
@ -525,13 +415,12 @@ impl<T: Parser> Parser for Box<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<T: CommandFactory> CommandFactory for Box<T> {
|
||||
fn into_app<'help>() -> Command<'help> {
|
||||
<T as CommandFactory>::into_app()
|
||||
fn command<'help>() -> Command<'help> {
|
||||
<T as CommandFactory>::command()
|
||||
}
|
||||
fn into_app_for_update<'help>() -> Command<'help> {
|
||||
<T as CommandFactory>::into_app_for_update()
|
||||
fn command_for_update<'help>() -> Command<'help> {
|
||||
<T as CommandFactory>::command_for_update()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,10 +18,6 @@ pub enum ContextKind {
|
|||
ExpectedNumValues,
|
||||
/// Minimum number of allowed values
|
||||
MinValues,
|
||||
/// Number of occurrences present
|
||||
ActualNumOccurrences,
|
||||
/// Maximum number of allowed occurrences
|
||||
MaxOccurrences,
|
||||
/// Potential fix for the user
|
||||
SuggestedCommand,
|
||||
/// Potential fix for the user
|
||||
|
|
|
@ -93,7 +93,7 @@ pub enum ErrorKind {
|
|||
/// let res = Command::new("prog")
|
||||
/// .arg(Arg::new("color")
|
||||
/// .takes_value(true)
|
||||
/// .forbid_empty_values(true)
|
||||
/// .value_parser(clap::builder::NonEmptyStringValueParser::new())
|
||||
/// .long("color"))
|
||||
/// .try_get_matches_from(vec!["prog", "--color="]);
|
||||
/// assert!(res.is_err());
|
||||
|
@ -123,7 +123,7 @@ pub enum ErrorKind {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{Command, Arg, ErrorKind};
|
||||
/// # use clap::{Command, Arg, ErrorKind, value_parser};
|
||||
/// fn is_numeric(val: &str) -> Result<(), String> {
|
||||
/// match val.parse::<i64>() {
|
||||
/// Ok(..) => Ok(()),
|
||||
|
@ -133,7 +133,7 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// let result = Command::new("prog")
|
||||
/// .arg(Arg::new("num")
|
||||
/// .validator(is_numeric))
|
||||
/// .value_parser(value_parser!(u8)))
|
||||
/// .try_get_matches_from(vec!["prog", "NotANumber"]);
|
||||
/// assert!(result.is_err());
|
||||
/// assert_eq!(result.unwrap_err().kind(), ErrorKind::ValueValidation);
|
||||
|
@ -175,24 +175,6 @@ pub enum ErrorKind {
|
|||
/// [`Arg::min_values`]: crate::Arg::min_values()
|
||||
TooFewValues,
|
||||
|
||||
/// Occurs when a user provides more occurrences for an argument than were defined by setting
|
||||
/// [`Arg::max_occurrences`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{Command, Arg, ErrorKind};
|
||||
/// let result = Command::new("prog")
|
||||
/// .arg(Arg::new("verbosity")
|
||||
/// .short('v')
|
||||
/// .max_occurrences(2))
|
||||
/// .try_get_matches_from(vec!["prog", "-vvv"]);
|
||||
/// assert!(result.is_err());
|
||||
/// assert_eq!(result.unwrap_err().kind(), ErrorKind::TooManyOccurrences);
|
||||
/// ```
|
||||
/// [`Arg::max_occurrences`]: crate::Arg::max_occurrences()
|
||||
TooManyOccurrences,
|
||||
|
||||
/// Occurs when the user provides a different number of values for an argument than what's
|
||||
/// been defined by setting [`Arg::number_of_values`] or than was implicitly set by
|
||||
/// [`Arg::value_names`].
|
||||
|
@ -289,7 +271,7 @@ pub enum ErrorKind {
|
|||
/// Occurs when the user provides a value containing invalid UTF-8.
|
||||
///
|
||||
/// To allow arbitrary data
|
||||
/// - Set [`Arg::allow_invalid_utf8`] for argument values
|
||||
/// - Set [`Arg::value_parser(value_parser!(OsString))`] for argument values
|
||||
/// - Set [`Command::allow_invalid_utf8_for_external_subcommands`] for external-subcommand
|
||||
/// values
|
||||
///
|
||||
|
@ -374,13 +356,6 @@ pub enum ErrorKind {
|
|||
/// ```
|
||||
DisplayVersion,
|
||||
|
||||
/// Occurs when using the [`ArgMatches::value_of_t`] and friends to convert an argument value
|
||||
/// into type `T`, but the argument you requested wasn't used. I.e. you asked for an argument
|
||||
/// with name `config` to be converted, but `config` wasn't used by the user.
|
||||
///
|
||||
/// [`ArgMatches::value_of_t`]: crate::ArgMatches::value_of_t()
|
||||
ArgumentNotFound,
|
||||
|
||||
/// Represents an [I/O error].
|
||||
/// Can occur when writing to `stderr` or `stdout` or reading a configuration file.
|
||||
///
|
||||
|
@ -410,7 +385,6 @@ impl ErrorKind {
|
|||
Self::ValueValidation => Some("Invalid value for one of the arguments"),
|
||||
Self::TooManyValues => Some("An argument received an unexpected value"),
|
||||
Self::TooFewValues => Some("An argument requires more values"),
|
||||
Self::TooManyOccurrences => Some("An argument occurred too many times"),
|
||||
Self::WrongNumberOfValues => Some("An argument received too many or too few values"),
|
||||
Self::ArgumentConflict => {
|
||||
Some("An argument cannot be used with one or more of the other specified arguments")
|
||||
|
@ -426,7 +400,6 @@ impl ErrorKind {
|
|||
Self::DisplayHelp => None,
|
||||
Self::DisplayHelpOnMissingArgumentOrSubcommand => None,
|
||||
Self::DisplayVersion => None,
|
||||
Self::ArgumentNotFound => Some("An argument wasn't found"),
|
||||
Self::Io => None,
|
||||
Self::Format => None,
|
||||
}
|
||||
|
|
164
src/error/mod.rs
164
src/error/mod.rs
|
@ -1,5 +1,4 @@
|
|||
//! Error reporting
|
||||
#![allow(deprecated)]
|
||||
|
||||
// Std
|
||||
use std::{
|
||||
|
@ -7,7 +6,7 @@ use std::{
|
|||
convert::From,
|
||||
error,
|
||||
fmt::{self, Debug, Display, Formatter},
|
||||
io::{self, BufRead},
|
||||
io::{self},
|
||||
result::Result as StdResult,
|
||||
};
|
||||
|
||||
|
@ -16,7 +15,6 @@ use crate::output::fmt::Colorizer;
|
|||
use crate::output::fmt::Stream;
|
||||
use crate::parser::features::suggestions;
|
||||
use crate::util::{color::ColorChoice, safe_exit, SUCCESS_CODE, USAGE_CODE};
|
||||
use crate::AppSettings;
|
||||
use crate::Command;
|
||||
|
||||
mod context;
|
||||
|
@ -39,18 +37,6 @@ pub type Result<T, E = Error> = StdResult<T, E>;
|
|||
#[derive(Debug)]
|
||||
pub struct Error {
|
||||
inner: Box<ErrorInner>,
|
||||
/// Deprecated, replaced with [`Error::kind()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.1.0", note = "Replaced with `Error::kind()`")
|
||||
)]
|
||||
pub kind: ErrorKind,
|
||||
/// Deprecated, replaced with [`Error::context()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.1.0", note = "Replaced with `Error::context()`")
|
||||
)]
|
||||
pub info: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -61,7 +47,6 @@ struct ErrorInner {
|
|||
source: Option<Box<dyn error::Error + Send + Sync>>,
|
||||
help_flag: Option<&'static str>,
|
||||
color_when: ColorChoice,
|
||||
wait_on_exit: bool,
|
||||
backtrace: Option<Backtrace>,
|
||||
}
|
||||
|
||||
|
@ -121,13 +106,6 @@ impl Error {
|
|||
// Swallow broken pipe errors
|
||||
let _ = self.print();
|
||||
|
||||
if self.inner.wait_on_exit {
|
||||
wlnerr!("\nPress [ENTER] / [RETURN] to continue...");
|
||||
let mut s = String::new();
|
||||
let i = io::stdin();
|
||||
i.lock().read_line(&mut s).unwrap();
|
||||
}
|
||||
|
||||
safe_exit(USAGE_CODE);
|
||||
}
|
||||
|
||||
|
@ -156,18 +134,6 @@ impl Error {
|
|||
self.formatted().print()
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`Command::error`]
|
||||
///
|
||||
/// [`Command::error`]: crate::Command::error
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "Replaced with `Command::error`")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
pub fn with_description(description: String, kind: ErrorKind) -> Self {
|
||||
Error::raw(kind, description)
|
||||
}
|
||||
|
||||
fn new(kind: ErrorKind) -> Self {
|
||||
Self {
|
||||
inner: Box::new(ErrorInner {
|
||||
|
@ -177,25 +143,18 @@ impl Error {
|
|||
source: None,
|
||||
help_flag: None,
|
||||
color_when: ColorChoice::Never,
|
||||
wait_on_exit: false,
|
||||
backtrace: Backtrace::new(),
|
||||
}),
|
||||
kind,
|
||||
info: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn for_app(kind: ErrorKind, cmd: &Command, colorizer: Colorizer, info: Vec<String>) -> Self {
|
||||
Self::new(kind)
|
||||
.set_message(colorizer)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
fn for_app(kind: ErrorKind, cmd: &Command, colorizer: Colorizer) -> Self {
|
||||
Self::new(kind).set_message(colorizer).with_cmd(cmd)
|
||||
}
|
||||
|
||||
pub(crate) fn with_cmd(self, cmd: &Command) -> Self {
|
||||
self.set_wait_on_exit(cmd.is_set(AppSettings::WaitOnError))
|
||||
.set_color(cmd.get_color())
|
||||
self.set_color(cmd.get_color())
|
||||
.set_help_flag(get_help_flag(cmd))
|
||||
}
|
||||
|
||||
|
@ -204,11 +163,6 @@ impl Error {
|
|||
self
|
||||
}
|
||||
|
||||
pub(crate) fn set_info(mut self, info: Vec<String>) -> Self {
|
||||
self.info = info;
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn set_source(mut self, source: Box<dyn error::Error + Send + Sync>) -> Self {
|
||||
self.inner.source = Some(source);
|
||||
self
|
||||
|
@ -224,11 +178,6 @@ impl Error {
|
|||
self
|
||||
}
|
||||
|
||||
pub(crate) fn set_wait_on_exit(mut self, yes: bool) -> Self {
|
||||
self.inner.wait_on_exit = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Does not verify if `ContextKind` is already present
|
||||
#[inline(never)]
|
||||
pub(crate) fn insert_context_unchecked(
|
||||
|
@ -259,7 +208,7 @@ impl Error {
|
|||
}
|
||||
|
||||
pub(crate) fn display_help(cmd: &Command, colorizer: Colorizer) -> Self {
|
||||
Self::for_app(ErrorKind::DisplayHelp, cmd, colorizer, vec![])
|
||||
Self::for_app(ErrorKind::DisplayHelp, cmd, colorizer)
|
||||
}
|
||||
|
||||
pub(crate) fn display_help_error(cmd: &Command, colorizer: Colorizer) -> Self {
|
||||
|
@ -267,12 +216,11 @@ impl Error {
|
|||
ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand,
|
||||
cmd,
|
||||
colorizer,
|
||||
vec![],
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn display_version(cmd: &Command, colorizer: Colorizer) -> Self {
|
||||
Self::for_app(ErrorKind::DisplayVersion, cmd, colorizer, vec![])
|
||||
Self::for_app(ErrorKind::DisplayVersion, cmd, colorizer)
|
||||
}
|
||||
|
||||
pub(crate) fn argument_conflict(
|
||||
|
@ -281,7 +229,6 @@ impl Error {
|
|||
mut others: Vec<String>,
|
||||
usage: String,
|
||||
) -> Self {
|
||||
let info = others.clone();
|
||||
let others = match others.len() {
|
||||
0 => ContextValue::None,
|
||||
1 => ContextValue::String(others.pop().unwrap()),
|
||||
|
@ -289,7 +236,6 @@ impl Error {
|
|||
};
|
||||
Self::new(ErrorKind::ArgumentConflict)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidArg, ContextValue::String(arg)),
|
||||
(ContextKind::PriorArg, others),
|
||||
|
@ -298,10 +244,8 @@ impl Error {
|
|||
}
|
||||
|
||||
pub(crate) fn empty_value(cmd: &Command, good_vals: &[&str], arg: String) -> Self {
|
||||
let info = vec![arg.clone()];
|
||||
let mut err = Self::new(ErrorKind::EmptyValue)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([(ContextKind::InvalidArg, ContextValue::String(arg))]);
|
||||
if !good_vals.is_empty() {
|
||||
err = err.insert_context_unchecked(
|
||||
|
@ -313,10 +257,8 @@ impl Error {
|
|||
}
|
||||
|
||||
pub(crate) fn no_equals(cmd: &Command, arg: String, usage: String) -> Self {
|
||||
let info = vec![arg.clone()];
|
||||
Self::new(ErrorKind::NoEquals)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidArg, ContextValue::String(arg)),
|
||||
(ContextKind::Usage, ContextValue::String(usage)),
|
||||
|
@ -329,13 +271,9 @@ impl Error {
|
|||
good_vals: &[&str],
|
||||
arg: String,
|
||||
) -> Self {
|
||||
let mut info = vec![arg.clone(), bad_val.clone()];
|
||||
info.extend(good_vals.iter().map(|s| (*s).to_owned()));
|
||||
|
||||
let suggestion = suggestions::did_you_mean(&bad_val, good_vals.iter()).pop();
|
||||
let mut err = Self::new(ErrorKind::InvalidValue)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidArg, ContextValue::String(arg)),
|
||||
(ContextKind::InvalidValue, ContextValue::String(bad_val)),
|
||||
|
@ -360,11 +298,9 @@ impl Error {
|
|||
name: String,
|
||||
usage: String,
|
||||
) -> Self {
|
||||
let info = vec![subcmd.clone()];
|
||||
let suggestion = format!("{} -- {}", name, subcmd);
|
||||
Self::new(ErrorKind::InvalidSubcommand)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidSubcommand, ContextValue::String(subcmd)),
|
||||
(
|
||||
|
@ -380,10 +316,8 @@ impl Error {
|
|||
}
|
||||
|
||||
pub(crate) fn unrecognized_subcommand(cmd: &Command, subcmd: String, usage: String) -> Self {
|
||||
let info = vec![subcmd.clone()];
|
||||
Self::new(ErrorKind::UnrecognizedSubcommand)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidSubcommand, ContextValue::String(subcmd)),
|
||||
(ContextKind::Usage, ContextValue::String(usage)),
|
||||
|
@ -395,10 +329,8 @@ impl Error {
|
|||
required: Vec<String>,
|
||||
usage: String,
|
||||
) -> Self {
|
||||
let info = required.clone();
|
||||
Self::new(ErrorKind::MissingRequiredArgument)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidArg, ContextValue::Strings(required)),
|
||||
(ContextKind::Usage, ContextValue::String(usage)),
|
||||
|
@ -406,10 +338,8 @@ impl Error {
|
|||
}
|
||||
|
||||
pub(crate) fn missing_subcommand(cmd: &Command, name: String, usage: String) -> Self {
|
||||
let info = vec![];
|
||||
Self::new(ErrorKind::MissingSubcommand)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidSubcommand, ContextValue::String(name)),
|
||||
(ContextKind::Usage, ContextValue::String(usage)),
|
||||
|
@ -417,43 +347,14 @@ impl Error {
|
|||
}
|
||||
|
||||
pub(crate) fn invalid_utf8(cmd: &Command, usage: String) -> Self {
|
||||
let info = vec![];
|
||||
Self::new(ErrorKind::InvalidUtf8)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([(ContextKind::Usage, ContextValue::String(usage))])
|
||||
}
|
||||
|
||||
pub(crate) fn too_many_occurrences(
|
||||
cmd: &Command,
|
||||
arg: String,
|
||||
max_occurs: usize,
|
||||
curr_occurs: usize,
|
||||
usage: String,
|
||||
) -> Self {
|
||||
let info = vec![arg.clone(), curr_occurs.to_string(), max_occurs.to_string()];
|
||||
Self::new(ErrorKind::TooManyOccurrences)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidArg, ContextValue::String(arg)),
|
||||
(
|
||||
ContextKind::MaxOccurrences,
|
||||
ContextValue::Number(max_occurs as isize),
|
||||
),
|
||||
(
|
||||
ContextKind::ActualNumValues,
|
||||
ContextValue::Number(curr_occurs as isize),
|
||||
),
|
||||
(ContextKind::Usage, ContextValue::String(usage)),
|
||||
])
|
||||
}
|
||||
|
||||
pub(crate) fn too_many_values(cmd: &Command, val: String, arg: String, usage: String) -> Self {
|
||||
let info = vec![arg.clone(), val.clone()];
|
||||
Self::new(ErrorKind::TooManyValues)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidArg, ContextValue::String(arg)),
|
||||
(ContextKind::InvalidValue, ContextValue::String(val)),
|
||||
|
@ -468,10 +369,8 @@ impl Error {
|
|||
curr_vals: usize,
|
||||
usage: String,
|
||||
) -> Self {
|
||||
let info = vec![arg.clone(), curr_vals.to_string(), min_vals.to_string()];
|
||||
Self::new(ErrorKind::TooFewValues)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidArg, ContextValue::String(arg)),
|
||||
(
|
||||
|
@ -491,9 +390,7 @@ impl Error {
|
|||
val: String,
|
||||
err: Box<dyn error::Error + Send + Sync>,
|
||||
) -> Self {
|
||||
let info = vec![arg.clone(), val.to_string(), err.to_string()];
|
||||
Self::new(ErrorKind::ValueValidation)
|
||||
.set_info(info)
|
||||
.set_source(err)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidArg, ContextValue::String(arg)),
|
||||
|
@ -508,10 +405,8 @@ impl Error {
|
|||
curr_vals: usize,
|
||||
usage: String,
|
||||
) -> Self {
|
||||
let info = vec![arg.clone(), curr_vals.to_string(), num_vals.to_string()];
|
||||
Self::new(ErrorKind::WrongNumberOfValues)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidArg, ContextValue::String(arg)),
|
||||
(
|
||||
|
@ -527,10 +422,8 @@ impl Error {
|
|||
}
|
||||
|
||||
pub(crate) fn unexpected_multiple_usage(cmd: &Command, arg: String, usage: String) -> Self {
|
||||
let info = vec![arg.clone()];
|
||||
Self::new(ErrorKind::UnexpectedMultipleUsage)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidArg, ContextValue::String(arg)),
|
||||
(ContextKind::Usage, ContextValue::String(usage)),
|
||||
|
@ -543,10 +436,8 @@ impl Error {
|
|||
did_you_mean: Option<(String, Option<String>)>,
|
||||
usage: String,
|
||||
) -> Self {
|
||||
let info = vec![arg.clone()];
|
||||
let mut err = Self::new(ErrorKind::UnknownArgument)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidArg, ContextValue::String(arg)),
|
||||
(ContextKind::Usage, ContextValue::String(usage)),
|
||||
|
@ -567,10 +458,8 @@ impl Error {
|
|||
}
|
||||
|
||||
pub(crate) fn unnecessary_double_dash(cmd: &Command, arg: String, usage: String) -> Self {
|
||||
let info = vec![arg.clone()];
|
||||
Self::new(ErrorKind::UnknownArgument)
|
||||
.with_cmd(cmd)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([
|
||||
(ContextKind::InvalidArg, ContextValue::String(arg)),
|
||||
(ContextKind::TrailingArg, ContextValue::Bool(true)),
|
||||
|
@ -578,13 +467,6 @@ impl Error {
|
|||
])
|
||||
}
|
||||
|
||||
pub(crate) fn argument_not_found_auto(arg: String) -> Self {
|
||||
let info = vec![arg.clone()];
|
||||
Self::new(ErrorKind::ArgumentNotFound)
|
||||
.set_info(info)
|
||||
.extend_context_unchecked([(ContextKind::InvalidArg, ContextValue::String(arg))])
|
||||
}
|
||||
|
||||
fn formatted(&self) -> Cow<'_, Colorizer> {
|
||||
if let Some(message) = self.inner.message.as_ref() {
|
||||
message.formatted()
|
||||
|
@ -784,29 +666,6 @@ impl Error {
|
|||
}
|
||||
}
|
||||
ErrorKind::InvalidUtf8 => false,
|
||||
ErrorKind::TooManyOccurrences => {
|
||||
let invalid_arg = self.get_context(ContextKind::InvalidArg);
|
||||
let actual_num_occurs = self.get_context(ContextKind::ActualNumOccurrences);
|
||||
let max_occurs = self.get_context(ContextKind::MaxOccurrences);
|
||||
if let (
|
||||
Some(ContextValue::String(invalid_arg)),
|
||||
Some(ContextValue::Number(actual_num_occurs)),
|
||||
Some(ContextValue::Number(max_occurs)),
|
||||
) = (invalid_arg, actual_num_occurs, max_occurs)
|
||||
{
|
||||
let were_provided = Error::singular_or_plural(*actual_num_occurs as usize);
|
||||
c.none("The argument '");
|
||||
c.warning(invalid_arg);
|
||||
c.none("' allows at most ");
|
||||
c.warning(max_occurs.to_string());
|
||||
c.none(" occurrences but ");
|
||||
c.warning(actual_num_occurs.to_string());
|
||||
c.none(were_provided);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
ErrorKind::TooManyValues => {
|
||||
let invalid_arg = self.get_context(ContextKind::InvalidArg);
|
||||
let invalid_value = self.get_context(ContextKind::InvalidValue);
|
||||
|
@ -956,17 +815,6 @@ impl Error {
|
|||
false
|
||||
}
|
||||
}
|
||||
ErrorKind::ArgumentNotFound => {
|
||||
let invalid_arg = self.get_context(ContextKind::InvalidArg);
|
||||
if let Some(ContextValue::String(invalid_arg)) = invalid_arg {
|
||||
c.none("The argument '");
|
||||
c.warning(invalid_arg.to_string());
|
||||
c.none("' wasn't found");
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
ErrorKind::DisplayHelp
|
||||
| ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand
|
||||
| ErrorKind::DisplayVersion
|
||||
|
|
81
src/lib.rs
81
src/lib.rs
|
@ -109,48 +109,15 @@ pub(crate) use crate::util::color::ColorChoice;
|
|||
pub use crate::derive::{Args, CommandFactory, FromArgMatches, Parser, Subcommand, ValueEnum};
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub use crate::builder::App;
|
||||
pub use crate::builder::{AppFlags, AppSettings, ArgFlags, ArgSettings, PossibleValue, ValueHint};
|
||||
pub use crate::builder::{AppFlags, AppSettings, PossibleValue, ValueHint};
|
||||
pub use crate::error::{ErrorKind, Result};
|
||||
#[allow(deprecated)]
|
||||
pub use crate::parser::{Indices, OsValues, ValueSource, Values};
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
#[doc(hidden)]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
pub use yaml_rust::YamlLoader;
|
||||
pub use crate::parser::{Indices, ValueSource};
|
||||
|
||||
#[cfg(feature = "derive")]
|
||||
#[doc(hidden)]
|
||||
pub use clap_derive::{self, *};
|
||||
|
||||
/// Deprecated, replaced with [`CommandFactory`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "Replaced with `CommandFactory`")
|
||||
)]
|
||||
pub use CommandFactory as IntoApp;
|
||||
/// Deprecated, replaced with [`Parser`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "Replaced with `Parser`")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
pub use Parser as StructOpt;
|
||||
/// Deprecated, replaced with [`ValueEnum`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.2.0", note = "Replaced with `ValueEnum`")
|
||||
)]
|
||||
pub use ValueEnum as ArgEnum;
|
||||
|
||||
#[cfg(feature = "unstable-doc")]
|
||||
pub mod _cookbook;
|
||||
#[cfg(feature = "unstable-doc")]
|
||||
|
@ -175,9 +142,6 @@ mod macros;
|
|||
|
||||
mod derive;
|
||||
|
||||
#[cfg(feature = "regex")]
|
||||
pub use crate::builder::RegexRef;
|
||||
|
||||
pub mod builder;
|
||||
pub mod error;
|
||||
pub mod parser;
|
||||
|
@ -189,44 +153,3 @@ mod util;
|
|||
const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a bug \
|
||||
report at https://github.com/clap-rs/clap/issues";
|
||||
const INVALID_UTF8: &str = "unexpected invalid UTF-8 code point";
|
||||
|
||||
/// Deprecated, replaced with [`Command::new`], unless you were looking for [Subcommand]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Replaced with `Command::new` unless you intended the `Subcommand` trait"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct SubCommand {}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl SubCommand {
|
||||
/// Deprecated, replaced with [`Command::new`].
|
||||
/// Did you mean Subcommand (lower-case c)?
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "Replaced with `Command::new`")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
pub fn with_name<'help>(name: &str) -> App<'help> {
|
||||
Command::new(name)
|
||||
}
|
||||
|
||||
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
|
||||
#[cfg(feature = "yaml")]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
pub fn from_yaml(yaml: &yaml_rust::Yaml) -> App {
|
||||
#![allow(deprecated)]
|
||||
Command::from_yaml(yaml)
|
||||
}
|
||||
}
|
||||
|
|
416
src/macros.rs
416
src/macros.rs
|
@ -1,207 +1,3 @@
|
|||
/// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
|
||||
#[cfg(feature = "yaml")]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! load_yaml {
|
||||
($yaml:expr) => {
|
||||
&$crate::YamlLoader::load_from_str(include_str!($yaml)).expect("failed to load YAML file")
|
||||
[0]
|
||||
};
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::value_of_t`][crate::ArgMatches::value_of_t]
|
||||
#[macro_export]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_one`")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
macro_rules! value_t {
|
||||
($m:ident, $v:expr, $t:ty) => {
|
||||
$crate::value_t!($m.value_of($v), $t)
|
||||
};
|
||||
($m:ident.value_of($v:expr), $t:ty) => {
|
||||
$m.value_of_t::<$t>($v)
|
||||
};
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::value_of_t_or_exit`][crate::ArgMatches::value_of_t_or_exit]
|
||||
#[macro_export]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_one`")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
macro_rules! value_t_or_exit {
|
||||
($m:ident, $v:expr, $t:ty) => {
|
||||
value_t_or_exit!($m.value_of($v), $t)
|
||||
};
|
||||
($m:ident.value_of($v:expr), $t:ty) => {
|
||||
$m.value_of_t_or_exit::<$t>($v)
|
||||
};
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::values_of_t`][crate::ArgMatches::value_of_t]
|
||||
#[macro_export]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_many`")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
macro_rules! values_t {
|
||||
($m:ident, $v:expr, $t:ty) => {
|
||||
values_t!($m.values_of($v), $t)
|
||||
};
|
||||
($m:ident.values_of($v:expr), $t:ty) => {
|
||||
$m.values_of_t::<$t>($v)
|
||||
};
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::values_of_t_or_exit`][crate::ArgMatches::value_of_t_or_exit]
|
||||
#[macro_export]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::get_many`")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
macro_rules! values_t_or_exit {
|
||||
($m:ident, $v:expr, $t:ty) => {
|
||||
values_t_or_exit!($m.values_of($v), $t)
|
||||
};
|
||||
($m:ident.values_of($v:expr), $t:ty) => {
|
||||
$m.values_of_t_or_exit::<$t>($v)
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "Replaced with `ValueEnum`")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! _clap_count_exprs {
|
||||
() => { 0 };
|
||||
($e:expr) => { 1 };
|
||||
($e:expr, $($es:expr),+) => { 1 + $crate::_clap_count_exprs!($($es),*) };
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgEnum`][crate::ArgEnum]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.0.0", note = "Replaced with `ValueEnum`")
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! arg_enum {
|
||||
(@as_item $($i:item)*) => ($($i)*);
|
||||
(@impls ( $($tts:tt)* ) -> ($e:ident, $($v:ident),+)) => {
|
||||
$crate::arg_enum!(@as_item
|
||||
$($tts)*
|
||||
|
||||
impl ::std::str::FromStr for $e {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> ::std::result::Result<Self,Self::Err> {
|
||||
#[allow(deprecated, unused_imports)]
|
||||
use ::std::ascii::AsciiExt;
|
||||
match s {
|
||||
$(stringify!($v) |
|
||||
_ if s.eq_ignore_ascii_case(stringify!($v)) => Ok($e::$v)),+,
|
||||
_ => Err({
|
||||
let v = vec![
|
||||
$(stringify!($v),)+
|
||||
];
|
||||
format!("valid values: {}",
|
||||
v.join(", "))
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl ::std::fmt::Display for $e {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
match *self {
|
||||
$($e::$v => write!(f, stringify!($v)),)+
|
||||
}
|
||||
}
|
||||
}
|
||||
impl $e {
|
||||
#[allow(dead_code)]
|
||||
pub fn variants() -> [&'static str; $crate::_clap_count_exprs!($(stringify!($v)),+)] {
|
||||
[
|
||||
$(stringify!($v),)+
|
||||
]
|
||||
}
|
||||
});
|
||||
};
|
||||
($(#[$($m:meta),+])+ pub enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
|
||||
$crate::arg_enum!(@impls
|
||||
($(#[$($m),+])+
|
||||
pub enum $e {
|
||||
$($v$(=$val)*),+
|
||||
}) -> ($e, $($v),+)
|
||||
);
|
||||
};
|
||||
($(#[$($m:meta),+])+ pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
|
||||
$crate::arg_enum!(@impls
|
||||
($(#[$($m),+])+
|
||||
pub enum $e {
|
||||
$($v$(=$val)*),+
|
||||
}) -> ($e, $($v),+)
|
||||
);
|
||||
};
|
||||
($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
|
||||
$crate::arg_enum!(@impls
|
||||
($(#[$($m),+])+
|
||||
enum $e {
|
||||
$($v$(=$val)*),+
|
||||
}) -> ($e, $($v),+)
|
||||
);
|
||||
};
|
||||
($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
|
||||
$crate::arg_enum!(@impls
|
||||
($(#[$($m),+])+
|
||||
enum $e {
|
||||
$($v$(=$val)*),+
|
||||
}) -> ($e, $($v),+)
|
||||
);
|
||||
};
|
||||
(pub enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
|
||||
$crate::arg_enum!(@impls
|
||||
(pub enum $e {
|
||||
$($v$(=$val)*),+
|
||||
}) -> ($e, $($v),+)
|
||||
);
|
||||
};
|
||||
(pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
|
||||
$crate::arg_enum!(@impls
|
||||
(pub enum $e {
|
||||
$($v$(=$val)*),+
|
||||
}) -> ($e, $($v),+)
|
||||
);
|
||||
};
|
||||
(enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => {
|
||||
$crate::arg_enum!(@impls
|
||||
(enum $e {
|
||||
$($v$(=$val)*),+
|
||||
}) -> ($e, $($v),+)
|
||||
);
|
||||
};
|
||||
(enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => {
|
||||
$crate::arg_enum!(@impls
|
||||
(enum $e {
|
||||
$($v$(=$val)*),+
|
||||
}) -> ($e, $($v),+)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
/// Allows you to pull the version from your Cargo.toml at compile time as
|
||||
/// `MAJOR.MINOR.PATCH_PKGVERSION_PRE`
|
||||
///
|
||||
|
@ -359,46 +155,6 @@ macro_rules! command {
|
|||
}};
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`clap::command!`][crate::command]
|
||||
#[cfg(feature = "cargo")]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.1.0", note = "Replaced with `clap::command!")
|
||||
)]
|
||||
#[macro_export]
|
||||
macro_rules! app_from_crate {
|
||||
() => {{
|
||||
let mut cmd = $crate::Command::new($crate::crate_name!()).version($crate::crate_version!());
|
||||
|
||||
let author = $crate::crate_authors!(", ");
|
||||
if !author.is_empty() {
|
||||
cmd = cmd.author(author)
|
||||
}
|
||||
|
||||
let about = $crate::crate_description!();
|
||||
if !about.is_empty() {
|
||||
cmd = cmd.about(about)
|
||||
}
|
||||
|
||||
cmd
|
||||
}};
|
||||
($sep:expr) => {{
|
||||
let mut cmd = $crate::Command::new($crate::crate_name!()).version($crate::crate_version!());
|
||||
|
||||
let author = $crate::crate_authors!($sep);
|
||||
if !author.is_empty() {
|
||||
cmd = cmd.author(author)
|
||||
}
|
||||
|
||||
let about = $crate::crate_description!();
|
||||
if !about.is_empty() {
|
||||
cmd = cmd.about(about)
|
||||
}
|
||||
|
||||
cmd
|
||||
}};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! arg_impl {
|
||||
|
@ -706,7 +462,7 @@ macro_rules! arg_impl {
|
|||
/// 2. Long
|
||||
/// 3. Value Name
|
||||
///
|
||||
/// See [`Arg::name`][crate::Arg::name].
|
||||
/// See [`Arg::id`][crate::Arg::id].
|
||||
///
|
||||
/// ### Short
|
||||
///
|
||||
|
@ -773,168 +529,6 @@ macro_rules! arg {
|
|||
}};
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`clap::Parser`][crate::Parser] and [`clap::arg!`][crate::arg] (Issue clap-rs/clap#2835)
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(
|
||||
since = "3.0.0",
|
||||
note = "Replaced with `clap::Parser` for a declarative API (Issue clap-rs/clap#2835)"
|
||||
)
|
||||
)]
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! clap_app {
|
||||
(@app ($builder:expr)) => { $builder };
|
||||
(@app ($builder:expr) (@arg ($name:expr): $($tail:tt)*) $($tt:tt)*) => {
|
||||
$crate::clap_app!{ @app
|
||||
($builder.arg(
|
||||
$crate::clap_app!{ @arg ($crate::Arg::new($name)) (-) $($tail)* }))
|
||||
$($tt)*
|
||||
}
|
||||
};
|
||||
(@app ($builder:expr) (@arg $name:ident: $($tail:tt)*) $($tt:tt)*) => {
|
||||
$crate::clap_app!{ @app
|
||||
($builder.arg(
|
||||
$crate::clap_app!{ @arg ($crate::Arg::new(stringify!($name))) (-) $($tail)* }))
|
||||
$($tt)*
|
||||
}
|
||||
};
|
||||
(@app ($builder:expr) (@setting $setting:ident) $($tt:tt)*) => {
|
||||
$crate::clap_app!{ @app
|
||||
($builder.setting($crate::AppSettings::$setting))
|
||||
$($tt)*
|
||||
}
|
||||
};
|
||||
// Treat the application builder as an argument to set its attributes
|
||||
(@app ($builder:expr) (@attributes $($attr:tt)*) $($tt:tt)*) => {
|
||||
$crate::clap_app!{ @app ($crate::clap_app!{ @arg ($builder) $($attr)* }) $($tt)* }
|
||||
};
|
||||
(@app ($builder:expr) (@group $name:ident => $($tail:tt)*) $($tt:tt)*) => {
|
||||
$crate::clap_app!{ @app
|
||||
($crate::clap_app!{ @group ($builder, $crate::ArgGroup::new(stringify!($name))) $($tail)* })
|
||||
$($tt)*
|
||||
}
|
||||
};
|
||||
(@app ($builder:expr) (@group $name:ident !$ident:ident => $($tail:tt)*) $($tt:tt)*) => {
|
||||
$crate::clap_app!{ @app
|
||||
($crate::clap_app!{ @group ($builder, $crate::ArgGroup::new(stringify!($name)).$ident(false)) $($tail)* })
|
||||
$($tt)*
|
||||
}
|
||||
};
|
||||
(@app ($builder:expr) (@group $name:ident +$ident:ident => $($tail:tt)*) $($tt:tt)*) => {
|
||||
$crate::clap_app!{ @app
|
||||
($crate::clap_app!{ @group ($builder, $crate::ArgGroup::new(stringify!($name)).$ident(true)) $($tail)* })
|
||||
$($tt)*
|
||||
}
|
||||
};
|
||||
// Handle subcommand creation
|
||||
(@app ($builder:expr) (@subcommand $name:ident => $($tail:tt)*) $($tt:tt)*) => {
|
||||
$crate::clap_app!{ @app
|
||||
($builder.subcommand(
|
||||
$crate::clap_app!{ @app ($crate::Command::new(stringify!($name))) $($tail)* }
|
||||
))
|
||||
$($tt)*
|
||||
}
|
||||
};
|
||||
// Yaml like function calls - used for setting various meta directly against the app
|
||||
(@app ($builder:expr) ($ident:ident: $($v:expr),*) $($tt:tt)*) => {
|
||||
// $crate::clap_app!{ @app ($builder.$ident($($v),*)) $($tt)* }
|
||||
$crate::clap_app!{ @app
|
||||
($builder.$ident($($v),*))
|
||||
$($tt)*
|
||||
}
|
||||
};
|
||||
|
||||
// Add members to group and continue argument handling with the parent builder
|
||||
(@group ($builder:expr, $group:expr)) => { $builder.group($group) };
|
||||
// Treat the group builder as an argument to set its attributes
|
||||
(@group ($builder:expr, $group:expr) (@attributes $($attr:tt)*) $($tt:tt)*) => {
|
||||
$crate::clap_app!{ @group ($builder, $crate::clap_app!{ @arg ($group) (-) $($attr)* }) $($tt)* }
|
||||
};
|
||||
(@group ($builder:expr, $group:expr) (@arg $name:ident: $($tail:tt)*) $($tt:tt)*) => {
|
||||
$crate::clap_app!{ @group
|
||||
($crate::clap_app!{ @app ($builder) (@arg $name: $($tail)*) },
|
||||
$group.arg(stringify!($name)))
|
||||
$($tt)*
|
||||
}
|
||||
};
|
||||
|
||||
// No more tokens to munch
|
||||
(@arg ($arg:expr) $modes:tt) => { $arg };
|
||||
// Shorthand tokens influenced by the usage_string
|
||||
(@arg ($arg:expr) $modes:tt --($long:expr) $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg.long($long)) $modes $($tail)* }
|
||||
};
|
||||
(@arg ($arg:expr) $modes:tt --$long:ident $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg.long(stringify!($long))) $modes $($tail)* }
|
||||
};
|
||||
(@arg ($arg:expr) $modes:tt -$short:ident $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg.short(stringify!($short).chars().next().unwrap())) $modes $($tail)* }
|
||||
};
|
||||
(@arg ($arg:expr) (-) <$var:ident> $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) +takes_value +required $($tail)* }
|
||||
};
|
||||
(@arg ($arg:expr) (+) <$var:ident> $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) $($tail)* }
|
||||
};
|
||||
(@arg ($arg:expr) (-) [$var:ident] $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) +takes_value $($tail)* }
|
||||
};
|
||||
(@arg ($arg:expr) (+) [$var:ident] $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) $($tail)* }
|
||||
};
|
||||
(@arg ($arg:expr) $modes:tt ... $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg) $modes +multiple +takes_value $($tail)* }
|
||||
};
|
||||
// Shorthand magic
|
||||
(@arg ($arg:expr) $modes:tt #{$n:expr, $m:expr} $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg) $modes min_values($n) max_values($m) $($tail)* }
|
||||
};
|
||||
(@arg ($arg:expr) $modes:tt * $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg) $modes +required $($tail)* }
|
||||
};
|
||||
// !foo -> .foo(false)
|
||||
(@arg ($arg:expr) $modes:tt !$ident:ident $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg.$ident(false)) $modes $($tail)* }
|
||||
};
|
||||
// +foo -> .foo(true)
|
||||
(@arg ($arg:expr) $modes:tt +$ident:ident $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg.$ident(true)) $modes $($tail)* }
|
||||
};
|
||||
// Validator
|
||||
(@arg ($arg:expr) $modes:tt {$fn_:expr} $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg.validator($fn_)) $modes $($tail)* }
|
||||
};
|
||||
(@as_expr $expr:expr) => { $expr };
|
||||
// Help
|
||||
(@arg ($arg:expr) $modes:tt $desc:tt) => { $arg.help($crate::clap_app!{ @as_expr $desc }) };
|
||||
// Handle functions that need to be called multiple times for each argument
|
||||
(@arg ($arg:expr) $modes:tt $ident:ident[$($target:ident)*] $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg $( .$ident(stringify!($target)) )*) $modes $($tail)* }
|
||||
};
|
||||
// Inherit builder's functions, e.g. `index(2)`, `requires_if("val", "arg")`
|
||||
(@arg ($arg:expr) $modes:tt $ident:ident($($expr:expr),*) $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg.$ident($($expr),*)) $modes $($tail)* }
|
||||
};
|
||||
// Inherit builder's functions with trailing comma, e.g. `index(2,)`, `requires_if("val", "arg",)`
|
||||
(@arg ($arg:expr) $modes:tt $ident:ident($($expr:expr,)*) $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @arg ($arg.$ident($($expr),*)) $modes $($tail)* }
|
||||
};
|
||||
|
||||
// Build a subcommand outside of an app.
|
||||
(@subcommand $name:ident => $($tail:tt)*) => {
|
||||
$crate::clap_app!{ @app ($crate::Command::new(stringify!($name))) $($tail)* }
|
||||
};
|
||||
// Start the magic
|
||||
(($name:expr) => $($tail:tt)*) => {{
|
||||
$crate::clap_app!{ @app ($crate::Command::new($name)) $($tail)*}
|
||||
}};
|
||||
|
||||
($name:ident => $($tail:tt)*) => {{
|
||||
$crate::clap_app!{ @app ($crate::Command::new(stringify!($name))) $($tail)*}
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! impl_settings {
|
||||
($settings:ident, $flags:ident,
|
||||
$(
|
||||
|
@ -1031,14 +625,6 @@ macro_rules! impl_settings {
|
|||
}
|
||||
}
|
||||
|
||||
// Convenience for writing to stderr thanks to https://github.com/BurntSushi
|
||||
macro_rules! wlnerr {
|
||||
($($arg:tt)*) => ({
|
||||
use std::io::{Write, stderr};
|
||||
writeln!(&mut stderr(), $($arg)*).ok();
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "debug")]
|
||||
macro_rules! debug {
|
||||
($($arg:tt)*) => ({
|
||||
|
|
|
@ -481,7 +481,7 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> {
|
|||
if let Some(arg) = arg {
|
||||
const DASH_SPACE: usize = "- ".len();
|
||||
const COLON_SPACE: usize = ": ".len();
|
||||
let possible_vals = arg.get_possible_values2();
|
||||
let possible_vals = arg.get_possible_values();
|
||||
if self.use_long
|
||||
&& !arg.is_hide_possible_values_set()
|
||||
&& possible_vals.iter().any(PossibleValue::should_show_help)
|
||||
|
@ -660,7 +660,7 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> {
|
|||
}
|
||||
}
|
||||
|
||||
let possible_vals = a.get_possible_values2();
|
||||
let possible_vals = a.get_possible_values();
|
||||
if !(a.is_hide_possible_values_set()
|
||||
|| possible_vals.is_empty()
|
||||
|| cfg!(feature = "unstable-v4")
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
// Std
|
||||
use std::any::Any;
|
||||
use std::borrow::Cow;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fmt::{Debug, Display};
|
||||
use std::fmt::Debug;
|
||||
use std::iter::{Cloned, Flatten, Map};
|
||||
use std::slice::Iter;
|
||||
use std::str::FromStr;
|
||||
|
||||
// Third Party
|
||||
use indexmap::IndexMap;
|
||||
|
@ -17,7 +15,6 @@ use crate::parser::MatchedArg;
|
|||
use crate::parser::MatchesError;
|
||||
use crate::parser::ValueSource;
|
||||
use crate::util::{Id, Key};
|
||||
use crate::Error;
|
||||
use crate::INTERNAL_ERROR_MSG;
|
||||
|
||||
/// Container for parse results.
|
||||
|
@ -341,62 +338,6 @@ impl ArgMatches {
|
|||
!self.args.is_empty()
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::get_one()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`")
|
||||
)]
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
pub fn value_of<T: Key>(&self, id: T) -> Option<&str> {
|
||||
let id = Id::from(id);
|
||||
let arg = self.get_arg(&id)?;
|
||||
let v = unwrap_string_arg(&id, arg.first()?);
|
||||
Some(v)
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::get_one()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`")
|
||||
)]
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
pub fn value_of_lossy<T: Key>(&self, id: T) -> Option<Cow<'_, str>> {
|
||||
let id = Id::from(id);
|
||||
let arg = self.get_arg(&id)?;
|
||||
let v = unwrap_os_string_arg(&id, arg.first()?);
|
||||
Some(v.to_string_lossy())
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::get_one()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`")
|
||||
)]
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
pub fn value_of_os<T: Key>(&self, id: T) -> Option<&OsStr> {
|
||||
let id = Id::from(id);
|
||||
let arg = self.get_arg(&id)?;
|
||||
let v = unwrap_os_string_arg(&id, arg.first()?);
|
||||
Some(v)
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::get_many()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`")
|
||||
)]
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
pub fn values_of<T: Key>(&self, id: T) -> Option<Values> {
|
||||
#![allow(deprecated)]
|
||||
let id = Id::from(id);
|
||||
let arg = self.get_arg(&id)?;
|
||||
let v = Values {
|
||||
iter: arg.vals_flatten().map(unwrap_string),
|
||||
len: arg.num_vals(),
|
||||
};
|
||||
Some(v)
|
||||
}
|
||||
|
||||
/// Get an [`Iterator`] over groups of values of a specific option.
|
||||
///
|
||||
/// specifically grouped by the occurrences of the options.
|
||||
|
@ -442,119 +383,6 @@ impl ArgMatches {
|
|||
Some(v)
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::get_many()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`")
|
||||
)]
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
pub fn values_of_lossy<T: Key>(&self, id: T) -> Option<Vec<String>> {
|
||||
let id = Id::from(id);
|
||||
let arg = self.get_arg(&id)?;
|
||||
let v = arg
|
||||
.vals_flatten()
|
||||
.map(|v| unwrap_os_string_arg(&id, v).to_string_lossy().into_owned())
|
||||
.collect();
|
||||
Some(v)
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::get_many()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`")
|
||||
)]
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
pub fn values_of_os<T: Key>(&self, id: T) -> Option<OsValues> {
|
||||
#![allow(deprecated)]
|
||||
let id = Id::from(id);
|
||||
let arg = self.get_arg(&id)?;
|
||||
let v = OsValues {
|
||||
iter: arg.vals_flatten().map(unwrap_os_string),
|
||||
len: arg.num_vals(),
|
||||
};
|
||||
Some(v)
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::get_one()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`")
|
||||
)]
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
pub fn value_of_t<R>(&self, name: &str) -> Result<R, Error>
|
||||
where
|
||||
R: FromStr,
|
||||
<R as FromStr>::Err: Display,
|
||||
{
|
||||
#![allow(deprecated)]
|
||||
let v = self
|
||||
.value_of(name)
|
||||
.ok_or_else(|| Error::argument_not_found_auto(name.to_string()))?;
|
||||
v.parse::<R>().map_err(|e| {
|
||||
let message = format!(
|
||||
"The argument '{}' isn't a valid value for '{}': {}",
|
||||
v, name, e
|
||||
);
|
||||
|
||||
Error::value_validation(name.to_string(), v.to_string(), message.into())
|
||||
})
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::get_one()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_one()`")
|
||||
)]
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
pub fn value_of_t_or_exit<R>(&self, name: &str) -> R
|
||||
where
|
||||
R: FromStr,
|
||||
<R as FromStr>::Err: Display,
|
||||
{
|
||||
#![allow(deprecated)]
|
||||
self.value_of_t(name).unwrap_or_else(|e| e.exit())
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::get_many()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`")
|
||||
)]
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
pub fn values_of_t<R>(&self, name: &str) -> Result<Vec<R>, Error>
|
||||
where
|
||||
R: FromStr,
|
||||
<R as FromStr>::Err: Display,
|
||||
{
|
||||
#![allow(deprecated)]
|
||||
let v = self
|
||||
.values_of(name)
|
||||
.ok_or_else(|| Error::argument_not_found_auto(name.to_string()))?;
|
||||
v.map(|v| {
|
||||
v.parse::<R>().map_err(|e| {
|
||||
let message = format!("The argument '{}' isn't a valid value: {}", v, e);
|
||||
|
||||
Error::value_validation(name.to_string(), v.to_string(), message.into())
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::get_many()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`")
|
||||
)]
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
pub fn values_of_t_or_exit<R>(&self, name: &str) -> Vec<R>
|
||||
where
|
||||
R: FromStr,
|
||||
<R as FromStr>::Err: Display,
|
||||
{
|
||||
#![allow(deprecated)]
|
||||
self.values_of_t(name).unwrap_or_else(|e| e.exit())
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgAction::SetTrue`][crate::ArgAction] or
|
||||
/// [`ArgMatches::contains_id`].
|
||||
#[cfg_attr(
|
||||
|
@ -1499,52 +1327,6 @@ impl Default for RawValues<'_> {
|
|||
// commit: be5e1fa3c26e351761b33010ddbdaf5f05dbcc33
|
||||
// license: MIT - Copyright (c) 2015 The Rust Project Developers
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::get_many()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`")
|
||||
)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Values<'a> {
|
||||
#[allow(clippy::type_complexity)]
|
||||
iter: Map<Flatten<Iter<'a, Vec<AnyValue>>>, for<'r> fn(&'r AnyValue) -> &'r str>,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'a> Iterator for Values<'a> {
|
||||
type Item = &'a str;
|
||||
|
||||
fn next(&mut self) -> Option<&'a str> {
|
||||
self.iter.next()
|
||||
}
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(self.len, Some(self.len))
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'a> DoubleEndedIterator for Values<'a> {
|
||||
fn next_back(&mut self) -> Option<&'a str> {
|
||||
self.iter.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'a> ExactSizeIterator for Values<'a> {}
|
||||
|
||||
/// Creates an empty iterator.
|
||||
#[allow(deprecated)]
|
||||
impl<'a> Default for Values<'a> {
|
||||
fn default() -> Self {
|
||||
static EMPTY: [Vec<AnyValue>; 0] = [];
|
||||
Values {
|
||||
iter: EMPTY[..].iter().flatten().map(|_| unreachable!()),
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct GroupedValues<'a> {
|
||||
|
@ -1584,52 +1366,6 @@ impl<'a> Default for GroupedValues<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Deprecated, replaced with [`ArgMatches::get_many()`]
|
||||
#[cfg_attr(
|
||||
feature = "deprecated",
|
||||
deprecated(since = "3.2.0", note = "Replaced with `ArgMatches::get_many()`")
|
||||
)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct OsValues<'a> {
|
||||
#[allow(clippy::type_complexity)]
|
||||
iter: Map<Flatten<Iter<'a, Vec<AnyValue>>>, fn(&AnyValue) -> &OsStr>,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'a> Iterator for OsValues<'a> {
|
||||
type Item = &'a OsStr;
|
||||
|
||||
fn next(&mut self) -> Option<&'a OsStr> {
|
||||
self.iter.next()
|
||||
}
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(self.len, Some(self.len))
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'a> DoubleEndedIterator for OsValues<'a> {
|
||||
fn next_back(&mut self) -> Option<&'a OsStr> {
|
||||
self.iter.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'a> ExactSizeIterator for OsValues<'a> {}
|
||||
|
||||
/// Creates an empty iterator.
|
||||
#[allow(deprecated)]
|
||||
impl Default for OsValues<'_> {
|
||||
fn default() -> Self {
|
||||
static EMPTY: [Vec<AnyValue>; 0] = [];
|
||||
OsValues {
|
||||
iter: EMPTY[..].iter().flatten().map(|_| unreachable!()),
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate over indices for where an argument appeared when parsing, via [`ArgMatches::indices_of`]
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -1687,6 +1423,7 @@ impl<'a> Default for Indices<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-grouped")]
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
#[inline]
|
||||
fn unwrap_string(value: &AnyValue) -> &str {
|
||||
|
@ -1698,45 +1435,6 @@ fn unwrap_string(value: &AnyValue) -> &str {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
#[inline]
|
||||
fn unwrap_string_arg<'v>(id: &Id, value: &'v AnyValue) -> &'v str {
|
||||
match value.downcast_ref::<String>() {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
panic!(
|
||||
"Must use `_os` lookups with `Arg::allow_invalid_utf8` at `{:?}`",
|
||||
id
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
#[inline]
|
||||
fn unwrap_os_string(value: &AnyValue) -> &OsStr {
|
||||
match value.downcast_ref::<OsString>() {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
panic!("Must use `Arg::allow_invalid_utf8` with `_os` lookups",)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(debug_assertions, track_caller)]
|
||||
#[inline]
|
||||
fn unwrap_os_string_arg<'v>(id: &Id, value: &'v AnyValue) -> &'v OsStr {
|
||||
match value.downcast_ref::<OsString>() {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
panic!(
|
||||
"Must use `Arg::allow_invalid_utf8` with `_os` lookups at `{:?}`",
|
||||
id
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -1746,20 +1444,6 @@ mod tests {
|
|||
static_assertions::assert_impl_all!(ArgMatches: Send, Sync, Unpin);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_values() {
|
||||
#![allow(deprecated)]
|
||||
let mut values: Values = Values::default();
|
||||
assert_eq!(values.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_osvalues() {
|
||||
#![allow(deprecated)]
|
||||
let mut values: OsValues = OsValues::default();
|
||||
assert_eq!(values.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_raw_values() {
|
||||
let mut values: RawValues = Default::default();
|
||||
|
|
|
@ -12,6 +12,3 @@ pub use value_source::ValueSource;
|
|||
pub(crate) use any_value::AnyValue;
|
||||
pub(crate) use arg_matches::SubCommand;
|
||||
pub(crate) use matched_arg::MatchedArg;
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub use arg_matches::{OsValues, Values};
|
||||
|
|
|
@ -22,6 +22,3 @@ pub use self::matches::RawValues;
|
|||
pub use self::matches::ValuesRef;
|
||||
pub use self::matches::{ArgMatches, Indices, ValueSource};
|
||||
pub use error::MatchesError;
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub use self::matches::{OsValues, Values};
|
||||
|
|
|
@ -88,82 +88,6 @@ impl<'help, 'cmd> Validator<'help, 'cmd> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_arg_values(&self, arg: &Arg, ma: &MatchedArg) -> ClapResult<()> {
|
||||
debug!("Validator::validate_arg_values: arg={:?}", arg.name);
|
||||
for val in ma.raw_vals_flatten() {
|
||||
if !arg.possible_vals.is_empty() {
|
||||
debug!(
|
||||
"Validator::validate_arg_values: possible_vals={:?}",
|
||||
arg.possible_vals
|
||||
);
|
||||
let val_str = val.to_string_lossy();
|
||||
let ok = arg
|
||||
.possible_vals
|
||||
.iter()
|
||||
.any(|pv| pv.matches(&val_str, arg.is_ignore_case_set()));
|
||||
if !ok {
|
||||
return Err(Error::invalid_value(
|
||||
self.cmd,
|
||||
val_str.into_owned(),
|
||||
&arg.possible_vals
|
||||
.iter()
|
||||
.filter(|pv| !pv.is_hide_set())
|
||||
.map(PossibleValue::get_name)
|
||||
.collect::<Vec<_>>(),
|
||||
arg.to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
{
|
||||
#![allow(deprecated)]
|
||||
if arg.is_forbid_empty_values_set() && val.is_empty() {
|
||||
debug!("Validator::validate_arg_values: illegal empty val found");
|
||||
return Err(Error::empty_value(
|
||||
self.cmd,
|
||||
&get_possible_values(arg)
|
||||
.iter()
|
||||
.filter(|pv| !pv.is_hide_set())
|
||||
.map(PossibleValue::get_name)
|
||||
.collect::<Vec<_>>(),
|
||||
arg.to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref vtor) = arg.validator {
|
||||
debug!("Validator::validate_arg_values: checking validator...");
|
||||
let mut vtor = vtor.lock().unwrap();
|
||||
if let Err(e) = vtor(&*val.to_string_lossy()) {
|
||||
debug!("error");
|
||||
return Err(Error::value_validation(
|
||||
arg.to_string(),
|
||||
val.to_string_lossy().into_owned(),
|
||||
e,
|
||||
)
|
||||
.with_cmd(self.cmd));
|
||||
} else {
|
||||
debug!("good");
|
||||
}
|
||||
}
|
||||
if let Some(ref vtor) = arg.validator_os {
|
||||
debug!("Validator::validate_arg_values: checking validator_os...");
|
||||
let mut vtor = vtor.lock().unwrap();
|
||||
if let Err(e) = vtor(val) {
|
||||
debug!("error");
|
||||
return Err(Error::value_validation(
|
||||
arg.to_string(),
|
||||
val.to_string_lossy().into(),
|
||||
e,
|
||||
)
|
||||
.with_cmd(self.cmd));
|
||||
} else {
|
||||
debug!("good");
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_conflicts(
|
||||
&mut self,
|
||||
matcher: &ArgMatcher,
|
||||
|
@ -322,7 +246,6 @@ impl<'help, 'cmd> Validator<'help, 'cmd> {
|
|||
);
|
||||
if let Some(arg) = self.cmd.find(name) {
|
||||
self.validate_arg_num_vals(arg, ma)?;
|
||||
self.validate_arg_values(arg, ma)?;
|
||||
self.validate_arg_num_occurs(arg, ma)?;
|
||||
}
|
||||
Ok(())
|
||||
|
@ -348,24 +271,6 @@ impl<'help, 'cmd> Validator<'help, 'cmd> {
|
|||
.create_usage_with_title(&[]),
|
||||
));
|
||||
}
|
||||
if let Some(max_occurs) = a.max_occurs {
|
||||
debug!(
|
||||
"Validator::validate_arg_num_occurs: max_occurs set...{}",
|
||||
max_occurs
|
||||
);
|
||||
let occurs = ma.get_occurrences() as usize;
|
||||
if occurs > max_occurs {
|
||||
return Err(Error::too_many_occurrences(
|
||||
self.cmd,
|
||||
a.to_string(),
|
||||
max_occurs,
|
||||
occurs,
|
||||
Usage::new(self.cmd)
|
||||
.required(&self.required)
|
||||
.create_usage_with_title(&[]),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -676,13 +581,8 @@ impl Conflicts {
|
|||
}
|
||||
|
||||
fn get_possible_values<'help>(a: &Arg<'help>) -> Vec<PossibleValue<'help>> {
|
||||
#![allow(deprecated)]
|
||||
if !a.is_takes_value_set() {
|
||||
vec![]
|
||||
} else if let Some(pvs) = a.get_possible_values() {
|
||||
// Check old first in case the user explicitly set possible values and the derive inferred
|
||||
// a `ValueParser` with some.
|
||||
pvs.to_vec()
|
||||
} else {
|
||||
a.get_value_parser()
|
||||
.possible_values()
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
#![cfg(feature = "cargo")]
|
||||
#![allow(deprecated)]
|
||||
|
||||
use clap::{app_from_crate, error::ErrorKind};
|
||||
|
||||
static EVERYTHING: &str = "clap {{version}}
|
||||
A simple to use, efficient, and full-featured Command Line Argument Parser
|
||||
|
||||
USAGE:
|
||||
clap
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn app_from_crate() {
|
||||
let res = app_from_crate!().try_get_matches_from(vec!["clap", "--help"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayHelp);
|
||||
assert_eq!(
|
||||
err.to_string(),
|
||||
EVERYTHING.replace("{{version}}", env!("CARGO_PKG_VERSION"))
|
||||
);
|
||||
}
|
|
@ -81,72 +81,6 @@ SUBCOMMANDS:
|
|||
info
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn setting() {
|
||||
#![allow(deprecated)]
|
||||
let m = Command::new("setting").args_override_self(true);
|
||||
assert!(m.is_set(AppSettings::AllArgsOverrideSelf));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_setting() {
|
||||
#![allow(deprecated)]
|
||||
let m = Command::new("global_setting").args_override_self(true);
|
||||
assert!(m.is_set(AppSettings::AllArgsOverrideSelf));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unset_setting() {
|
||||
#![allow(deprecated)]
|
||||
let m = Command::new("unset_setting").args_override_self(true);
|
||||
assert!(m.is_set(AppSettings::AllArgsOverrideSelf));
|
||||
|
||||
let m = m.args_override_self(false);
|
||||
assert!(!m.is_set(AppSettings::AllArgsOverrideSelf), "{:#?}", m);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unset_global_setting() {
|
||||
#![allow(deprecated)]
|
||||
let m = Command::new("unset_global_setting").args_override_self(true);
|
||||
assert!(m.is_set(AppSettings::AllArgsOverrideSelf));
|
||||
|
||||
let m = m.args_override_self(false);
|
||||
assert!(!m.is_set(AppSettings::AllArgsOverrideSelf), "{:#?}", m);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setting_bitor() {
|
||||
#![allow(deprecated)]
|
||||
let m = Command::new("setting_bitor").setting(
|
||||
AppSettings::InferSubcommands | AppSettings::Hidden | AppSettings::DisableHelpSubcommand,
|
||||
);
|
||||
|
||||
assert!(m.is_set(AppSettings::InferSubcommands));
|
||||
assert!(m.is_set(AppSettings::Hidden));
|
||||
assert!(m.is_set(AppSettings::DisableHelpSubcommand));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unset_setting_bitor() {
|
||||
#![allow(deprecated)]
|
||||
let m = Command::new("unset_setting_bitor")
|
||||
.setting(AppSettings::InferSubcommands)
|
||||
.setting(AppSettings::Hidden)
|
||||
.setting(AppSettings::DisableHelpSubcommand);
|
||||
|
||||
assert!(m.is_set(AppSettings::InferSubcommands));
|
||||
assert!(m.is_set(AppSettings::Hidden));
|
||||
assert!(m.is_set(AppSettings::DisableHelpSubcommand));
|
||||
|
||||
let m = m.unset_setting(
|
||||
AppSettings::InferSubcommands | AppSettings::Hidden | AppSettings::DisableHelpSubcommand,
|
||||
);
|
||||
assert!(!m.is_set(AppSettings::InferSubcommands), "{:#?}", m);
|
||||
assert!(!m.is_set(AppSettings::Hidden), "{:#?}", m);
|
||||
assert!(!m.is_set(AppSettings::DisableHelpSubcommand), "{:#?}", m);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_command_negate_required() {
|
||||
Command::new("sub_command_negate")
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
#![allow(deprecated)]
|
||||
use clap::{Arg, ArgSettings};
|
||||
|
||||
#[test]
|
||||
fn setting() {
|
||||
let m = Arg::new("setting").setting(ArgSettings::Required);
|
||||
assert!(m.is_required_set());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unset_setting() {
|
||||
let m = Arg::new("unset_setting").setting(ArgSettings::Required);
|
||||
assert!(m.is_required_set());
|
||||
|
||||
let m = m.unset_setting(ArgSettings::Required);
|
||||
assert!(!m.is_required_set(), "{:#?}", m);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setting_bitor() {
|
||||
let m = Arg::new("setting_bitor")
|
||||
.setting(ArgSettings::Required | ArgSettings::Hidden | ArgSettings::Last);
|
||||
|
||||
assert!(m.is_required_set());
|
||||
assert!(m.is_hide_set());
|
||||
assert!(m.is_last_set());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unset_setting_bitor() {
|
||||
let m = Arg::new("unset_setting_bitor")
|
||||
.setting(ArgSettings::Required)
|
||||
.setting(ArgSettings::Hidden)
|
||||
.setting(ArgSettings::Last);
|
||||
|
||||
assert!(m.is_required_set());
|
||||
assert!(m.is_hide_set());
|
||||
assert!(m.is_last_set());
|
||||
|
||||
let m = m.unset_setting(ArgSettings::Required | ArgSettings::Hidden | ArgSettings::Last);
|
||||
assert!(!m.is_required_set(), "{:#?}", m);
|
||||
assert!(!m.is_hide_set(), "{:#?}", m);
|
||||
assert!(!m.is_last_set(), "{:#?}", m);
|
||||
}
|
|
@ -250,29 +250,6 @@ fn issue_1374() {
|
|||
assert_eq!(vs.collect::<Vec<_>>(), vec!["a", "b", "c", "d"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_2171_deprecated() {
|
||||
#![allow(deprecated)]
|
||||
let schema = Command::new("ripgrep#1701 reproducer")
|
||||
.args_override_self(true)
|
||||
.arg(Arg::new("pretty").short('p').long("pretty"))
|
||||
.arg(Arg::new("search_zip").short('z').long("search-zip"));
|
||||
|
||||
let test_args = &[
|
||||
vec!["reproducer", "-pz", "-p"],
|
||||
vec!["reproducer", "-pzp"],
|
||||
vec!["reproducer", "-zpp"],
|
||||
vec!["reproducer", "-pp", "-z"],
|
||||
vec!["reproducer", "-p", "-p", "-z"],
|
||||
vec!["reproducer", "-p", "-pz"],
|
||||
vec!["reproducer", "-ppz"],
|
||||
];
|
||||
|
||||
for argv in test_args {
|
||||
let _ = schema.clone().try_get_matches_from(argv).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_2171() {
|
||||
let schema = Command::new("ripgrep#1701 reproducer")
|
||||
|
|
|
@ -1,505 +0,0 @@
|
|||
#![allow(clippy::bool_assert_comparison)]
|
||||
|
||||
use clap::Arg;
|
||||
use clap::ArgAction;
|
||||
use clap::Command;
|
||||
|
||||
#[test]
|
||||
fn set() {
|
||||
let cmd = Command::new("test").arg(Arg::new("mammal").long("mammal").action(ArgAction::Set));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(matches.get_one::<String>("mammal"), None);
|
||||
assert_eq!(matches.is_present("mammal"), false);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), None);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal", "dog"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.get_one::<String>("mammal").unwrap(), "dog");
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(2));
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal", "dog", "--mammal", "cat"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.get_one::<String>("mammal").unwrap(), "cat");
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(4));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn append() {
|
||||
let cmd = Command::new("test").arg(Arg::new("mammal").long("mammal").action(ArgAction::Append));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(matches.get_one::<String>("mammal"), None);
|
||||
assert_eq!(matches.is_present("mammal"), false);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), None);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal", "dog"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.get_one::<String>("mammal").unwrap(), "dog");
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(
|
||||
matches.indices_of("mammal").unwrap().collect::<Vec<_>>(),
|
||||
vec![2]
|
||||
);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal", "dog", "--mammal", "cat"])
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
matches
|
||||
.get_many::<String>("mammal")
|
||||
.unwrap()
|
||||
.map(|s| s.as_str())
|
||||
.collect::<Vec<_>>(),
|
||||
vec!["dog", "cat"]
|
||||
);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(
|
||||
matches.indices_of("mammal").unwrap().collect::<Vec<_>>(),
|
||||
vec![2, 4]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_true() {
|
||||
let cmd =
|
||||
Command::new("test").arg(Arg::new("mammal").long("mammal").action(ArgAction::SetTrue));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), false);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(1));
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(1));
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_true_with_explicit_default_value() {
|
||||
let cmd = Command::new("test").arg(
|
||||
Arg::new("mammal")
|
||||
.long("mammal")
|
||||
.action(ArgAction::SetTrue)
|
||||
.default_value("false"),
|
||||
);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(1));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), false);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_true_with_default_value_if_present() {
|
||||
let cmd = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("mammal")
|
||||
.long("mammal")
|
||||
.action(ArgAction::SetTrue)
|
||||
.default_value_if("dog", None, Some("true")),
|
||||
)
|
||||
.arg(Arg::new("dog").long("dog").action(ArgAction::SetTrue));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), false);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), false);
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test", "--dog"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), true);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), false);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_true_with_default_value_if_value() {
|
||||
let cmd = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("mammal")
|
||||
.long("mammal")
|
||||
.action(ArgAction::SetTrue)
|
||||
.default_value_if("dog", Some("true"), Some("true")),
|
||||
)
|
||||
.arg(Arg::new("dog").long("dog").action(ArgAction::SetTrue));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), false);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), false);
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test", "--dog"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), true);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), false);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_true_with_required_if_eq() {
|
||||
let cmd = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("mammal")
|
||||
.long("mammal")
|
||||
.action(ArgAction::SetTrue)
|
||||
.required_if_eq("dog", "true"),
|
||||
)
|
||||
.arg(Arg::new("dog").long("dog").action(ArgAction::SetTrue));
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), false);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
|
||||
|
||||
cmd.clone()
|
||||
.try_get_matches_from(["test", "--dog"])
|
||||
.unwrap_err();
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--dog", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), true);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_false() {
|
||||
let cmd = Command::new("test").arg(
|
||||
Arg::new("mammal")
|
||||
.long("mammal")
|
||||
.action(ArgAction::SetFalse),
|
||||
);
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(1));
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), false);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(1));
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), false);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_false_with_explicit_default_value() {
|
||||
let cmd = Command::new("test").arg(
|
||||
Arg::new("mammal")
|
||||
.long("mammal")
|
||||
.action(ArgAction::SetFalse)
|
||||
.default_value("true"),
|
||||
);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), false);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(1));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_false_with_default_value_if_present() {
|
||||
let cmd = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("mammal")
|
||||
.long("mammal")
|
||||
.action(ArgAction::SetFalse)
|
||||
.default_value_if("dog", None, Some("false")),
|
||||
)
|
||||
.arg(Arg::new("dog").long("dog").action(ArgAction::SetFalse));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), true);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test", "--dog"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), false);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), false);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), true);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_false_with_default_value_if_value() {
|
||||
let cmd = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("mammal")
|
||||
.long("mammal")
|
||||
.action(ArgAction::SetFalse)
|
||||
.default_value_if("dog", Some("false"), Some("false")),
|
||||
)
|
||||
.arg(Arg::new("dog").long("dog").action(ArgAction::SetFalse));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), true);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test", "--dog"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), false);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), false);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<bool>("dog").unwrap(), true);
|
||||
assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn count() {
|
||||
let cmd = Command::new("test").arg(Arg::new("mammal").long("mammal").action(ArgAction::Count));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<u8>("mammal").unwrap(), 0);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(1));
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<u8>("mammal").unwrap(), 1);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(1));
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<u8>("mammal").unwrap(), 2);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn count_with_explicit_default_value() {
|
||||
let cmd = Command::new("test").arg(
|
||||
Arg::new("mammal")
|
||||
.long("mammal")
|
||||
.action(ArgAction::Count)
|
||||
.default_value("10"),
|
||||
);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<u8>("mammal").unwrap(), 1);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(1));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<u8>("mammal").unwrap(), 10);
|
||||
assert_eq!(matches.is_present("mammal"), true);
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
assert_eq!(matches.occurrences_of("mammal"), 0);
|
||||
}
|
||||
assert_eq!(matches.index_of("mammal"), Some(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn count_with_default_value_if_present() {
|
||||
let cmd = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("mammal")
|
||||
.long("mammal")
|
||||
.action(ArgAction::Count)
|
||||
.default_value_if("dog", None, Some("10")),
|
||||
)
|
||||
.arg(Arg::new("dog").long("dog").action(ArgAction::Count));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<u8>("dog").unwrap(), 0);
|
||||
assert_eq!(*matches.get_one::<u8>("mammal").unwrap(), 0);
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test", "--dog"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<u8>("dog").unwrap(), 1);
|
||||
assert_eq!(*matches.get_one::<u8>("mammal").unwrap(), 10);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<u8>("dog").unwrap(), 0);
|
||||
assert_eq!(*matches.get_one::<u8>("mammal").unwrap(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn count_with_default_value_if_value() {
|
||||
let cmd = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("mammal")
|
||||
.long("mammal")
|
||||
.action(ArgAction::Count)
|
||||
.default_value_if("dog", Some("2"), Some("10")),
|
||||
)
|
||||
.arg(Arg::new("dog").long("dog").action(ArgAction::Count));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<u8>("dog").unwrap(), 0);
|
||||
assert_eq!(*matches.get_one::<u8>("mammal").unwrap(), 0);
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(["test", "--dog"]).unwrap();
|
||||
assert_eq!(*matches.get_one::<u8>("dog").unwrap(), 1);
|
||||
assert_eq!(*matches.get_one::<u8>("mammal").unwrap(), 0);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--dog", "--dog"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<u8>("dog").unwrap(), 2);
|
||||
assert_eq!(*matches.get_one::<u8>("mammal").unwrap(), 10);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(["test", "--mammal"])
|
||||
.unwrap();
|
||||
assert_eq!(*matches.get_one::<u8>("dog").unwrap(), 0);
|
||||
assert_eq!(*matches.get_one::<u8>("mammal").unwrap(), 1);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#![cfg(feature = "cargo")]
|
||||
#![allow(deprecated)]
|
||||
|
||||
use clap::{app_from_crate, error::ErrorKind};
|
||||
|
||||
static EVERYTHING: &str = "clap {{version}}
|
||||
A simple to use, efficient, and full-featured Command Line Argument Parser
|
||||
|
||||
USAGE:
|
||||
clap
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn app_from_crate() {
|
||||
let res = app_from_crate!().try_get_matches_from(vec!["clap", "--help"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayHelp);
|
||||
assert_eq!(
|
||||
err.to_string(),
|
||||
EVERYTHING.replace("{{version}}", env!("CARGO_PKG_VERSION"))
|
||||
);
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,196 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use clap::{arg, Arg, Command};
|
||||
|
||||
static SC_VISIBLE_ALIAS_HELP: &str = "ct-test 1.2
|
||||
Some help
|
||||
|
||||
USAGE:
|
||||
ct test [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-f, --flag [aliases: v_flg, flag2, flg3]
|
||||
-h, --help Print help information
|
||||
-o, --opt <opt> [aliases: visible]
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static SC_INVISIBLE_ALIAS_HELP: &str = "ct-test 1.2
|
||||
Some help
|
||||
|
||||
USAGE:
|
||||
ct test [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-f, --flag
|
||||
-h, --help Print help information
|
||||
-o, --opt <opt>
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn single_alias_of_option() {
|
||||
let a = Command::new("single_alias")
|
||||
.arg(
|
||||
Arg::new("alias")
|
||||
.long("alias")
|
||||
.takes_value(true)
|
||||
.help("single alias")
|
||||
.alias("new-opt"),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--new-opt", "cool"]);
|
||||
assert!(a.is_ok(), "{}", a.unwrap_err());
|
||||
let a = a.unwrap();
|
||||
assert!(a.is_present("alias"));
|
||||
assert_eq!(a.value_of("alias").unwrap(), "cool");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_aliases_of_option() {
|
||||
let a = Command::new("multiple_aliases").arg(
|
||||
Arg::new("aliases")
|
||||
.long("aliases")
|
||||
.takes_value(true)
|
||||
.help("multiple aliases")
|
||||
.aliases(&["alias1", "alias2", "alias3"]),
|
||||
);
|
||||
let long = a
|
||||
.clone()
|
||||
.try_get_matches_from(vec!["", "--aliases", "value"]);
|
||||
assert!(long.is_ok(), "{}", long.unwrap_err());
|
||||
let long = long.unwrap();
|
||||
|
||||
let als1 = a
|
||||
.clone()
|
||||
.try_get_matches_from(vec!["", "--alias1", "value"]);
|
||||
assert!(als1.is_ok(), "{}", als1.unwrap_err());
|
||||
let als1 = als1.unwrap();
|
||||
|
||||
let als2 = a
|
||||
.clone()
|
||||
.try_get_matches_from(vec!["", "--alias2", "value"]);
|
||||
assert!(als2.is_ok(), "{}", als2.unwrap_err());
|
||||
let als2 = als2.unwrap();
|
||||
|
||||
let als3 = a
|
||||
.clone()
|
||||
.try_get_matches_from(vec!["", "--alias3", "value"]);
|
||||
assert!(als3.is_ok(), "{}", als3.unwrap_err());
|
||||
let als3 = als3.unwrap();
|
||||
|
||||
assert!(long.is_present("aliases"));
|
||||
assert!(als1.is_present("aliases"));
|
||||
assert!(als2.is_present("aliases"));
|
||||
assert!(als3.is_present("aliases"));
|
||||
assert_eq!(long.value_of("aliases").unwrap(), "value");
|
||||
assert_eq!(als1.value_of("aliases").unwrap(), "value");
|
||||
assert_eq!(als2.value_of("aliases").unwrap(), "value");
|
||||
assert_eq!(als3.value_of("aliases").unwrap(), "value");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_alias_of_flag() {
|
||||
let a = Command::new("test")
|
||||
.arg(Arg::new("flag").long("flag").alias("alias"))
|
||||
.try_get_matches_from(vec!["", "--alias"]);
|
||||
assert!(a.is_ok(), "{}", a.unwrap_err());
|
||||
let a = a.unwrap();
|
||||
assert!(a.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_aliases_of_flag() {
|
||||
let a = Command::new("test").arg(Arg::new("flag").long("flag").aliases(&[
|
||||
"invisible",
|
||||
"set",
|
||||
"of",
|
||||
"cool",
|
||||
"aliases",
|
||||
]));
|
||||
|
||||
let flag = a.clone().try_get_matches_from(vec!["", "--flag"]);
|
||||
assert!(flag.is_ok(), "{}", flag.unwrap_err());
|
||||
let flag = flag.unwrap();
|
||||
|
||||
let inv = a.clone().try_get_matches_from(vec!["", "--invisible"]);
|
||||
assert!(inv.is_ok(), "{}", inv.unwrap_err());
|
||||
let inv = inv.unwrap();
|
||||
|
||||
let cool = a.clone().try_get_matches_from(vec!["", "--cool"]);
|
||||
assert!(cool.is_ok(), "{}", cool.unwrap_err());
|
||||
let cool = cool.unwrap();
|
||||
|
||||
let als = a.clone().try_get_matches_from(vec!["", "--aliases"]);
|
||||
assert!(als.is_ok(), "{}", als.unwrap_err());
|
||||
let als = als.unwrap();
|
||||
|
||||
assert!(flag.is_present("flag"));
|
||||
assert!(inv.is_present("flag"));
|
||||
assert!(cool.is_present("flag"));
|
||||
assert!(als.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn alias_on_a_subcommand_option() {
|
||||
let m = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some").arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.takes_value(true)
|
||||
.alias("opt")
|
||||
.help("testing testing"),
|
||||
),
|
||||
)
|
||||
.arg(Arg::new("other").long("other").aliases(&["o1", "o2", "o3"]))
|
||||
.try_get_matches_from(vec!["test", "some", "--opt", "awesome"])
|
||||
.unwrap();
|
||||
|
||||
assert!(m.subcommand_matches("some").is_some());
|
||||
let sub_m = m.subcommand_matches("some").unwrap();
|
||||
assert!(sub_m.is_present("test"));
|
||||
assert_eq!(sub_m.value_of("test").unwrap(), "awesome");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invisible_arg_aliases_help_output() {
|
||||
let cmd = Command::new("ct").author("Salim Afiune").subcommand(
|
||||
Command::new("test")
|
||||
.about("Some help")
|
||||
.version("1.2")
|
||||
.arg(
|
||||
Arg::new("opt")
|
||||
.long("opt")
|
||||
.short('o')
|
||||
.takes_value(true)
|
||||
.aliases(&["invisible", "als1", "more"]),
|
||||
)
|
||||
.arg(arg!(-f - -flag).aliases(&["unseeable", "flg1", "anyway"])),
|
||||
);
|
||||
utils::assert_output(cmd, "ct test --help", SC_INVISIBLE_ALIAS_HELP, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn visible_arg_aliases_help_output() {
|
||||
let cmd = Command::new("ct").author("Salim Afiune").subcommand(
|
||||
Command::new("test")
|
||||
.about("Some help")
|
||||
.version("1.2")
|
||||
.arg(
|
||||
Arg::new("opt")
|
||||
.long("opt")
|
||||
.short('o')
|
||||
.takes_value(true)
|
||||
.alias("invisible")
|
||||
.visible_alias("visible"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("flg")
|
||||
.long("flag")
|
||||
.short('f')
|
||||
.visible_aliases(&["v_flg", "flag2", "flg3"]),
|
||||
),
|
||||
);
|
||||
utils::assert_output(cmd, "ct test --help", SC_VISIBLE_ALIAS_HELP, false);
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use clap::{arg, Arg, Command};
|
||||
|
||||
static SC_VISIBLE_ALIAS_HELP: &str = "ct-test 1.2
|
||||
Some help
|
||||
|
||||
USAGE:
|
||||
ct test [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-f, --flag [aliases: flag1] [short aliases: a, b, 🦆]
|
||||
-h, --help Print help information
|
||||
-o, --opt <opt> [short aliases: v]
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static SC_INVISIBLE_ALIAS_HELP: &str = "ct-test 1.2
|
||||
Some help
|
||||
|
||||
USAGE:
|
||||
ct test [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-f, --flag
|
||||
-h, --help Print help information
|
||||
-o, --opt <opt>
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn single_short_alias_of_option() {
|
||||
let a = Command::new("single_alias")
|
||||
.arg(
|
||||
Arg::new("alias")
|
||||
.long("alias")
|
||||
.takes_value(true)
|
||||
.help("single short alias")
|
||||
.short_alias('a'),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "-a", "cool"]);
|
||||
assert!(a.is_ok(), "{}", a.unwrap_err());
|
||||
let a = a.unwrap();
|
||||
assert!(a.is_present("alias"));
|
||||
assert_eq!(a.value_of("alias").unwrap(), "cool");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_short_aliases_of_option() {
|
||||
let a = Command::new("multiple_aliases").arg(
|
||||
Arg::new("aliases")
|
||||
.long("aliases")
|
||||
.takes_value(true)
|
||||
.help("multiple aliases")
|
||||
.short_aliases(&['1', '2', '3']),
|
||||
);
|
||||
let long = a
|
||||
.clone()
|
||||
.try_get_matches_from(vec!["", "--aliases", "value"]);
|
||||
assert!(long.is_ok(), "{}", long.unwrap_err());
|
||||
let long = long.unwrap();
|
||||
|
||||
let als1 = a.clone().try_get_matches_from(vec!["", "-1", "value"]);
|
||||
assert!(als1.is_ok(), "{}", als1.unwrap_err());
|
||||
let als1 = als1.unwrap();
|
||||
|
||||
let als2 = a.clone().try_get_matches_from(vec!["", "-2", "value"]);
|
||||
assert!(als2.is_ok(), "{}", als2.unwrap_err());
|
||||
let als2 = als2.unwrap();
|
||||
|
||||
let als3 = a.clone().try_get_matches_from(vec!["", "-3", "value"]);
|
||||
assert!(als3.is_ok(), "{}", als3.unwrap_err());
|
||||
let als3 = als3.unwrap();
|
||||
|
||||
assert!(long.is_present("aliases"));
|
||||
assert!(als1.is_present("aliases"));
|
||||
assert!(als2.is_present("aliases"));
|
||||
assert!(als3.is_present("aliases"));
|
||||
assert_eq!(long.value_of("aliases").unwrap(), "value");
|
||||
assert_eq!(als1.value_of("aliases").unwrap(), "value");
|
||||
assert_eq!(als2.value_of("aliases").unwrap(), "value");
|
||||
assert_eq!(als3.value_of("aliases").unwrap(), "value");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_short_alias_of_flag() {
|
||||
let a = Command::new("test")
|
||||
.arg(Arg::new("flag").long("flag").short_alias('f'))
|
||||
.try_get_matches_from(vec!["", "-f"]);
|
||||
assert!(a.is_ok(), "{}", a.unwrap_err());
|
||||
let a = a.unwrap();
|
||||
assert!(a.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_short_aliases_of_flag() {
|
||||
let a = Command::new("test").arg(
|
||||
Arg::new("flag")
|
||||
.long("flag")
|
||||
.short_aliases(&['a', 'b', 'c', 'd', 'e']),
|
||||
);
|
||||
|
||||
let flag = a.clone().try_get_matches_from(vec!["", "--flag"]);
|
||||
assert!(flag.is_ok(), "{}", flag.unwrap_err());
|
||||
let flag = flag.unwrap();
|
||||
|
||||
let als1 = a.clone().try_get_matches_from(vec!["", "-a"]);
|
||||
assert!(als1.is_ok(), "{}", als1.unwrap_err());
|
||||
let als1 = als1.unwrap();
|
||||
|
||||
let als2 = a.clone().try_get_matches_from(vec!["", "-b"]);
|
||||
assert!(als2.is_ok(), "{}", als2.unwrap_err());
|
||||
let als2 = als2.unwrap();
|
||||
|
||||
let als3 = a.clone().try_get_matches_from(vec!["", "-c"]);
|
||||
assert!(als3.is_ok(), "{}", als3.unwrap_err());
|
||||
let als3 = als3.unwrap();
|
||||
|
||||
assert!(flag.is_present("flag"));
|
||||
assert!(als1.is_present("flag"));
|
||||
assert!(als2.is_present("flag"));
|
||||
assert!(als3.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_alias_on_a_subcommand_option() {
|
||||
let m = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some").arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.takes_value(true)
|
||||
.short_alias('o')
|
||||
.help("testing testing"),
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("other")
|
||||
.long("other")
|
||||
.short_aliases(&['1', '2', '3']),
|
||||
)
|
||||
.try_get_matches_from(vec!["test", "some", "-o", "awesome"])
|
||||
.unwrap();
|
||||
|
||||
assert!(m.subcommand_matches("some").is_some());
|
||||
let sub_m = m.subcommand_matches("some").unwrap();
|
||||
assert!(sub_m.is_present("test"));
|
||||
assert_eq!(sub_m.value_of("test").unwrap(), "awesome");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invisible_short_arg_aliases_help_output() {
|
||||
let cmd = Command::new("ct").author("Salim Afiune").subcommand(
|
||||
Command::new("test")
|
||||
.about("Some help")
|
||||
.version("1.2")
|
||||
.arg(
|
||||
Arg::new("opt")
|
||||
.long("opt")
|
||||
.short('o')
|
||||
.takes_value(true)
|
||||
.short_aliases(&['a', 'b', 'c']),
|
||||
)
|
||||
.arg(arg!(-f - -flag).short_aliases(&['x', 'y', 'z'])),
|
||||
);
|
||||
utils::assert_output(cmd, "ct test --help", SC_INVISIBLE_ALIAS_HELP, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn visible_short_arg_aliases_help_output() {
|
||||
let cmd = Command::new("ct").author("Salim Afiune").subcommand(
|
||||
Command::new("test")
|
||||
.about("Some help")
|
||||
.version("1.2")
|
||||
.arg(
|
||||
Arg::new("opt")
|
||||
.long("opt")
|
||||
.short('o')
|
||||
.takes_value(true)
|
||||
.short_alias('i')
|
||||
.visible_short_alias('v'),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("flg")
|
||||
.long("flag")
|
||||
.short('f')
|
||||
.visible_alias("flag1")
|
||||
.visible_short_aliases(&['a', 'b', '🦆']),
|
||||
),
|
||||
);
|
||||
utils::assert_output(cmd, "ct test --help", SC_VISIBLE_ALIAS_HELP, false);
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
#[cfg(debug_assertions)]
|
||||
use clap::{Arg, Command};
|
||||
|
||||
#[test]
|
||||
#[cfg(debug_assertions)]
|
||||
#[should_panic = "`f` is not an id of an argument or a group."]
|
||||
fn arg_matches_if_present_wrong_arg() {
|
||||
let m = Command::new("test")
|
||||
.arg(Arg::new("flag").short('f'))
|
||||
.try_get_matches_from(&["test", "-f"])
|
||||
.unwrap();
|
||||
|
||||
assert!(m.is_present("flag"));
|
||||
m.is_present("f");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(debug_assertions)]
|
||||
#[should_panic = "`o` is not an id of an argument or a group."]
|
||||
fn arg_matches_value_of_wrong_arg() {
|
||||
let m = Command::new("test")
|
||||
.arg(Arg::new("opt").short('o').takes_value(true))
|
||||
.try_get_matches_from(&["test", "-o", "val"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(m.value_of("opt"), Some("val"));
|
||||
m.value_of("o");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(debug_assertions)]
|
||||
#[should_panic = "`seed` is not a name of a subcommand."]
|
||||
fn arg_matches_subcommand_matches_wrong_sub() {
|
||||
let m = Command::new("test")
|
||||
.subcommand(Command::new("speed"))
|
||||
.try_get_matches_from(&["test", "speed"])
|
||||
.unwrap();
|
||||
|
||||
assert!(m.subcommand_matches("speed").is_some());
|
||||
m.subcommand_matches("seed");
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
#![allow(deprecated)]
|
||||
use clap::{Arg, ArgSettings};
|
||||
|
||||
#[test]
|
||||
fn setting() {
|
||||
let m = Arg::new("setting").setting(ArgSettings::Required);
|
||||
assert!(m.is_required_set());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unset_setting() {
|
||||
let m = Arg::new("unset_setting").setting(ArgSettings::Required);
|
||||
assert!(m.is_required_set());
|
||||
|
||||
let m = m.unset_setting(ArgSettings::Required);
|
||||
assert!(!m.is_required_set(), "{:#?}", m);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setting_bitor() {
|
||||
let m = Arg::new("setting_bitor")
|
||||
.setting(ArgSettings::Required | ArgSettings::Hidden | ArgSettings::Last);
|
||||
|
||||
assert!(m.is_required_set());
|
||||
assert!(m.is_hide_set());
|
||||
assert!(m.is_last_set());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unset_setting_bitor() {
|
||||
let m = Arg::new("unset_setting_bitor")
|
||||
.setting(ArgSettings::Required)
|
||||
.setting(ArgSettings::Hidden)
|
||||
.setting(ArgSettings::Last);
|
||||
|
||||
assert!(m.is_required_set());
|
||||
assert!(m.is_hide_set());
|
||||
assert!(m.is_last_set());
|
||||
|
||||
let m = m.unset_setting(ArgSettings::Required | ArgSettings::Hidden | ArgSettings::Last);
|
||||
assert!(!m.is_required_set(), "{:#?}", m);
|
||||
assert!(!m.is_hide_set(), "{:#?}", m);
|
||||
assert!(!m.is_last_set(), "{:#?}", m);
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
use clap::{Arg, Command};
|
||||
|
||||
#[test]
|
||||
fn borrowed_args() {
|
||||
let arg = Arg::new("some").short('s').long("some").help("other help");
|
||||
let arg2 = Arg::new("some2")
|
||||
.short('S')
|
||||
.long("some-thing")
|
||||
.help("other help");
|
||||
let result = Command::new("sub_command_negate")
|
||||
.arg(Arg::new("test").index(1))
|
||||
.arg(&arg)
|
||||
.arg(&arg2)
|
||||
.subcommand(Command::new("sub1").arg(&arg))
|
||||
.try_get_matches_from(vec!["prog"]);
|
||||
assert!(result.is_ok(), "{}", result.unwrap_err());
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
#![cfg(feature = "cargo")]
|
||||
|
||||
use clap::{
|
||||
crate_authors, crate_description, crate_name, crate_version, error::ErrorKind, Command,
|
||||
};
|
||||
|
||||
static DESCRIPTION_ONLY: &str = "prog 1
|
||||
A simple to use, efficient, and full-featured Command Line Argument Parser
|
||||
|
||||
USAGE:
|
||||
prog
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static AUTHORS_ONLY: &str = "prog 1
|
||||
|
||||
|
||||
USAGE:
|
||||
prog
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn crate_version() {
|
||||
let res = Command::new("prog")
|
||||
.version(crate_version!())
|
||||
.try_get_matches_from(vec!["prog", "--version"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayVersion);
|
||||
assert_eq!(
|
||||
err.to_string(),
|
||||
format!("prog {}\n", env!("CARGO_PKG_VERSION"))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crate_description() {
|
||||
let res = Command::new("prog")
|
||||
.version("1")
|
||||
.about(crate_description!())
|
||||
.try_get_matches_from(vec!["prog", "--help"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayHelp);
|
||||
assert_eq!(err.to_string(), DESCRIPTION_ONLY);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crate_authors() {
|
||||
let res = Command::new("prog")
|
||||
.version("1")
|
||||
.author(crate_authors!())
|
||||
.try_get_matches_from(vec!["prog", "--help"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayHelp);
|
||||
assert_eq!(err.to_string(), AUTHORS_ONLY);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crate_name() {
|
||||
let res = Command::new(crate_name!())
|
||||
.version("3.0")
|
||||
.try_get_matches_from(vec!["clap", "--version"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayVersion);
|
||||
assert_eq!(err.to_string(), "clap 3.0\n");
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
#![cfg(feature = "cargo")]
|
||||
|
||||
use clap::{command, error::ErrorKind};
|
||||
|
||||
static EVERYTHING: &str = "clap {{version}}
|
||||
A simple to use, efficient, and full-featured Command Line Argument Parser
|
||||
|
||||
USAGE:
|
||||
clap
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn command() {
|
||||
let res = command!().try_get_matches_from(vec!["clap", "--help"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayHelp);
|
||||
assert_eq!(
|
||||
err.to_string(),
|
||||
EVERYTHING.replace("{{version}}", env!("CARGO_PKG_VERSION"))
|
||||
);
|
||||
}
|
|
@ -1,509 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use clap::{arg, error::ErrorKind, Arg, ArgGroup, Command};
|
||||
|
||||
static CONFLICT_ERR: &str = "error: The argument '--flag' cannot be used with '-F'
|
||||
|
||||
USAGE:
|
||||
clap-test --flag --long-option-2 <option2> <positional> <positional2>
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
static CONFLICT_ERR_REV: &str = "error: The argument '-F' cannot be used with '--flag'
|
||||
|
||||
USAGE:
|
||||
clap-test -F --long-option-2 <option2> <positional> <positional2>
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
static CONFLICT_ERR_THREE: &str = "error: The argument '--one' cannot be used with:
|
||||
--two
|
||||
--three
|
||||
|
||||
USAGE:
|
||||
three_conflicting_arguments --one
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn flag_conflict() {
|
||||
let result = Command::new("flag_conflict")
|
||||
.arg(arg!(-f --flag "some flag").conflicts_with("other"))
|
||||
.arg(arg!(-o --other "some flag"))
|
||||
.try_get_matches_from(vec!["myprog", "-f", "-o"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_conflict_2() {
|
||||
let result = Command::new("flag_conflict")
|
||||
.arg(arg!(-f --flag "some flag").conflicts_with("other"))
|
||||
.arg(arg!(-o --other "some flag"))
|
||||
.try_get_matches_from(vec!["myprog", "-o", "-f"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_conflict_with_all() {
|
||||
let result = Command::new("flag_conflict")
|
||||
.arg(arg!(-f --flag "some flag").conflicts_with_all(&["other"]))
|
||||
.arg(arg!(-o --other "some flag"))
|
||||
.try_get_matches_from(vec!["myprog", "-o", "-f"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_conflict_with_everything() {
|
||||
let result = Command::new("flag_conflict")
|
||||
.arg(arg!(-f --flag "some flag").exclusive(true))
|
||||
.arg(arg!(-o --other "some flag"))
|
||||
.try_get_matches_from(vec!["myprog", "-o", "-f"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn arg_conflicts_with_group() {
|
||||
let mut cmd = Command::new("group_conflict")
|
||||
.arg(arg!(-f --flag "some flag").conflicts_with("gr"))
|
||||
.group(ArgGroup::new("gr").arg("some").arg("other"))
|
||||
.arg(arg!(--some "some arg"))
|
||||
.arg(arg!(--other "other arg"));
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other", "-f"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "-f", "--some"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--some"]);
|
||||
if let Err(err) = result {
|
||||
panic!("{}", err);
|
||||
}
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other"]);
|
||||
if let Err(err) = result {
|
||||
panic!("{}", err);
|
||||
}
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--flag"]);
|
||||
if let Err(err) = result {
|
||||
panic!("{}", err);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn arg_conflicts_with_group_with_multiple_sources() {
|
||||
let mut cmd = clap::Command::new("group_conflict")
|
||||
.arg(clap::arg!(-f --flag "some flag").conflicts_with("gr"))
|
||||
.group(clap::ArgGroup::new("gr").multiple(true))
|
||||
.arg(
|
||||
clap::arg!(--some <name> "some arg")
|
||||
.required(false)
|
||||
.group("gr"),
|
||||
)
|
||||
.arg(
|
||||
clap::arg!(--other <secs> "other arg")
|
||||
.required(false)
|
||||
.default_value("1000")
|
||||
.group("gr"),
|
||||
);
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "-f"]);
|
||||
if let Err(err) = result {
|
||||
panic!("{}", err);
|
||||
}
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--some", "usb1"]);
|
||||
if let Err(err) = result {
|
||||
panic!("{}", err);
|
||||
}
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--some", "usb1", "--other", "40"]);
|
||||
if let Err(err) = result {
|
||||
panic!("{}", err);
|
||||
}
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "-f", "--some", "usb1"]);
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_conflicts_with_arg() {
|
||||
let mut cmd = Command::new("group_conflict")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.group(
|
||||
ArgGroup::new("gr")
|
||||
.arg("some")
|
||||
.arg("other")
|
||||
.conflicts_with("flag"),
|
||||
)
|
||||
.arg(arg!(--some "some arg"))
|
||||
.arg(arg!(--other "other arg"));
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other", "-f"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "-f", "--some"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--some"]);
|
||||
if let Err(err) = result {
|
||||
panic!("{}", err);
|
||||
}
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other"]);
|
||||
if let Err(err) = result {
|
||||
panic!("{}", err);
|
||||
}
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--flag"]);
|
||||
if let Err(err) = result {
|
||||
panic!("{}", err);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn arg_conflicts_with_required_group() {
|
||||
let mut cmd = Command::new("group_conflict")
|
||||
.arg(arg!(-f --flag "some flag").conflicts_with("gr"))
|
||||
.group(ArgGroup::new("gr").required(true).arg("some").arg("other"))
|
||||
.arg(arg!(--some "some arg"))
|
||||
.arg(arg!(--other "other arg"));
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other", "-f"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "-f", "--some"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--some"]);
|
||||
if let Err(err) = result {
|
||||
panic!("{}", err);
|
||||
}
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other"]);
|
||||
if let Err(err) = result {
|
||||
panic!("{}", err);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn required_group_conflicts_with_arg() {
|
||||
let mut cmd = Command::new("group_conflict")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.group(
|
||||
ArgGroup::new("gr")
|
||||
.required(true)
|
||||
.arg("some")
|
||||
.arg("other")
|
||||
.conflicts_with("flag"),
|
||||
)
|
||||
.arg(arg!(--some "some arg"))
|
||||
.arg(arg!(--other "other arg"));
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other", "-f"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "-f", "--some"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--some"]);
|
||||
if let Err(err) = result {
|
||||
panic!("{}", err);
|
||||
}
|
||||
|
||||
let result = cmd.try_get_matches_from_mut(vec!["myprog", "--other"]);
|
||||
if let Err(err) = result {
|
||||
panic!("{}", err);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conflict_output() {
|
||||
utils::assert_output(
|
||||
utils::complex_app(),
|
||||
"clap-test val1 fa --flag --long-option-2 val2 -F",
|
||||
CONFLICT_ERR,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conflict_output_rev() {
|
||||
utils::assert_output(
|
||||
utils::complex_app(),
|
||||
"clap-test val1 fa -F --long-option-2 val2 --flag",
|
||||
CONFLICT_ERR_REV,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conflict_output_with_required() {
|
||||
utils::assert_output(
|
||||
utils::complex_app(),
|
||||
"clap-test val1 --flag --long-option-2 val2 -F",
|
||||
CONFLICT_ERR,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conflict_output_rev_with_required() {
|
||||
utils::assert_output(
|
||||
utils::complex_app(),
|
||||
"clap-test val1 -F --long-option-2 val2 --flag",
|
||||
CONFLICT_ERR_REV,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conflict_output_three_conflicting() {
|
||||
let cmd = Command::new("three_conflicting_arguments")
|
||||
.arg(
|
||||
Arg::new("one")
|
||||
.long("one")
|
||||
.conflicts_with_all(&["two", "three"]),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("two")
|
||||
.long("two")
|
||||
.conflicts_with_all(&["one", "three"]),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("three")
|
||||
.long("three")
|
||||
.conflicts_with_all(&["one", "two"]),
|
||||
);
|
||||
utils::assert_output(
|
||||
cmd,
|
||||
"three_conflicting_arguments --one --two --three",
|
||||
CONFLICT_ERR_THREE,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_conflicting_arguments() {
|
||||
let a = Command::new("two_conflicting_arguments")
|
||||
.arg(
|
||||
Arg::new("develop")
|
||||
.long("develop")
|
||||
.conflicts_with("production"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("production")
|
||||
.long("production")
|
||||
.conflicts_with("develop"),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--develop", "--production"]);
|
||||
|
||||
assert!(a.is_err());
|
||||
let a = a.unwrap_err();
|
||||
assert!(
|
||||
a.to_string()
|
||||
.contains("The argument \'--develop\' cannot be used with \'--production\'"),
|
||||
"{}",
|
||||
a
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn three_conflicting_arguments() {
|
||||
let a = Command::new("three_conflicting_arguments")
|
||||
.arg(
|
||||
Arg::new("one")
|
||||
.long("one")
|
||||
.conflicts_with_all(&["two", "three"]),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("two")
|
||||
.long("two")
|
||||
.conflicts_with_all(&["one", "three"]),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("three")
|
||||
.long("three")
|
||||
.conflicts_with_all(&["one", "two"]),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--one", "--two", "--three"]);
|
||||
|
||||
assert!(a.is_err());
|
||||
let a = a.unwrap_err();
|
||||
assert!(
|
||||
a.to_string()
|
||||
.contains("The argument \'--one\' cannot be used with:"),
|
||||
"{}",
|
||||
a
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument 'config' cannot conflict with itself"]
|
||||
fn self_conflicting_arg() {
|
||||
let _ = Command::new("prog")
|
||||
.arg(Arg::new("config").long("config").conflicts_with("config"))
|
||||
.try_get_matches_from(vec!["", "--config"]);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument or group 'extra' specified in 'conflicts_with*' for 'config' does not exist"]
|
||||
fn conflicts_with_invalid_arg() {
|
||||
let _ = Command::new("prog")
|
||||
.arg(Arg::new("config").long("config").conflicts_with("extra"))
|
||||
.try_get_matches_from(vec!["", "--config"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conflict_with_unused_default() {
|
||||
let result = Command::new("conflict")
|
||||
.arg(
|
||||
arg!(-o --opt <opt> "some opt")
|
||||
.required(false)
|
||||
.default_value("default"),
|
||||
)
|
||||
.arg(arg!(-f --flag "some flag").conflicts_with("opt"))
|
||||
.try_get_matches_from(vec!["myprog", "-f"]);
|
||||
|
||||
assert!(result.is_ok(), "{}", result.unwrap_err());
|
||||
let m = result.unwrap();
|
||||
|
||||
assert_eq!(m.value_of("opt"), Some("default"));
|
||||
assert!(m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conflicts_with_alongside_default() {
|
||||
let result = Command::new("conflict")
|
||||
.arg(
|
||||
arg!(-o --opt <opt> "some opt")
|
||||
.default_value("default")
|
||||
.required(false)
|
||||
.conflicts_with("flag"),
|
||||
)
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.try_get_matches_from(vec!["myprog", "-f"]);
|
||||
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"conflicts_with should ignore default_value: {:?}",
|
||||
result.unwrap_err()
|
||||
);
|
||||
let m = result.unwrap();
|
||||
|
||||
assert_eq!(m.value_of("opt"), Some("default"));
|
||||
assert!(m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_in_conflicts_with() {
|
||||
let result = Command::new("conflict")
|
||||
.arg(
|
||||
Arg::new("opt")
|
||||
.long("opt")
|
||||
.default_value("default")
|
||||
.group("one"),
|
||||
)
|
||||
.arg(Arg::new("flag").long("flag").conflicts_with("one"))
|
||||
.try_get_matches_from(vec!["myprog", "--flag"]);
|
||||
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"conflicts_with on an arg group should ignore default_value: {:?}",
|
||||
result.unwrap_err()
|
||||
);
|
||||
let m = result.unwrap();
|
||||
|
||||
assert_eq!(m.value_of("opt"), Some("default"));
|
||||
assert!(m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_conflicts_with_default_value() {
|
||||
let result = Command::new("conflict")
|
||||
.arg(
|
||||
Arg::new("opt")
|
||||
.long("opt")
|
||||
.default_value("default")
|
||||
.group("one"),
|
||||
)
|
||||
.arg(Arg::new("flag").long("flag").group("one"))
|
||||
.try_get_matches_from(vec!["myprog", "--flag"]);
|
||||
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"arg group count should ignore default_value: {:?}",
|
||||
result.unwrap_err()
|
||||
);
|
||||
let m = result.unwrap();
|
||||
|
||||
assert_eq!(m.value_of("opt"), Some("default"));
|
||||
assert!(m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_conflicts_with_default_arg() {
|
||||
let result = Command::new("conflict")
|
||||
.arg(Arg::new("opt").long("opt").default_value("default"))
|
||||
.arg(Arg::new("flag").long("flag").group("one"))
|
||||
.group(ArgGroup::new("one").conflicts_with("opt"))
|
||||
.try_get_matches_from(vec!["myprog", "--flag"]);
|
||||
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"arg group conflicts_with should ignore default_value: {:?}",
|
||||
result.unwrap_err()
|
||||
);
|
||||
let m = result.unwrap();
|
||||
|
||||
assert_eq!(m.value_of("opt"), Some("default"));
|
||||
assert!(m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exclusive_with_required() {
|
||||
let cmd = Command::new("bug")
|
||||
.arg(Arg::new("test").long("test").exclusive(true))
|
||||
.arg(Arg::new("input").takes_value(true).required(true));
|
||||
|
||||
cmd.clone()
|
||||
.try_get_matches_from(["bug", "--test", "required"])
|
||||
.unwrap_err();
|
||||
|
||||
cmd.clone()
|
||||
.try_get_matches_from(["bug", "required"])
|
||||
.unwrap();
|
||||
|
||||
cmd.clone().try_get_matches_from(["bug", "--test"]).unwrap();
|
||||
}
|
|
@ -1,187 +0,0 @@
|
|||
use clap::{arg, Arg, ArgMatches, Command};
|
||||
|
||||
#[test]
|
||||
fn opt_missing() {
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
Arg::new("color")
|
||||
.long("color")
|
||||
.default_value("auto")
|
||||
.min_values(0)
|
||||
.require_equals(true)
|
||||
.default_missing_value("always"),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("color"));
|
||||
assert_eq!(m.value_of("color").unwrap(), "auto");
|
||||
assert_eq!(m.occurrences_of("color"), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opt_present_with_missing_value() {
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
Arg::new("color")
|
||||
.long("color")
|
||||
.default_value("auto")
|
||||
.min_values(0)
|
||||
.require_equals(true)
|
||||
.default_missing_value("always"),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--color"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("color"));
|
||||
assert_eq!(m.value_of("color").unwrap(), "always");
|
||||
assert_eq!(m.occurrences_of("color"), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opt_present_with_value() {
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
Arg::new("color")
|
||||
.long("color")
|
||||
.default_value("auto")
|
||||
.min_values(0)
|
||||
.require_equals(true)
|
||||
.default_missing_value("always"),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--color=never"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("color"));
|
||||
assert_eq!(m.value_of("color").unwrap(), "never");
|
||||
assert_eq!(m.occurrences_of("color"), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opt_present_with_empty_value() {
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
Arg::new("color")
|
||||
.long("color")
|
||||
.default_value("auto")
|
||||
.require_equals(true)
|
||||
.default_missing_value("always"),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--color="]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("color"));
|
||||
assert_eq!(m.value_of("color").unwrap(), "");
|
||||
assert_eq!(m.occurrences_of("color"), 1);
|
||||
}
|
||||
|
||||
//## `default_value`/`default_missing_value` non-interaction checks
|
||||
|
||||
#[test]
|
||||
fn opt_default() {
|
||||
// assert no change to usual argument handling when adding default_missing_value()
|
||||
let r = Command::new("cmd")
|
||||
.arg(
|
||||
arg!(o: -o [opt] "some opt")
|
||||
.default_value("default")
|
||||
.default_missing_value("default_missing"),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.value_of("o").unwrap(), "default");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opt_default_user_override() {
|
||||
// assert no change to usual argument handling when adding default_missing_value()
|
||||
let r = Command::new("cmd")
|
||||
.arg(
|
||||
arg!(o: -o [opt] "some opt")
|
||||
.default_value("default")
|
||||
.default_missing_value("default_missing"),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "-o=value"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.value_of("o").unwrap(), "value");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::bool_assert_comparison)]
|
||||
fn default_missing_value_flag_value() {
|
||||
let cmd = Command::new("test").arg(
|
||||
Arg::new("flag")
|
||||
.long("flag")
|
||||
.takes_value(true)
|
||||
.default_missing_value("true"),
|
||||
);
|
||||
|
||||
fn flag_value(m: ArgMatches) -> bool {
|
||||
match m.value_of("flag") {
|
||||
None => false,
|
||||
Some(x) => x.parse().expect("non boolean value"),
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
flag_value(cmd.clone().try_get_matches_from(&["test"]).unwrap()),
|
||||
false
|
||||
);
|
||||
assert_eq!(
|
||||
flag_value(
|
||||
cmd.clone()
|
||||
.try_get_matches_from(&["test", "--flag"])
|
||||
.unwrap()
|
||||
),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
flag_value(
|
||||
cmd.clone()
|
||||
.try_get_matches_from(&["test", "--flag=true"])
|
||||
.unwrap()
|
||||
),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
flag_value(
|
||||
cmd.clone()
|
||||
.try_get_matches_from(&["test", "--flag=false"])
|
||||
.unwrap()
|
||||
),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument `arg`'s default_missing_value=value doesn't match possible values"]
|
||||
fn default_missing_values_are_possible_values() {
|
||||
use clap::{Arg, Command};
|
||||
|
||||
let _ = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.possible_values(["one", "two"])
|
||||
.default_missing_value("value"),
|
||||
)
|
||||
.try_get_matches();
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument `arg`'s default_missing_value=value failed validation: invalid digit found in string"]
|
||||
fn default_missing_values_are_valid() {
|
||||
use clap::{Arg, Command};
|
||||
|
||||
let _ = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.validator(|val| val.parse::<u32>().map_err(|e| e.to_string()))
|
||||
.default_missing_value("value"),
|
||||
)
|
||||
.try_get_matches();
|
||||
}
|
|
@ -1,708 +0,0 @@
|
|||
use super::utils;
|
||||
use clap::{arg, error::ErrorKind, Arg, Command};
|
||||
|
||||
#[test]
|
||||
fn opts() {
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!(o: -o <opt> "some opt")
|
||||
.required(false)
|
||||
.default_value("default"),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.value_of("o").unwrap(), "default");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opt_without_value_fail() {
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!(o: -o <opt> "some opt")
|
||||
.required(false)
|
||||
.default_value("default")
|
||||
.forbid_empty_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "-o"]);
|
||||
assert!(r.is_err());
|
||||
let err = r.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::EmptyValue);
|
||||
assert!(err
|
||||
.to_string()
|
||||
.contains("The argument '-o <opt>' requires a value but none was supplied"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opt_user_override() {
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!(--opt <FILE> "some arg")
|
||||
.required(false)
|
||||
.default_value("default"),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt", "value"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("opt"));
|
||||
assert_eq!(m.value_of("opt").unwrap(), "value");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positionals() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!([arg] "some opt").default_value("default"))
|
||||
.try_get_matches_from(vec![""]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "default");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positional_user_override() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!([arg] "some arg").default_value("default"))
|
||||
.try_get_matches_from(vec!["", "value"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "value");
|
||||
}
|
||||
|
||||
// OsStr Default Values
|
||||
|
||||
#[test]
|
||||
fn osstr_opts() {
|
||||
use std::ffi::OsStr;
|
||||
let expected = OsStr::new("default");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!(o: -o <opt> "some opt")
|
||||
.required(false)
|
||||
.default_value_os(expected),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.value_of("o").unwrap(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn osstr_opt_user_override() {
|
||||
use std::ffi::OsStr;
|
||||
let default = OsStr::new("default");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!(--opt <FILE> "some arg")
|
||||
.required(false)
|
||||
.default_value_os(default),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt", "value"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("opt"));
|
||||
assert_eq!(m.value_of("opt").unwrap(), "value");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn osstr_positionals() {
|
||||
use std::ffi::OsStr;
|
||||
let expected = OsStr::new("default");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(arg!([arg] "some opt").default_value_os(expected))
|
||||
.try_get_matches_from(vec![""]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn osstr_positional_user_override() {
|
||||
use std::ffi::OsStr;
|
||||
let default = OsStr::new("default");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(arg!([arg] "some arg").default_value_os(default))
|
||||
.try_get_matches_from(vec!["", "value"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "value");
|
||||
}
|
||||
|
||||
// --- Default if arg is present
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_no_default() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(true))
|
||||
.arg(arg!([arg] "some arg").default_value_if("opt", None, Some("default")))
|
||||
.try_get_matches_from(vec!["", "--opt", "some"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "default");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_no_default_user_override() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(arg!([arg] "some arg").default_value_if("opt", None, Some("default")))
|
||||
.try_get_matches_from(vec!["", "--opt", "some", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_no_arg_with_default() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_if("opt", None, Some("default")),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "first");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_with_default() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_if("opt", None, Some("default")),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt", "some"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "default");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_with_default_user_override() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_if("opt", None, Some("default")),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt", "some", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_no_arg_with_default_user_override() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_if("opt", None, Some("default")),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "other");
|
||||
}
|
||||
|
||||
// Conditional Default Values
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_with_value_no_default() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(arg!([arg] "some arg").default_value_if("opt", Some("value"), Some("default")))
|
||||
.try_get_matches_from(vec!["", "--opt", "value"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "default");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_with_value_no_default_fail() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(arg!([arg] "some arg").default_value_if("opt", Some("value"), Some("default")))
|
||||
.try_get_matches_from(vec!["", "--opt", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(!m.is_present("arg"));
|
||||
assert!(m.value_of("arg").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_with_value_no_default_user_override() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(arg!([arg] "some arg").default_value_if("opt", Some("some"), Some("default")))
|
||||
.try_get_matches_from(vec!["", "--opt", "some", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_with_value_no_arg_with_default() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_if("opt", Some("some"), Some("default")),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "first");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_with_value_no_arg_with_default_fail() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_if("opt", Some("some"), Some("default")),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "first");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_with_value_with_default() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_if("opt", Some("some"), Some("default")),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt", "some"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "default");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_with_value_with_default_user_override() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_if("opt", Some("some"), Some("default")),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt", "some", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_no_arg_with_value_with_default_user_override() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_if("opt", Some("some"), Some("default")),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_if_arg_present_no_arg_with_value_with_default_user_override_fail() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_if("opt", Some("some"), Some("default")),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt", "value", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "other");
|
||||
}
|
||||
|
||||
// Unsetting the default
|
||||
|
||||
#[test]
|
||||
fn no_default_if_arg_present_with_value_no_default() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(arg!([arg] "some arg").default_value_if("opt", Some("value"), None))
|
||||
.try_get_matches_from(vec!["", "--opt", "value"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(!m.is_present("arg"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_default_if_arg_present_with_value_with_default() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("default")
|
||||
.default_value_if("opt", Some("value"), None),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt", "value"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(!m.is_present("arg"));
|
||||
assert!(m.value_of("arg").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_default_if_arg_present_with_value_with_default_user_override() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("default")
|
||||
.default_value_if("opt", Some("value"), None),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt", "value", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_default_if_arg_present_no_arg_with_value_with_default() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("default")
|
||||
.default_value_if("opt", Some("value"), None),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "default");
|
||||
}
|
||||
|
||||
// Multiple conditions
|
||||
|
||||
#[test]
|
||||
fn default_ifs_arg_present() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(arg!(--flag "some arg"))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_ifs(&[
|
||||
("opt", Some("some"), Some("default")),
|
||||
("flag", None, Some("flg")),
|
||||
]),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--flag"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "flg");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_default_ifs_arg_present() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(arg!(--flag "some arg"))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_ifs(&[("opt", Some("some"), Some("default")), ("flag", None, None)]),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--flag"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(!m.is_present("arg"));
|
||||
assert!(m.value_of("arg").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_ifs_arg_present_user_override() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(arg!(--flag "some arg"))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_ifs(&[
|
||||
("opt", Some("some"), Some("default")),
|
||||
("flag", None, Some("flg")),
|
||||
]),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--flag", "value"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "value");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_ifs_arg_present_order() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(--opt <FILE> "some arg").required(false))
|
||||
.arg(arg!(--flag "some arg"))
|
||||
.arg(
|
||||
arg!([arg] "some arg")
|
||||
.default_value("first")
|
||||
.default_value_ifs(&[
|
||||
("opt", Some("some"), Some("default")),
|
||||
("flag", None, Some("flg")),
|
||||
]),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt=some", "--flag"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "default");
|
||||
}
|
||||
|
||||
// Interaction with requires
|
||||
|
||||
#[test]
|
||||
fn conditional_reqs_pass() {
|
||||
let m = Command::new("Test cmd")
|
||||
.arg(
|
||||
Arg::new("target")
|
||||
.takes_value(true)
|
||||
.default_value("file")
|
||||
.long("target"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("input")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.long("input"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("output")
|
||||
.takes_value(true)
|
||||
.required_if_eq("target", "file")
|
||||
.long("output"),
|
||||
)
|
||||
.try_get_matches_from(vec!["test", "--input", "some", "--output", "other"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
assert_eq!(m.value_of("output"), Some("other"));
|
||||
assert_eq!(m.value_of("input"), Some("some"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_defaults() {
|
||||
let r = Command::new("diff")
|
||||
.arg(
|
||||
Arg::new("files")
|
||||
.long("files")
|
||||
.number_of_values(2)
|
||||
.allow_invalid_utf8(true)
|
||||
.default_values(&["old", "new"]),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("files"));
|
||||
assert_eq!(m.values_of_lossy("files").unwrap(), vec!["old", "new"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_defaults_override() {
|
||||
let r = Command::new("diff")
|
||||
.arg(
|
||||
Arg::new("files")
|
||||
.long("files")
|
||||
.number_of_values(2)
|
||||
.allow_invalid_utf8(true)
|
||||
.default_values(&["old", "new"]),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--files", "other", "mine"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("files"));
|
||||
assert_eq!(m.values_of_lossy("files").unwrap(), vec!["other", "mine"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_vals_donnot_show_in_smart_usage() {
|
||||
let cmd = Command::new("bug")
|
||||
.arg(
|
||||
Arg::new("foo")
|
||||
.long("config")
|
||||
.takes_value(true)
|
||||
.default_value("bar"),
|
||||
)
|
||||
.arg(Arg::new("input").required(true));
|
||||
|
||||
utils::assert_output(
|
||||
cmd,
|
||||
"bug",
|
||||
"error: The following required arguments were not provided:
|
||||
<input>
|
||||
|
||||
USAGE:
|
||||
bug [OPTIONS] <input>
|
||||
|
||||
For more information try --help
|
||||
",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1050_num_vals_and_defaults() {
|
||||
let res = Command::new("hello")
|
||||
.arg(
|
||||
Arg::new("exit-code")
|
||||
.long("exit-code")
|
||||
.takes_value(true)
|
||||
.number_of_values(1)
|
||||
.default_value("0"),
|
||||
)
|
||||
.try_get_matches_from(vec!["hello", "--exit-code=1"]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
let m = res.unwrap();
|
||||
assert_eq!(m.value_of("exit-code"), Some("1"));
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument `arg`'s default_value=value doesn't match possible values"]
|
||||
fn default_values_are_possible_values() {
|
||||
use clap::{Arg, Command};
|
||||
|
||||
let _ = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.possible_values(["one", "two"])
|
||||
.default_value("value"),
|
||||
)
|
||||
.try_get_matches();
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument `arg`'s default_value=one failed validation: invalid digit found in string"]
|
||||
fn invalid_default_values() {
|
||||
use clap::{Arg, Command};
|
||||
|
||||
let _ = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.validator(|val| val.parse::<u32>().map_err(|e| e.to_string()))
|
||||
.default_value("one"),
|
||||
)
|
||||
.try_get_matches();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid_delimited_default_values() {
|
||||
use clap::{Arg, Command};
|
||||
|
||||
let _ = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.validator(|val| val.parse::<u32>().map_err(|e| e.to_string()))
|
||||
.use_value_delimiter(true)
|
||||
.require_value_delimiter(true)
|
||||
.default_value("1,2,3"),
|
||||
)
|
||||
.try_get_matches();
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument `arg`'s default_value=one failed validation: invalid digit found in string"]
|
||||
fn invalid_delimited_default_values() {
|
||||
use clap::{Arg, Command};
|
||||
|
||||
let _ = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.validator(|val| val.parse::<u32>().map_err(|e| e.to_string()))
|
||||
.use_value_delimiter(true)
|
||||
.require_value_delimiter(true)
|
||||
.default_value("one,two"),
|
||||
)
|
||||
.try_get_matches();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_value_delimiter() {
|
||||
let cmd = Command::new("multiple_values").arg(
|
||||
Arg::new("option")
|
||||
.long("option")
|
||||
.help("multiple options")
|
||||
.value_delimiter(';')
|
||||
.default_value("first;second"),
|
||||
);
|
||||
|
||||
let matches = cmd.try_get_matches_from(vec![""]).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
matches.values_of("option").unwrap().collect::<Vec<_>>(),
|
||||
["first", "second"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_with_value_delimiter() {
|
||||
let cmd = Command::new("program").arg(
|
||||
Arg::new("option")
|
||||
.long("option")
|
||||
.value_delimiter(';')
|
||||
.default_missing_values(&["value1;value2;value3", "value4;value5"]),
|
||||
);
|
||||
|
||||
let matches = cmd
|
||||
.try_get_matches_from(vec!["program", "--option"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
matches.values_of("option").unwrap().collect::<Vec<_>>(),
|
||||
["value1", "value2", "value3", "value4", "value5"]
|
||||
);
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
use clap::{Arg, Command};
|
||||
|
||||
#[test]
|
||||
fn opt_default_no_delim() {
|
||||
let m = Command::new("no_delim")
|
||||
.arg(Arg::new("option").long("option").takes_value(true))
|
||||
.try_get_matches_from(vec!["", "--option", "val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
||||
assert!(m.is_present("option"));
|
||||
assert_eq!(m.occurrences_of("option"), 1);
|
||||
assert_eq!(m.value_of("option").unwrap(), "val1,val2,val3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opt_eq_no_delim() {
|
||||
let m = Command::new("no_delim")
|
||||
.arg(Arg::new("option").long("option").takes_value(true))
|
||||
.try_get_matches_from(vec!["", "--option=val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
||||
assert!(m.is_present("option"));
|
||||
assert_eq!(m.occurrences_of("option"), 1);
|
||||
assert_eq!(m.value_of("option").unwrap(), "val1,val2,val3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opt_s_eq_no_delim() {
|
||||
let m = Command::new("no_delim")
|
||||
.arg(Arg::new("option").short('o').takes_value(true))
|
||||
.try_get_matches_from(vec!["", "-o=val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok(), "{:?}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
||||
assert!(m.is_present("option"));
|
||||
assert_eq!(m.occurrences_of("option"), 1);
|
||||
assert_eq!(m.value_of("option").unwrap(), "val1,val2,val3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opt_s_default_no_delim() {
|
||||
let m = Command::new("no_delim")
|
||||
.arg(Arg::new("option").short('o').takes_value(true))
|
||||
.try_get_matches_from(vec!["", "-o", "val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok(), "{:?}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
||||
assert!(m.is_present("option"));
|
||||
assert_eq!(m.occurrences_of("option"), 1);
|
||||
assert_eq!(m.value_of("option").unwrap(), "val1,val2,val3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opt_s_no_space_no_delim() {
|
||||
let m = Command::new("no_delim")
|
||||
.arg(Arg::new("option").short('o').takes_value(true))
|
||||
.try_get_matches_from(vec!["", "-o", "val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
||||
assert!(m.is_present("option"));
|
||||
assert_eq!(m.occurrences_of("option"), 1);
|
||||
assert_eq!(m.value_of("option").unwrap(), "val1,val2,val3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opt_s_no_space_mult_no_delim() {
|
||||
let m = Command::new("no_delim")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "-o", "val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
||||
assert!(m.is_present("option"));
|
||||
assert_eq!(m.occurrences_of("option"), 1);
|
||||
assert_eq!(m.value_of("option").unwrap(), "val1,val2,val3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opt_eq_mult_def_delim() {
|
||||
let m = Command::new("no_delim")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.long("opt")
|
||||
.takes_value(true)
|
||||
.multiple_values(true)
|
||||
.use_value_delimiter(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt=val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
||||
assert!(m.is_present("option"));
|
||||
assert_eq!(m.occurrences_of("option"), 1);
|
||||
assert_eq!(
|
||||
m.values_of("option").unwrap().collect::<Vec<_>>(),
|
||||
&["val1", "val2", "val3"]
|
||||
);
|
||||
}
|
|
@ -1,293 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use std::str;
|
||||
|
||||
use clap::{AppSettings, Arg, Command};
|
||||
|
||||
static NO_DERIVE_ORDER: &str = "test 1.2
|
||||
|
||||
USAGE:
|
||||
test [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
--flag_a second flag
|
||||
--flag_b first flag
|
||||
-h, --help Print help information
|
||||
--option_a <option_a> second option
|
||||
--option_b <option_b> first option
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static UNIFIED_HELP_AND_DERIVE: &str = "test 1.2
|
||||
|
||||
USAGE:
|
||||
test [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
--flag_b first flag
|
||||
--option_b <option_b> first option
|
||||
--flag_a second flag
|
||||
--option_a <option_a> second option
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static UNIFIED_DERIVE_SC_PROP: &str = "test-sub 1.2
|
||||
|
||||
USAGE:
|
||||
test sub [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
--flag_b first flag
|
||||
--option_b <option_b> first option
|
||||
--flag_a second flag
|
||||
--option_a <option_a> second option
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static UNIFIED_DERIVE_SC_PROP_EXPLICIT_ORDER: &str = "test-sub 1.2
|
||||
|
||||
USAGE:
|
||||
test sub [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
--flag_a second flag
|
||||
--flag_b first flag
|
||||
--option_b <option_b> first option
|
||||
--option_a <option_a> second option
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static PREFER_USER_HELP_DERIVE_ORDER: &str = "test 1.2
|
||||
|
||||
USAGE:
|
||||
test [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help message
|
||||
--flag_b first flag
|
||||
--flag_a second flag
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static PREFER_USER_HELP_SUBCMD_DERIVE_ORDER: &str = "test-sub 1.2
|
||||
|
||||
USAGE:
|
||||
test sub [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help message
|
||||
--flag_b first flag
|
||||
--flag_a second flag
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn no_derive_order() {
|
||||
let cmd = Command::new("test").version("1.2").args(&[
|
||||
Arg::new("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::new("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
Arg::new("flag_a").long("flag_a").help("second flag"),
|
||||
Arg::new("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
]);
|
||||
|
||||
utils::assert_output(cmd, "test --help", NO_DERIVE_ORDER, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_order() {
|
||||
let cmd = Command::new("test")
|
||||
.setting(AppSettings::DeriveDisplayOrder)
|
||||
.version("1.2")
|
||||
.args(&[
|
||||
Arg::new("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::new("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
Arg::new("flag_a").long("flag_a").help("second flag"),
|
||||
Arg::new("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
]);
|
||||
|
||||
utils::assert_output(cmd, "test --help", UNIFIED_HELP_AND_DERIVE, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_order_next_order() {
|
||||
static HELP: &str = "test 1.2
|
||||
|
||||
USAGE:
|
||||
test [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
--flag_b first flag
|
||||
--option_b <option_b> first option
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
--flag_a second flag
|
||||
--option_a <option_a> second option
|
||||
";
|
||||
|
||||
let cmd = Command::new("test")
|
||||
.setting(AppSettings::DeriveDisplayOrder)
|
||||
.version("1.2")
|
||||
.next_display_order(10000)
|
||||
.arg(Arg::new("flag_a").long("flag_a").help("second flag"))
|
||||
.arg(
|
||||
Arg::new("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
)
|
||||
.next_display_order(10)
|
||||
.arg(Arg::new("flag_b").long("flag_b").help("first flag"))
|
||||
.arg(
|
||||
Arg::new("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "test --help", HELP, false);
|
||||
}
|
||||
|
||||
#[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 <option_a> first option
|
||||
--option_b <option_b> second option
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
let cmd = Command::new("test")
|
||||
.setting(AppSettings::DeriveDisplayOrder)
|
||||
.version("1.2")
|
||||
.next_display_order(None)
|
||||
.arg(Arg::new("flag_a").long("flag_a").help("first flag"))
|
||||
.arg(
|
||||
Arg::new("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
)
|
||||
.arg(Arg::new("flag_b").long("flag_b").help("second flag"))
|
||||
.arg(
|
||||
Arg::new("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "test --help", HELP, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_order_subcommand_propagate() {
|
||||
let cmd = Command::new("test")
|
||||
.global_setting(AppSettings::DeriveDisplayOrder)
|
||||
.subcommand(
|
||||
Command::new("sub").version("1.2").args(&[
|
||||
Arg::new("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::new("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
Arg::new("flag_a").long("flag_a").help("second flag"),
|
||||
Arg::new("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
]),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "test sub --help", UNIFIED_DERIVE_SC_PROP, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_order_subcommand_propagate_with_explicit_display_order() {
|
||||
let cmd = Command::new("test")
|
||||
.global_setting(AppSettings::DeriveDisplayOrder)
|
||||
.subcommand(
|
||||
Command::new("sub").version("1.2").args(&[
|
||||
Arg::new("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::new("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
Arg::new("flag_a")
|
||||
.long("flag_a")
|
||||
.help("second flag")
|
||||
.display_order(0),
|
||||
Arg::new("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
]),
|
||||
);
|
||||
|
||||
utils::assert_output(
|
||||
cmd,
|
||||
"test sub --help",
|
||||
UNIFIED_DERIVE_SC_PROP_EXPLICIT_ORDER,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prefer_user_help_with_derive_order() {
|
||||
let cmd = Command::new("test")
|
||||
.setting(AppSettings::DeriveDisplayOrder)
|
||||
.version("1.2")
|
||||
.args(&[
|
||||
Arg::new("help")
|
||||
.long("help")
|
||||
.short('h')
|
||||
.help("Print help message"),
|
||||
Arg::new("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::new("flag_a").long("flag_a").help("second flag"),
|
||||
]);
|
||||
|
||||
utils::assert_output(cmd, "test --help", PREFER_USER_HELP_DERIVE_ORDER, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prefer_user_help_in_subcommand_with_derive_order() {
|
||||
let cmd = Command::new("test")
|
||||
.global_setting(AppSettings::DeriveDisplayOrder)
|
||||
.subcommand(
|
||||
Command::new("sub").version("1.2").args(&[
|
||||
Arg::new("help")
|
||||
.long("help")
|
||||
.short('h')
|
||||
.help("Print help message"),
|
||||
Arg::new("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::new("flag_a").long("flag_a").help("second flag"),
|
||||
]),
|
||||
);
|
||||
|
||||
utils::assert_output(
|
||||
cmd,
|
||||
"test sub --help",
|
||||
PREFER_USER_HELP_SUBCMD_DERIVE_ORDER,
|
||||
false,
|
||||
);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use clap::Command;
|
||||
|
||||
#[test]
|
||||
fn very_large_display_order() {
|
||||
let cmd = Command::new("test").subcommand(Command::new("sub").display_order(usize::MAX));
|
||||
|
||||
utils::assert_output(
|
||||
cmd,
|
||||
"test --help",
|
||||
"test
|
||||
|
||||
USAGE:
|
||||
test [SUBCOMMAND]
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
|
||||
SUBCOMMANDS:
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
sub
|
||||
",
|
||||
false,
|
||||
);
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
use clap::{error::ErrorKind, Arg, Command};
|
||||
|
||||
static HELP: &str = "prog
|
||||
|
||||
USAGE:
|
||||
prog [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-a
|
||||
-b
|
||||
-c
|
||||
-h, --help Print help information
|
||||
";
|
||||
|
||||
static ONLY_B_ERROR: &str = "error: The following required arguments were not provided:
|
||||
-c
|
||||
|
||||
USAGE:
|
||||
prog -b -c
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
static ONLY_C_ERROR: &str = "error: The following required arguments were not provided:
|
||||
-b
|
||||
|
||||
USAGE:
|
||||
prog -c -b
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
fn cmd() -> Command<'static> {
|
||||
Command::new("prog")
|
||||
.arg(
|
||||
Arg::new("a")
|
||||
.short('a')
|
||||
.required_unless_present_any(&["b", "c"])
|
||||
.conflicts_with_all(&["b", "c"]),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("b")
|
||||
.short('b')
|
||||
.required_unless_present("a")
|
||||
.requires("c"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("c")
|
||||
.short('c')
|
||||
.required_unless_present("a")
|
||||
.requires("b"),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid_cases() {
|
||||
let res = cmd().try_get_matches_from(vec!["", "-a"]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
let res = cmd().clone().try_get_matches_from(vec!["", "-b", "-c"]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
let res = cmd().try_get_matches_from(vec!["", "-c", "-b"]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn help_text() {
|
||||
let res = cmd().try_get_matches_from(vec!["prog", "--help"]);
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayHelp);
|
||||
println!("{}", err);
|
||||
assert_eq!(err.to_string(), HELP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_duplicate_error() {
|
||||
let res = cmd().try_get_matches_from(vec!["", "-b"]);
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
|
||||
assert_eq!(err.to_string(), ONLY_B_ERROR);
|
||||
|
||||
let res = cmd().try_get_matches_from(vec!["", "-c"]);
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
|
||||
assert_eq!(err.to_string(), ONLY_C_ERROR);
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use clap::{error::ErrorKind, Arg, Command};
|
||||
|
||||
#[test]
|
||||
fn empty_values() {
|
||||
let m = Command::new("config")
|
||||
.arg(Arg::new("config").long("config").takes_value(true))
|
||||
.try_get_matches_from(&["config", "--config", ""])
|
||||
.unwrap();
|
||||
assert_eq!(m.value_of("config"), Some(""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_values_with_equals() {
|
||||
let m = Command::new("config")
|
||||
.arg(Arg::new("config").long("config").takes_value(true))
|
||||
.try_get_matches_from(&["config", "--config="])
|
||||
.unwrap();
|
||||
assert_eq!(m.value_of("config"), Some(""));
|
||||
|
||||
let m = Command::new("config")
|
||||
.arg(Arg::new("config").short('c').takes_value(true))
|
||||
.try_get_matches_from(&["config", "-c="])
|
||||
.unwrap();
|
||||
assert_eq!(m.value_of("config"), Some(""))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_empty_values() {
|
||||
let m = Command::new("config")
|
||||
.arg(
|
||||
Arg::new("config")
|
||||
.long("config")
|
||||
.takes_value(true)
|
||||
.forbid_empty_values(true),
|
||||
)
|
||||
.try_get_matches_from(&["config", "--config", ""]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::EmptyValue);
|
||||
|
||||
let m = Command::new("config")
|
||||
.arg(
|
||||
Arg::new("config")
|
||||
.short('c')
|
||||
.takes_value(true)
|
||||
.forbid_empty_values(true),
|
||||
)
|
||||
.try_get_matches_from(&["config", "-c", ""]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::EmptyValue)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_empty_values_with_equals() {
|
||||
let m = Command::new("config")
|
||||
.arg(
|
||||
Arg::new("config")
|
||||
.long("config")
|
||||
.takes_value(true)
|
||||
.forbid_empty_values(true),
|
||||
)
|
||||
.try_get_matches_from(&["config", "--config="]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::EmptyValue);
|
||||
|
||||
let m = Command::new("config")
|
||||
.arg(
|
||||
Arg::new("config")
|
||||
.short('c')
|
||||
.takes_value(true)
|
||||
.forbid_empty_values(true),
|
||||
)
|
||||
.try_get_matches_from(&["config", "-c="]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::EmptyValue);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_empty_values_without_equals() {
|
||||
let m = Command::new("config")
|
||||
.arg(
|
||||
Arg::new("config")
|
||||
.long("config")
|
||||
.takes_value(true)
|
||||
.forbid_empty_values(true),
|
||||
)
|
||||
.try_get_matches_from(&["config", "--config"]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::EmptyValue);
|
||||
|
||||
let m = Command::new("config")
|
||||
.arg(
|
||||
Arg::new("config")
|
||||
.short('c')
|
||||
.takes_value(true)
|
||||
.forbid_empty_values(true),
|
||||
)
|
||||
.try_get_matches_from(&["config", "-c"]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::EmptyValue)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_empty_values_without_equals_but_requires_equals() {
|
||||
let cmd = Command::new("config").arg(
|
||||
Arg::new("config")
|
||||
.long("config")
|
||||
.takes_value(true)
|
||||
.forbid_empty_values(true)
|
||||
.require_equals(true),
|
||||
);
|
||||
let m = cmd.clone().try_get_matches_from(&["config", "--config"]);
|
||||
// Should error on no equals rather than empty value.
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::NoEquals);
|
||||
|
||||
static NO_EUQALS_ERROR: &str =
|
||||
"error: Equal sign is needed when assigning values to '--config=<config>'.
|
||||
|
||||
USAGE:
|
||||
config [OPTIONS]
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
utils::assert_output(cmd, "config --config", NO_EUQALS_ERROR, true);
|
||||
}
|
|
@ -1,352 +0,0 @@
|
|||
#![cfg(feature = "env")]
|
||||
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
|
||||
use clap::{arg, Arg, Command};
|
||||
|
||||
#[test]
|
||||
fn env() {
|
||||
env::set_var("CLP_TEST_ENV", "env");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(arg!([arg] "some opt").env("CLP_TEST_ENV").takes_value(true))
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.occurrences_of("arg"), 0);
|
||||
assert_eq!(m.value_of("arg").unwrap(), "env");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn env_bool_literal() {
|
||||
env::set_var("CLP_TEST_FLAG_TRUE", "On");
|
||||
env::set_var("CLP_TEST_FLAG_FALSE", "nO");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(Arg::new("present").short('p').env("CLP_TEST_FLAG_TRUE"))
|
||||
.arg(Arg::new("negated").short('n').env("CLP_TEST_FLAG_FALSE"))
|
||||
.arg(Arg::new("absent").short('a').env("CLP_TEST_FLAG_ABSENT"))
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("present"));
|
||||
assert_eq!(m.occurrences_of("present"), 0);
|
||||
assert_eq!(m.value_of("present"), None);
|
||||
assert!(!m.is_present("negated"));
|
||||
assert!(!m.is_present("absent"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn env_os() {
|
||||
env::set_var("CLP_TEST_ENV_OS", "env");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!([arg] "some opt")
|
||||
.env_os(OsStr::new("CLP_TEST_ENV_OS"))
|
||||
.takes_value(true),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.occurrences_of("arg"), 0);
|
||||
assert_eq!(m.value_of("arg").unwrap(), "env");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_env() {
|
||||
// All the other tests use the presence of the Environment variable...
|
||||
// we need another variable just in case one of the others is running at the same time...
|
||||
env::remove_var("CLP_TEST_ENV_NONE");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!([arg] "some opt")
|
||||
.env("CLP_TEST_ENV_NONE")
|
||||
.takes_value(true),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(!m.is_present("arg"));
|
||||
assert_eq!(m.occurrences_of("arg"), 0);
|
||||
assert_eq!(m.value_of("arg"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_env_no_takes_value() {
|
||||
// All the other tests use the presence of the Environment variable...
|
||||
// we need another variable just in case one of the others is running at the same time...
|
||||
env::remove_var("CLP_TEST_ENV_NONE");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(arg!([arg] "some opt").env("CLP_TEST_ENV_NONE"))
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(!m.is_present("arg"));
|
||||
assert_eq!(m.occurrences_of("arg"), 0);
|
||||
assert_eq!(m.value_of("arg"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_default() {
|
||||
env::set_var("CLP_TEST_ENV_WD", "env");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!([arg] "some opt")
|
||||
.env("CLP_TEST_ENV_WD")
|
||||
.takes_value(true)
|
||||
.default_value("default"),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.occurrences_of("arg"), 0);
|
||||
assert_eq!(m.value_of("arg").unwrap(), "env");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opt_user_override() {
|
||||
env::set_var("CLP_TEST_ENV_OR", "env");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!(--arg [FILE] "some arg")
|
||||
.env("CLP_TEST_ENV_OR")
|
||||
.takes_value(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--arg", "opt"]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.occurrences_of("arg"), 1);
|
||||
assert_eq!(m.value_of("arg").unwrap(), "opt");
|
||||
|
||||
// see https://github.com/clap-rs/clap/issues/1835
|
||||
let values: Vec<_> = m.values_of("arg").unwrap().collect();
|
||||
assert_eq!(values, vec!["opt"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positionals() {
|
||||
env::set_var("CLP_TEST_ENV_P", "env");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!([arg] "some opt")
|
||||
.env("CLP_TEST_ENV_P")
|
||||
.takes_value(true),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.occurrences_of("arg"), 0);
|
||||
assert_eq!(m.value_of("arg").unwrap(), "env");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positionals_user_override() {
|
||||
env::set_var("CLP_TEST_ENV_POR", "env");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!([arg] "some opt")
|
||||
.env("CLP_TEST_ENV_POR")
|
||||
.takes_value(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "opt"]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.occurrences_of("arg"), 1);
|
||||
assert_eq!(m.value_of("arg").unwrap(), "opt");
|
||||
|
||||
// see https://github.com/clap-rs/clap/issues/1835
|
||||
let values: Vec<_> = m.values_of("arg").unwrap().collect();
|
||||
assert_eq!(values, vec!["opt"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_one() {
|
||||
env::set_var("CLP_TEST_ENV_MO", "env");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!([arg] "some opt")
|
||||
.env("CLP_TEST_ENV_MO")
|
||||
.takes_value(true)
|
||||
.use_value_delimiter(true)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.occurrences_of("arg"), 0);
|
||||
assert_eq!(m.values_of("arg").unwrap().collect::<Vec<_>>(), vec!["env"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_three() {
|
||||
env::set_var("CLP_TEST_ENV_MULTI1", "env1,env2,env3");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!([arg] "some opt")
|
||||
.env("CLP_TEST_ENV_MULTI1")
|
||||
.takes_value(true)
|
||||
.use_value_delimiter(true)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.occurrences_of("arg"), 0);
|
||||
assert_eq!(
|
||||
m.values_of("arg").unwrap().collect::<Vec<_>>(),
|
||||
vec!["env1", "env2", "env3"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_no_delimiter() {
|
||||
env::set_var("CLP_TEST_ENV_MULTI2", "env1 env2 env3");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!([arg] "some opt")
|
||||
.env("CLP_TEST_ENV_MULTI2")
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.occurrences_of("arg"), 0);
|
||||
assert_eq!(
|
||||
m.values_of("arg").unwrap().collect::<Vec<_>>(),
|
||||
vec!["env1 env2 env3"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn possible_value() {
|
||||
env::set_var("CLP_TEST_ENV_PV", "env");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!([arg] "some opt")
|
||||
.env("CLP_TEST_ENV_PV")
|
||||
.takes_value(true)
|
||||
.possible_value("env"),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.occurrences_of("arg"), 0);
|
||||
assert_eq!(m.value_of("arg").unwrap(), "env");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn not_possible_value() {
|
||||
env::set_var("CLP_TEST_ENV_NPV", "env");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!([arg] "some opt")
|
||||
.env("CLP_TEST_ENV_NPV")
|
||||
.takes_value(true)
|
||||
.possible_value("never"),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validator() {
|
||||
env::set_var("CLP_TEST_ENV_VDOR", "env");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!([arg] "some opt")
|
||||
.env("CLP_TEST_ENV_VDOR")
|
||||
.takes_value(true)
|
||||
.validator(|s| {
|
||||
if s == "env" {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("not equal".to_string())
|
||||
}
|
||||
}),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(m.occurrences_of("arg"), 0);
|
||||
assert_eq!(m.value_of("arg").unwrap(), "env");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validator_output() {
|
||||
env::set_var("CLP_TEST_ENV_VO", "42");
|
||||
|
||||
let m = Command::new("df")
|
||||
.arg(
|
||||
arg!([arg] "some opt")
|
||||
.env("CLP_TEST_ENV_VO")
|
||||
.takes_value(true)
|
||||
.validator(|s| s.parse::<i32>()),
|
||||
)
|
||||
.try_get_matches_from(vec![""])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(m.value_of("arg").unwrap().parse(), Ok(42));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validator_invalid() {
|
||||
env::set_var("CLP_TEST_ENV_IV", "env");
|
||||
|
||||
let r = Command::new("df")
|
||||
.arg(
|
||||
arg!([arg] "some opt")
|
||||
.env("CLP_TEST_ENV_IV")
|
||||
.takes_value(true)
|
||||
.validator(|s| {
|
||||
if s != "env" {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("is equal".to_string())
|
||||
}
|
||||
}),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
|
||||
assert!(r.is_err());
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use clap::{arg, error::ErrorKind, Arg, Command, Error};
|
||||
|
||||
fn assert_error(err: Error, expected_kind: ErrorKind, expected_output: &str, stderr: bool) {
|
||||
let actual_output = err.to_string();
|
||||
assert_eq!(
|
||||
stderr,
|
||||
err.use_stderr(),
|
||||
"Should Use STDERR failed. Should be {} but is {}",
|
||||
stderr,
|
||||
err.use_stderr()
|
||||
);
|
||||
assert_eq!(expected_kind, err.kind());
|
||||
utils::assert_eq(expected_output, actual_output)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn app_error() {
|
||||
static MESSAGE: &str = "error: Failed for mysterious reasons
|
||||
|
||||
USAGE:
|
||||
test [OPTIONS] --all
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
let cmd = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("all")
|
||||
.short('a')
|
||||
.long("all")
|
||||
.required(true)
|
||||
.help("Also do versioning for private crates (will not be published)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("exact")
|
||||
.long("exact")
|
||||
.help("Specify inter dependency version numbers exactly with `=`"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("no_git_commit")
|
||||
.long("no-git-commit")
|
||||
.help("Do not commit version changes"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("no_git_push")
|
||||
.long("no-git-push")
|
||||
.help("Do not push generated commit and tags to git remote"),
|
||||
);
|
||||
let mut cmd = cmd;
|
||||
let expected_kind = ErrorKind::InvalidValue;
|
||||
let err = cmd.error(expected_kind, "Failed for mysterious reasons");
|
||||
assert_error(err, expected_kind, MESSAGE, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_validation_has_newline() {
|
||||
let m = Command::new("test")
|
||||
.arg(arg!(<PORT>).help("Network port to use"))
|
||||
.try_get_matches_from(["test", "foo"])
|
||||
.unwrap();
|
||||
|
||||
let res = m.value_of_t::<usize>("PORT");
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert!(
|
||||
err.to_string().ends_with('\n'),
|
||||
"Errors should have a trailing newline, got {:?}",
|
||||
err.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn argument_not_found_auto_has_newline() {
|
||||
let m = Command::new("test")
|
||||
.arg(arg!([PORT]).help("Network port to use"))
|
||||
.try_get_matches_from(["test"])
|
||||
.unwrap();
|
||||
|
||||
let res = m.value_of_t::<usize>("PORT");
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert!(
|
||||
err.to_string().ends_with('\n'),
|
||||
"Errors should have a trailing newline, got {:?}",
|
||||
err.to_string()
|
||||
);
|
||||
}
|
|
@ -1,613 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use clap::{arg, error::ErrorKind, Arg, Command};
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_normal() {
|
||||
let matches = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some").short_flag('S').long_flag("some").arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.help("testing testing"),
|
||||
),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "some", "--test"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.subcommand_name().unwrap(), "some");
|
||||
let sub_matches = matches.subcommand_matches("some").unwrap();
|
||||
assert!(sub_matches.is_present("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_normal_with_alias() {
|
||||
let matches = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some")
|
||||
.short_flag('S')
|
||||
.long_flag("S")
|
||||
.arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.help("testing testing"),
|
||||
)
|
||||
.alias("result"),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "result", "--test"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.subcommand_name().unwrap(), "some");
|
||||
let sub_matches = matches.subcommand_matches("some").unwrap();
|
||||
assert!(sub_matches.is_present("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_short() {
|
||||
let matches = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some").short_flag('S').arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.help("testing testing"),
|
||||
),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "-S", "--test"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.subcommand_name().unwrap(), "some");
|
||||
let sub_matches = matches.subcommand_matches("some").unwrap();
|
||||
assert!(sub_matches.is_present("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_short_with_args() {
|
||||
let matches = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some").short_flag('S').arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.help("testing testing"),
|
||||
),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "-St"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.subcommand_name().unwrap(), "some");
|
||||
let sub_matches = matches.subcommand_matches("some").unwrap();
|
||||
assert!(sub_matches.is_present("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_short_with_alias() {
|
||||
let matches = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some")
|
||||
.short_flag('S')
|
||||
.arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.help("testing testing"),
|
||||
)
|
||||
.short_flag_alias('M')
|
||||
.short_flag_alias('B'),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "-Bt"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.subcommand_name().unwrap(), "some");
|
||||
let sub_matches = matches.subcommand_matches("some").unwrap();
|
||||
assert!(sub_matches.is_present("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_short_with_alias_same_as_short_flag() {
|
||||
let matches = Command::new("test")
|
||||
.subcommand(Command::new("some").short_flag('S').short_flag_alias('S'))
|
||||
.try_get_matches_from(vec!["myprog", "-S"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.subcommand_name().unwrap(), "some");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_long_with_alias_same_as_long_flag() {
|
||||
let matches = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some")
|
||||
.long_flag("sync")
|
||||
.long_flag_alias("sync"),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "--sync"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.subcommand_name().unwrap(), "some");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_short_with_aliases_vis_and_hidden() {
|
||||
let cmd = Command::new("test").subcommand(
|
||||
Command::new("some")
|
||||
.short_flag('S')
|
||||
.arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.help("testing testing"),
|
||||
)
|
||||
.visible_short_flag_aliases(&['M', 'B'])
|
||||
.short_flag_alias('C'),
|
||||
);
|
||||
let app1 = cmd.clone();
|
||||
let matches1 = app1.try_get_matches_from(vec!["test", "-M"]).unwrap();
|
||||
assert_eq!(matches1.subcommand_name().unwrap(), "some");
|
||||
|
||||
let app2 = cmd.clone();
|
||||
let matches2 = app2.try_get_matches_from(vec!["test", "-C"]).unwrap();
|
||||
assert_eq!(matches2.subcommand_name().unwrap(), "some");
|
||||
|
||||
let app3 = cmd.clone();
|
||||
let matches3 = app3.try_get_matches_from(vec!["test", "-B"]).unwrap();
|
||||
assert_eq!(matches3.subcommand_name().unwrap(), "some");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_short_with_aliases() {
|
||||
let matches = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some")
|
||||
.short_flag('S')
|
||||
.arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.help("testing testing"),
|
||||
)
|
||||
.short_flag_aliases(&['M', 'B']),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "-Bt"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.subcommand_name().unwrap(), "some");
|
||||
let sub_matches = matches.subcommand_matches("some").unwrap();
|
||||
assert!(sub_matches.is_present("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn flag_subcommand_short_with_alias_hyphen() {
|
||||
let _ = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some")
|
||||
.short_flag('S')
|
||||
.arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.help("testing testing"),
|
||||
)
|
||||
.short_flag_alias('-'),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "-Bt"])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn flag_subcommand_short_with_aliases_hyphen() {
|
||||
let _ = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some")
|
||||
.short_flag('S')
|
||||
.arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.help("testing testing"),
|
||||
)
|
||||
.short_flag_aliases(&['-', '-', '-']),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "-Bt"])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_short_after_long_arg() {
|
||||
let m = Command::new("pacman")
|
||||
.subcommand(
|
||||
Command::new("sync")
|
||||
.short_flag('S')
|
||||
.arg(Arg::new("clean").short('c')),
|
||||
)
|
||||
.arg(Arg::new("arg").long("arg").takes_value(true))
|
||||
.try_get_matches_from(vec!["pacman", "--arg", "foo", "-Sc"])
|
||||
.unwrap();
|
||||
let subm = m.subcommand_matches("sync");
|
||||
assert!(subm.is_some());
|
||||
let subm = subm.unwrap();
|
||||
assert!(subm.is_present("clean"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_long() {
|
||||
let matches = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some").long_flag("some").arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.help("testing testing"),
|
||||
),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "--some", "--test"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.subcommand_name().unwrap(), "some");
|
||||
let sub_matches = matches.subcommand_matches("some").unwrap();
|
||||
assert!(sub_matches.is_present("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_long_with_alias() {
|
||||
let matches = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some")
|
||||
.long_flag("some")
|
||||
.arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.help("testing testing"),
|
||||
)
|
||||
.long_flag_alias("result"),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "--result", "--test"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.subcommand_name().unwrap(), "some");
|
||||
let sub_matches = matches.subcommand_matches("some").unwrap();
|
||||
assert!(sub_matches.is_present("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_long_with_aliases() {
|
||||
let matches = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some")
|
||||
.long_flag("some")
|
||||
.arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.help("testing testing"),
|
||||
)
|
||||
.long_flag_aliases(&["result", "someall"]),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "--result", "--test"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.subcommand_name().unwrap(), "some");
|
||||
let sub_matches = matches.subcommand_matches("some").unwrap();
|
||||
assert!(sub_matches.is_present("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_multiple() {
|
||||
let matches = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some")
|
||||
.short_flag('S')
|
||||
.long_flag("some")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.arg(arg!(-p --print "print something"))
|
||||
.subcommand(
|
||||
Command::new("result")
|
||||
.short_flag('R')
|
||||
.long_flag("result")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.arg(arg!(-p --print "print something")),
|
||||
),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "-SfpRfp"])
|
||||
.unwrap();
|
||||
assert_eq!(matches.subcommand_name().unwrap(), "some");
|
||||
let sub_matches = matches.subcommand_matches("some").unwrap();
|
||||
assert!(sub_matches.is_present("flag"));
|
||||
assert!(sub_matches.is_present("print"));
|
||||
assert_eq!(sub_matches.subcommand_name().unwrap(), "result");
|
||||
let result_matches = sub_matches.subcommand_matches("result").unwrap();
|
||||
assert!(result_matches.is_present("flag"));
|
||||
assert!(result_matches.is_present("print"));
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "the \'-f\' short flag for the \'test\' argument conflicts with the short flag for \'some\' subcommand"]
|
||||
fn flag_subcommand_short_conflict_with_arg() {
|
||||
let _ = Command::new("test")
|
||||
.subcommand(Command::new("some").short_flag('f').long_flag("some"))
|
||||
.arg(Arg::new("test").short('f'))
|
||||
.try_get_matches_from(vec!["myprog", "-f"])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "the \'-f\' short flag is specified for both \'some\' and \'result\' subcommands"]
|
||||
fn flag_subcommand_short_conflict_with_alias() {
|
||||
let _ = Command::new("test")
|
||||
.subcommand(Command::new("some").short_flag('f').long_flag("some"))
|
||||
.subcommand(Command::new("result").short_flag('t').short_flag_alias('f'))
|
||||
.try_get_matches_from(vec!["myprog", "-f"])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "the \'--flag\' long flag is specified for both \'some\' and \'result\' subcommands"]
|
||||
fn flag_subcommand_long_conflict_with_alias() {
|
||||
let _ = Command::new("test")
|
||||
.subcommand(Command::new("some").long_flag("flag"))
|
||||
.subcommand(
|
||||
Command::new("result")
|
||||
.long_flag("test")
|
||||
.long_flag_alias("flag"),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "--flag"])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "the \'-f\' short flag for the \'test\' argument conflicts with the short flag for \'some\' subcommand"]
|
||||
fn flag_subcommand_short_conflict_with_arg_alias() {
|
||||
let _ = Command::new("test")
|
||||
.subcommand(Command::new("some").short_flag('f').long_flag("some"))
|
||||
.arg(Arg::new("test").short('t').short_alias('f'))
|
||||
.try_get_matches_from(vec!["myprog", "-f"])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "the \'--some\' long flag for the \'test\' argument conflicts with the short flag for \'some\' subcommand"]
|
||||
fn flag_subcommand_long_conflict_with_arg_alias() {
|
||||
let _ = Command::new("test")
|
||||
.subcommand(Command::new("some").short_flag('f').long_flag("some"))
|
||||
.arg(Arg::new("test").long("test").alias("some"))
|
||||
.try_get_matches_from(vec!["myprog", "--some"])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "the \'--flag\' long flag for the \'flag\' argument conflicts with the short flag for \'some\' subcommand"]
|
||||
fn flag_subcommand_long_conflict_with_arg() {
|
||||
let _ = Command::new("test")
|
||||
.subcommand(Command::new("some").short_flag('a').long_flag("flag"))
|
||||
.arg(Arg::new("flag").long("flag"))
|
||||
.try_get_matches_from(vec!["myprog", "--flag"])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_conflict_with_help() {
|
||||
let _ = Command::new("test")
|
||||
.subcommand(Command::new("help").short_flag('h').long_flag("help"))
|
||||
.try_get_matches_from(vec!["myprog", "--help"])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_conflict_with_version() {
|
||||
let _ = Command::new("test")
|
||||
.subcommand(Command::new("ver").short_flag('V').long_flag("version"))
|
||||
.try_get_matches_from(vec!["myprog", "--version"])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_long_infer_pass() {
|
||||
let m = Command::new("prog")
|
||||
.infer_subcommands(true)
|
||||
.subcommand(Command::new("test").long_flag("test"))
|
||||
.try_get_matches_from(vec!["prog", "--te"])
|
||||
.unwrap();
|
||||
assert_eq!(m.subcommand_name(), Some("test"));
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "suggestions"))]
|
||||
#[test]
|
||||
fn flag_subcommand_long_infer_fail() {
|
||||
let m = Command::new("prog")
|
||||
.infer_subcommands(true)
|
||||
.subcommand(Command::new("test").long_flag("test"))
|
||||
.subcommand(Command::new("temp").long_flag("temp"))
|
||||
.try_get_matches_from(vec!["prog", "--te"]);
|
||||
assert!(m.is_err(), "{:#?}", m.unwrap());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[cfg(feature = "suggestions")]
|
||||
#[test]
|
||||
fn flag_subcommand_long_infer_fail() {
|
||||
let m = Command::new("prog")
|
||||
.infer_subcommands(true)
|
||||
.subcommand(Command::new("test").long_flag("test"))
|
||||
.subcommand(Command::new("temp").long_flag("temp"))
|
||||
.try_get_matches_from(vec!["prog", "--te"]);
|
||||
assert!(m.is_err(), "{:#?}", m.unwrap());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_long_infer_pass_close() {
|
||||
let m = Command::new("prog")
|
||||
.infer_subcommands(true)
|
||||
.subcommand(Command::new("test").long_flag("test"))
|
||||
.subcommand(Command::new("temp").long_flag("temp"))
|
||||
.try_get_matches_from(vec!["prog", "--tes"])
|
||||
.unwrap();
|
||||
assert_eq!(m.subcommand_name(), Some("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_long_infer_exact_match() {
|
||||
let m = Command::new("prog")
|
||||
.infer_subcommands(true)
|
||||
.subcommand(Command::new("test").long_flag("test"))
|
||||
.subcommand(Command::new("testa").long_flag("testa"))
|
||||
.subcommand(Command::new("testb").long_flag("testb"))
|
||||
.try_get_matches_from(vec!["prog", "--test"])
|
||||
.unwrap();
|
||||
assert_eq!(m.subcommand_name(), Some("test"));
|
||||
}
|
||||
|
||||
static FLAG_SUBCOMMAND_HELP: &str = "pacman-query
|
||||
Query the package database.
|
||||
|
||||
USAGE:
|
||||
pacman {query|--query|-Q} [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-i, --info <info>... view package information
|
||||
-s, --search <search>... search locally installed packages for matching strings
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_long_short_normal_usage_string() {
|
||||
let cmd = Command::new("pacman")
|
||||
.about("package manager utility")
|
||||
.version("5.2.1")
|
||||
.subcommand_required(true)
|
||||
.author("Pacman Development Team")
|
||||
// Query subcommand
|
||||
//
|
||||
// Only a few of its arguments are implemented below.
|
||||
.subcommand(
|
||||
Command::new("query")
|
||||
.short_flag('Q')
|
||||
.long_flag("query")
|
||||
.about("Query the package database.")
|
||||
.arg(
|
||||
Arg::new("search")
|
||||
.short('s')
|
||||
.long("search")
|
||||
.help("search locally installed packages for matching strings")
|
||||
.conflicts_with("info")
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("info")
|
||||
.long("info")
|
||||
.short('i')
|
||||
.conflicts_with("search")
|
||||
.help("view package information")
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
),
|
||||
);
|
||||
utils::assert_output(cmd, "pacman -Qh", FLAG_SUBCOMMAND_HELP, false);
|
||||
}
|
||||
|
||||
static FLAG_SUBCOMMAND_NO_SHORT_HELP: &str = "pacman-query
|
||||
Query the package database.
|
||||
|
||||
USAGE:
|
||||
pacman {query|--query} [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-i, --info <info>... view package information
|
||||
-s, --search <search>... search locally installed packages for matching strings
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_long_normal_usage_string() {
|
||||
let cmd = Command::new("pacman")
|
||||
.about("package manager utility")
|
||||
.version("5.2.1")
|
||||
.subcommand_required(true)
|
||||
.author("Pacman Development Team")
|
||||
// Query subcommand
|
||||
//
|
||||
// Only a few of its arguments are implemented below.
|
||||
.subcommand(
|
||||
Command::new("query")
|
||||
.long_flag("query")
|
||||
.about("Query the package database.")
|
||||
.arg(
|
||||
Arg::new("search")
|
||||
.short('s')
|
||||
.long("search")
|
||||
.help("search locally installed packages for matching strings")
|
||||
.conflicts_with("info")
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("info")
|
||||
.long("info")
|
||||
.short('i')
|
||||
.conflicts_with("search")
|
||||
.help("view package information")
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
),
|
||||
);
|
||||
utils::assert_output(
|
||||
cmd,
|
||||
"pacman query --help",
|
||||
FLAG_SUBCOMMAND_NO_SHORT_HELP,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
static FLAG_SUBCOMMAND_NO_LONG_HELP: &str = "pacman-query
|
||||
Query the package database.
|
||||
|
||||
USAGE:
|
||||
pacman {query|-Q} [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-i, --info <info>... view package information
|
||||
-s, --search <search>... search locally installed packages for matching strings
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_short_normal_usage_string() {
|
||||
let cmd = Command::new("pacman")
|
||||
.about("package manager utility")
|
||||
.version("5.2.1")
|
||||
.subcommand_required(true)
|
||||
.author("Pacman Development Team")
|
||||
// Query subcommand
|
||||
//
|
||||
// Only a few of its arguments are implemented below.
|
||||
.subcommand(
|
||||
Command::new("query")
|
||||
.short_flag('Q')
|
||||
.about("Query the package database.")
|
||||
.arg(
|
||||
Arg::new("search")
|
||||
.short('s')
|
||||
.long("search")
|
||||
.help("search locally installed packages for matching strings")
|
||||
.conflicts_with("info")
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("info")
|
||||
.long("info")
|
||||
.short('i')
|
||||
.conflicts_with("search")
|
||||
.help("view package information")
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
),
|
||||
);
|
||||
utils::assert_output(
|
||||
cmd,
|
||||
"pacman query --help",
|
||||
FLAG_SUBCOMMAND_NO_LONG_HELP,
|
||||
false,
|
||||
);
|
||||
}
|
|
@ -1,198 +0,0 @@
|
|||
use super::utils;
|
||||
use clap::{arg, Arg, Command};
|
||||
|
||||
const USE_FLAG_AS_ARGUMENT: &str =
|
||||
"error: Found argument '--another-flag' which wasn't expected, or isn't valid in this context
|
||||
|
||||
\tIf you tried to supply `--another-flag` as a value rather than a flag, use `-- --another-flag`
|
||||
|
||||
USAGE:
|
||||
mycat [OPTIONS] [filename]
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn flag_using_short() {
|
||||
let m = Command::new("flag")
|
||||
.args(&[
|
||||
arg!(-f --flag "some flag"),
|
||||
arg!(-c --color "some other flag"),
|
||||
])
|
||||
.try_get_matches_from(vec!["", "-f", "-c"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("flag"));
|
||||
assert!(m.is_present("color"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lots_o_flags_sep() {
|
||||
let r = Command::new("opts")
|
||||
.arg(arg!(o: -o ... "some flag"))
|
||||
.try_get_matches_from(vec![
|
||||
"", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o",
|
||||
]);
|
||||
assert!(r.is_ok(), "{:?}", r.unwrap_err().kind());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.occurrences_of("o"), 297); // i.e. more than u8
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lots_o_flags_combined() {
|
||||
let r = Command::new("opts")
|
||||
.arg(arg!(o: -o ... "some flag"))
|
||||
.try_get_matches_from(vec![
|
||||
"",
|
||||
"-oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
|
||||
"-oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
|
||||
"-oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
|
||||
"-oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
|
||||
"-ooooooooooooooooooooooooooooooooooooooooo",
|
||||
]);
|
||||
assert!(r.is_ok(), "{:?}", r.unwrap_err().kind());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.occurrences_of("o"), 297); // i.e. more than u8
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_using_long() {
|
||||
let m = Command::new("flag")
|
||||
.args(&[arg!(--flag "some flag"), arg!(--color "some other flag")])
|
||||
.try_get_matches_from(vec!["", "--flag", "--color"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("flag"));
|
||||
assert!(m.is_present("color"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_using_long_with_literals() {
|
||||
use clap::error::ErrorKind;
|
||||
|
||||
let m = Command::new("flag")
|
||||
.arg(Arg::new("rainbow").long("rainbow"))
|
||||
.try_get_matches_from(vec!["", "--rainbow=false"]);
|
||||
assert!(m.is_err(), "{:#?}", m.unwrap());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::TooManyValues);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_using_mixed() {
|
||||
let m = Command::new("flag")
|
||||
.args(&[
|
||||
arg!(-f --flag "some flag"),
|
||||
arg!(-c --color "some other flag"),
|
||||
])
|
||||
.try_get_matches_from(vec!["", "-f", "--color"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("flag"));
|
||||
assert!(m.is_present("color"));
|
||||
|
||||
let m = Command::new("flag")
|
||||
.args(&[
|
||||
arg!(-f --flag "some flag"),
|
||||
arg!(-c --color "some other flag"),
|
||||
])
|
||||
.try_get_matches_from(vec!["", "--flag", "-c"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("flag"));
|
||||
assert!(m.is_present("color"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_flags_in_single() {
|
||||
let m = Command::new("multe_flags")
|
||||
.args(&[
|
||||
arg!(-f --flag "some flag"),
|
||||
arg!(-c --color "some other flag"),
|
||||
arg!(-d --debug "another other flag"),
|
||||
])
|
||||
.try_get_matches_from(vec!["", "-fcd"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("flag"));
|
||||
assert!(m.is_present("color"));
|
||||
assert!(m.is_present("debug"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1284_argument_in_flag_style() {
|
||||
let cmd = Command::new("mycat")
|
||||
.arg(Arg::new("filename"))
|
||||
.arg(Arg::new("a-flag").long("a-flag"));
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(vec!["", "--", "--another-flag"])
|
||||
.unwrap();
|
||||
assert_eq!(m.value_of("filename"), Some("--another-flag"));
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(vec!["", "--a-flag"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("a-flag"));
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(vec!["", "--", "--a-flag"])
|
||||
.unwrap();
|
||||
assert_eq!(m.value_of("filename"), Some("--a-flag"));
|
||||
|
||||
utils::assert_output(cmd, "mycat --another-flag", USE_FLAG_AS_ARGUMENT, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_2308_multiple_dashes() {
|
||||
static MULTIPLE_DASHES: &str =
|
||||
"error: Found argument '-----' which wasn't expected, or isn't valid in this context
|
||||
|
||||
If you tried to supply `-----` as a value rather than a flag, use `-- -----`
|
||||
|
||||
USAGE:
|
||||
test <arg>
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
let cmd = Command::new("test").arg(Arg::new("arg").takes_value(true).required(true));
|
||||
|
||||
utils::assert_output(cmd, "test -----", MULTIPLE_DASHES, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(feature = "unstable-v4"))]
|
||||
fn leading_dash_stripped() {
|
||||
let cmd = Command::new("mycat").arg(Arg::new("filename").long("--filename"));
|
||||
let matches = cmd.try_get_matches_from(["mycat", "--filename"]).unwrap();
|
||||
assert!(matches.is_present("filename"));
|
||||
}
|
||||
|
||||
#[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() {
|
||||
let cmd = Command::new("mycat").arg(Arg::new("filename").long("--filename"));
|
||||
cmd.debug_assert();
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
use clap::{arg, Arg, Command};
|
||||
|
||||
#[test]
|
||||
fn issue_1076() {
|
||||
let mut cmd = Command::new("myprog")
|
||||
.arg(
|
||||
Arg::new("GLOBAL_ARG")
|
||||
.long("global-arg")
|
||||
.help("Specifies something needed by the subcommands")
|
||||
.global(true)
|
||||
.takes_value(true)
|
||||
.default_value("default_value"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("GLOBAL_FLAG")
|
||||
.long("global-flag")
|
||||
.help("Specifies something needed by the subcommands")
|
||||
.global(true)
|
||||
.takes_value(true),
|
||||
)
|
||||
.subcommand(Command::new("outer").subcommand(Command::new("inner")));
|
||||
let _ = cmd.try_get_matches_from_mut(vec!["myprog"]);
|
||||
let _ = cmd.try_get_matches_from_mut(vec!["myprog"]);
|
||||
let _ = cmd.try_get_matches_from_mut(vec!["myprog"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn propagate_global_arg_in_subcommand_to_subsubcommand_1385() {
|
||||
let m1 = Command::new("foo")
|
||||
.subcommand(
|
||||
Command::new("sub1")
|
||||
.arg(Arg::new("arg1").long("arg1").takes_value(true).global(true))
|
||||
.subcommand(Command::new("sub1a")),
|
||||
)
|
||||
.try_get_matches_from(&["foo", "sub1", "--arg1", "v1", "sub1a"])
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
"v1",
|
||||
m1.subcommand_matches("sub1")
|
||||
.unwrap()
|
||||
.subcommand_matches("sub1a")
|
||||
.unwrap()
|
||||
.value_of("arg1")
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn propagate_global_arg_to_subcommand_in_subsubcommand_2053() {
|
||||
let m = Command::new("opts")
|
||||
.arg(arg!(--"global-flag").global(true))
|
||||
.arg(arg!(--"global-str" <str>).required(false).global(true))
|
||||
.subcommand(
|
||||
Command::new("test")
|
||||
.arg(arg!(--"sub-flag").global(true))
|
||||
.arg(arg!(--"sub-str" <str>).required(false).global(true))
|
||||
.subcommand(Command::new("test")),
|
||||
)
|
||||
.try_get_matches_from(&[
|
||||
"cmd",
|
||||
"test",
|
||||
"test",
|
||||
"--global-flag",
|
||||
"--global-str",
|
||||
"hello",
|
||||
"--sub-flag",
|
||||
"--sub-str",
|
||||
"world",
|
||||
])
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
Some("world"),
|
||||
m.subcommand_matches("test").unwrap().value_of("sub-str")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_arg_available_in_subcommand() {
|
||||
let m = Command::new("opt")
|
||||
.args(&[
|
||||
Arg::new("global").global(true).long("global"),
|
||||
Arg::new("not").global(false).long("not"),
|
||||
])
|
||||
.subcommand(Command::new("ping"))
|
||||
.try_get_matches_from(&["opt", "ping", "--global"])
|
||||
.unwrap();
|
||||
|
||||
assert!(m.is_present("global"));
|
||||
assert!(m.subcommand_matches("ping").unwrap().is_present("global"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deeply_nested_discovery() {
|
||||
let cmd = Command::new("a")
|
||||
.arg(arg!(--"long-a").global(true))
|
||||
.subcommand(
|
||||
Command::new("b")
|
||||
.arg(arg!(--"long-b").global(true))
|
||||
.subcommand(
|
||||
Command::new("c")
|
||||
.arg(arg!(--"long-c").global(true))
|
||||
.subcommand(Command::new("d")),
|
||||
),
|
||||
);
|
||||
|
||||
let m = cmd
|
||||
.try_get_matches_from(["a", "b", "c", "d", "--long-a", "--long-b", "--long-c"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("long-a"));
|
||||
let m = m.subcommand_matches("b").unwrap();
|
||||
assert!(m.is_present("long-b"));
|
||||
let m = m.subcommand_matches("c").unwrap();
|
||||
assert!(m.is_present("long-c"));
|
||||
}
|
|
@ -1,221 +0,0 @@
|
|||
#![cfg(feature = "unstable-grouped")]
|
||||
|
||||
use clap::{Arg, Command};
|
||||
|
||||
#[test]
|
||||
fn grouped_value_works() {
|
||||
let m = Command::new("cli")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.multiple_values(true)
|
||||
.multiple_occurrences(true),
|
||||
)
|
||||
.try_get_matches_from(&[
|
||||
"cli",
|
||||
"--option",
|
||||
"fr_FR:mon option 1",
|
||||
"en_US:my option 1",
|
||||
"--option",
|
||||
"fr_FR:mon option 2",
|
||||
"en_US:my option 2",
|
||||
])
|
||||
.unwrap();
|
||||
let grouped_vals: Vec<_> = m.grouped_values_of("option").unwrap().collect();
|
||||
assert_eq!(
|
||||
grouped_vals,
|
||||
vec![
|
||||
vec!["fr_FR:mon option 1", "en_US:my option 1",],
|
||||
vec!["fr_FR:mon option 2", "en_US:my option 2",],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1026() {
|
||||
let m = Command::new("cli")
|
||||
.arg(Arg::new("server").short('s').takes_value(true))
|
||||
.arg(Arg::new("user").short('u').takes_value(true))
|
||||
.arg(
|
||||
Arg::new("target")
|
||||
.long("target")
|
||||
.takes_value(true)
|
||||
.multiple_values(true)
|
||||
.multiple_occurrences(true),
|
||||
)
|
||||
.try_get_matches_from(&[
|
||||
"backup", "-s", "server", "-u", "user", "--target", "target1", "file1", "file2",
|
||||
"file3", "--target", "target2", "file4", "file5", "file6", "file7", "--target",
|
||||
"target3", "file8",
|
||||
])
|
||||
.unwrap();
|
||||
let grouped_vals: Vec<_> = m.grouped_values_of("target").unwrap().collect();
|
||||
assert_eq!(
|
||||
grouped_vals,
|
||||
vec![
|
||||
vec!["target1", "file1", "file2", "file3"],
|
||||
vec!["target2", "file4", "file5", "file6", "file7",],
|
||||
vec!["target3", "file8"]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grouped_value_long_flag_delimiter() {
|
||||
let m = Command::new("myapp")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.use_value_delimiter(true)
|
||||
.multiple_values(true)
|
||||
.multiple_occurrences(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
"myapp",
|
||||
"--option=hmm",
|
||||
"--option=val1,val2,val3",
|
||||
"--option",
|
||||
"alice,bob",
|
||||
])
|
||||
.unwrap();
|
||||
let grouped_vals: Vec<_> = m.grouped_values_of("option").unwrap().collect();
|
||||
assert_eq!(
|
||||
grouped_vals,
|
||||
vec![
|
||||
vec!["hmm"],
|
||||
vec!["val1", "val2", "val3"],
|
||||
vec!["alice", "bob"]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grouped_value_short_flag_delimiter() {
|
||||
let m = Command::new("myapp")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.takes_value(true)
|
||||
.use_value_delimiter(true)
|
||||
.multiple_values(true)
|
||||
.multiple_occurrences(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["myapp", "-o=foo", "-o=val1,val2,val3", "-o=bar"])
|
||||
.unwrap();
|
||||
let grouped_vals: Vec<_> = m.grouped_values_of("option").unwrap().collect();
|
||||
assert_eq!(
|
||||
grouped_vals,
|
||||
vec![vec!["foo"], vec!["val1", "val2", "val3"], vec!["bar"]]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grouped_value_positional_arg() {
|
||||
let m = Command::new("multiple_values")
|
||||
.arg(
|
||||
Arg::new("pos")
|
||||
.help("multiple positionals")
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
"myprog", "val1", "val2", "val3", "val4", "val5", "val6",
|
||||
])
|
||||
.unwrap();
|
||||
let grouped_vals: Vec<_> = m.grouped_values_of("pos").unwrap().collect();
|
||||
assert_eq!(
|
||||
grouped_vals,
|
||||
vec![vec!["val1", "val2", "val3", "val4", "val5", "val6"]]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grouped_value_multiple_positional_arg() {
|
||||
let m = Command::new("multiple_values")
|
||||
.arg(Arg::new("pos1").help("multiple positionals"))
|
||||
.arg(
|
||||
Arg::new("pos2")
|
||||
.help("multiple positionals")
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
"myprog", "val1", "val2", "val3", "val4", "val5", "val6",
|
||||
])
|
||||
.unwrap();
|
||||
let grouped_vals: Vec<_> = m.grouped_values_of("pos2").unwrap().collect();
|
||||
assert_eq!(
|
||||
grouped_vals,
|
||||
vec![vec!["val2", "val3", "val4", "val5", "val6"]]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grouped_value_multiple_positional_arg_last_multiple() {
|
||||
let m = Command::new("multiple_values")
|
||||
.arg(Arg::new("pos1").help("multiple positionals"))
|
||||
.arg(
|
||||
Arg::new("pos2")
|
||||
.help("multiple positionals")
|
||||
.takes_value(true)
|
||||
.multiple_values(true)
|
||||
.last(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
"myprog", "val1", "--", "val2", "val3", "val4", "val5", "val6",
|
||||
])
|
||||
.unwrap();
|
||||
let grouped_vals: Vec<_> = m.grouped_values_of("pos2").unwrap().collect();
|
||||
assert_eq!(
|
||||
grouped_vals,
|
||||
vec![vec!["val2", "val3", "val4", "val5", "val6"]]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1374() {
|
||||
let cmd = Command::new("MyApp").arg(
|
||||
Arg::new("input")
|
||||
.takes_value(true)
|
||||
.long("input")
|
||||
.overrides_with("input")
|
||||
.min_values(0)
|
||||
.multiple_occurrences(true),
|
||||
);
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["MyApp", "--input", "a", "b", "c", "--input", "d"])
|
||||
.unwrap();
|
||||
let vs = matches.values_of("input").unwrap();
|
||||
assert_eq!(vs.collect::<Vec<_>>(), vec!["a", "b", "c", "d"]);
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["MyApp", "--input", "a", "b", "--input", "c", "d"])
|
||||
.unwrap();
|
||||
let vs = matches.values_of("input").unwrap();
|
||||
assert_eq!(vs.collect::<Vec<_>>(), vec!["a", "b", "c", "d"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_2171() {
|
||||
let schema = Command::new("ripgrep#1701 reproducer")
|
||||
.args_override_self(true)
|
||||
.arg(Arg::new("pretty").short('p').long("pretty"))
|
||||
.arg(Arg::new("search_zip").short('z').long("search-zip"));
|
||||
|
||||
let test_args = &[
|
||||
vec!["reproducer", "-pz", "-p"],
|
||||
vec!["reproducer", "-pzp"],
|
||||
vec!["reproducer", "-zpp"],
|
||||
vec!["reproducer", "-pp", "-z"],
|
||||
vec!["reproducer", "-p", "-p", "-z"],
|
||||
vec!["reproducer", "-p", "-pz"],
|
||||
vec!["reproducer", "-ppz"],
|
||||
];
|
||||
|
||||
for argv in test_args {
|
||||
let _ = schema.clone().try_get_matches_from(argv).unwrap();
|
||||
}
|
||||
}
|
|
@ -1,325 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use clap::{arg, error::ErrorKind, Arg, ArgGroup, Command};
|
||||
|
||||
static REQ_GROUP_USAGE: &str = "error: The following required arguments were not provided:
|
||||
<base|--delete>
|
||||
|
||||
USAGE:
|
||||
clap-test <base|--delete>
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
static REQ_GROUP_CONFLICT_USAGE: &str =
|
||||
"error: The argument '--delete' cannot be used with '<base>'
|
||||
|
||||
USAGE:
|
||||
clap-test <base|--delete>
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
static REQ_GROUP_CONFLICT_ONLY_OPTIONS: &str =
|
||||
"error: The argument '--delete' cannot be used with '--all'
|
||||
|
||||
USAGE:
|
||||
clap-test <--all|--delete>
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn required_group_missing_arg() {
|
||||
let result = Command::new("group")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.arg(arg!( -c --color "some other flag"))
|
||||
.group(ArgGroup::new("req").args(&["flag", "color"]).required(true))
|
||||
.try_get_matches_from(vec![""]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument group 'req' contains non-existent argument"]
|
||||
fn non_existing_arg() {
|
||||
let _ = Command::new("group")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.arg(arg!(-c --color "some other flag"))
|
||||
.group(ArgGroup::new("req").args(&["flg", "color"]).required(true))
|
||||
.try_get_matches_from(vec![""]);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument group name must be unique\n\n\t'req' is already in use"]
|
||||
fn unique_group_name() {
|
||||
let _ = Command::new("group")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.arg(arg!(-c --color "some other flag"))
|
||||
.group(ArgGroup::new("req").args(&["flag"]).required(true))
|
||||
.group(ArgGroup::new("req").args(&["color"]).required(true))
|
||||
.try_get_matches_from(vec![""]);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument group name '' must not conflict with argument name"]
|
||||
fn groups_new_of_arg_name() {
|
||||
let _ = Command::new("group")
|
||||
.arg(Arg::new("a").long("a").group("a"))
|
||||
.try_get_matches_from(vec!["", "--a"]);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument group name 'a' must not conflict with argument name"]
|
||||
fn arg_group_new_of_arg_name() {
|
||||
let _ = Command::new("group")
|
||||
.arg(Arg::new("a").long("a").group("a"))
|
||||
.group(ArgGroup::new("a"))
|
||||
.try_get_matches_from(vec!["", "--a"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_single_value() {
|
||||
let res = Command::new("group")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.arg(arg!(-c --color [color] "some option"))
|
||||
.group(ArgGroup::new("grp").args(&["flag", "color"]))
|
||||
.try_get_matches_from(vec!["", "-c", "blue"]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("grp"));
|
||||
assert_eq!(m.value_of("grp").unwrap(), "blue");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_single_flag() {
|
||||
let res = Command::new("group")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.arg(arg!(-c --color [color] "some option"))
|
||||
.group(ArgGroup::new("grp").args(&["flag", "color"]))
|
||||
.try_get_matches_from(vec!["", "-f"]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("grp"));
|
||||
assert!(m.value_of("grp").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_empty() {
|
||||
let res = Command::new("group")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.arg(arg!(-c --color [color] "some option"))
|
||||
.group(ArgGroup::new("grp").args(&["flag", "color"]))
|
||||
.try_get_matches_from(vec![""]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
|
||||
let m = res.unwrap();
|
||||
assert!(!m.is_present("grp"));
|
||||
assert!(m.value_of("grp").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_reqired_flags_empty() {
|
||||
let result = Command::new("group")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.arg(arg!(-c --color "some option"))
|
||||
.group(ArgGroup::new("grp").required(true).args(&["flag", "color"]))
|
||||
.try_get_matches_from(vec![""]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_multi_value_single_arg() {
|
||||
let res = Command::new("group")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.arg(arg!(-c --color <color> "some option").multiple_values(true))
|
||||
.group(ArgGroup::new("grp").args(&["flag", "color"]))
|
||||
.try_get_matches_from(vec!["", "-c", "blue", "red", "green"]);
|
||||
assert!(res.is_ok(), "{:?}", res.unwrap_err().kind());
|
||||
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("grp"));
|
||||
assert_eq!(
|
||||
&*m.values_of("grp").unwrap().collect::<Vec<_>>(),
|
||||
&["blue", "red", "green"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_group() {
|
||||
let r = Command::new("empty_group")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.group(ArgGroup::new("vers").required(true))
|
||||
.try_get_matches_from(vec!["empty_prog"]);
|
||||
assert!(r.is_err());
|
||||
let err = r.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn req_group_usage_string() {
|
||||
let cmd = Command::new("req_group")
|
||||
.arg(arg!([base] "Base commit"))
|
||||
.arg(arg!(
|
||||
-d --delete "Remove the base commit information"
|
||||
))
|
||||
.group(
|
||||
ArgGroup::new("base_or_delete")
|
||||
.args(&["base", "delete"])
|
||||
.required(true),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "clap-test", REQ_GROUP_USAGE, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn req_group_with_conflict_usage_string() {
|
||||
let cmd = Command::new("req_group")
|
||||
.arg(arg!([base] "Base commit").conflicts_with("delete"))
|
||||
.arg(arg!(
|
||||
-d --delete "Remove the base commit information"
|
||||
))
|
||||
.group(
|
||||
ArgGroup::new("base_or_delete")
|
||||
.args(&["base", "delete"])
|
||||
.required(true),
|
||||
);
|
||||
|
||||
utils::assert_output(
|
||||
cmd,
|
||||
"clap-test --delete base",
|
||||
REQ_GROUP_CONFLICT_USAGE,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn req_group_with_conflict_usage_string_only_options() {
|
||||
let cmd = Command::new("req_group")
|
||||
.arg(arg!(-a --all "All").conflicts_with("delete"))
|
||||
.arg(arg!(
|
||||
-d --delete "Remove the base commit information"
|
||||
))
|
||||
.group(
|
||||
ArgGroup::new("all_or_delete")
|
||||
.args(&["all", "delete"])
|
||||
.required(true),
|
||||
);
|
||||
utils::assert_output(
|
||||
cmd,
|
||||
"clap-test --delete --all",
|
||||
REQ_GROUP_CONFLICT_ONLY_OPTIONS,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn required_group_multiple_args() {
|
||||
let result = Command::new("group")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.arg(arg!(-c --color "some other flag"))
|
||||
.group(
|
||||
ArgGroup::new("req")
|
||||
.args(&["flag", "color"])
|
||||
.required(true)
|
||||
.multiple(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["group", "-f", "-c"]);
|
||||
assert!(result.is_ok(), "{}", result.unwrap_err());
|
||||
let m = result.unwrap();
|
||||
assert!(m.is_present("flag"));
|
||||
assert!(m.is_present("color"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_multiple_args_error() {
|
||||
let result = Command::new("group")
|
||||
.arg(arg!(-f --flag "some flag"))
|
||||
.arg(arg!(-c --color "some other flag"))
|
||||
.group(ArgGroup::new("req").args(&["flag", "color"]))
|
||||
.try_get_matches_from(vec!["group", "-f", "-c"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_overrides_required() {
|
||||
let command = Command::new("group")
|
||||
.arg(arg!(--foo <FOO>))
|
||||
.arg(arg!(--bar <BAR>))
|
||||
.group(ArgGroup::new("group").args(&["foo", "bar"]).required(true));
|
||||
let result = command.try_get_matches_from(vec!["group", "--foo", "value"]);
|
||||
assert!(result.is_ok(), "{}", result.unwrap_err());
|
||||
let m = result.unwrap();
|
||||
assert!(m.is_present("foo"));
|
||||
assert!(!m.is_present("bar"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_usage_use_val_name() {
|
||||
static GROUP_USAGE_USE_VAL_NAME: &str = "prog
|
||||
|
||||
USAGE:
|
||||
prog <A>
|
||||
|
||||
ARGS:
|
||||
<A>
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
";
|
||||
let cmd = Command::new("prog")
|
||||
.arg(Arg::new("a").value_name("A"))
|
||||
.group(ArgGroup::new("group").arg("a").required(true));
|
||||
utils::assert_output(cmd, "prog --help", GROUP_USAGE_USE_VAL_NAME, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_acts_like_arg() {
|
||||
let result = Command::new("prog")
|
||||
.arg(Arg::new("debug").long("debug").group("mode"))
|
||||
.arg(Arg::new("verbose").long("verbose").group("mode"))
|
||||
.try_get_matches_from(vec!["prog", "--debug"]);
|
||||
|
||||
assert!(result.is_ok(), "{}", result.unwrap_err());
|
||||
let m = result.unwrap();
|
||||
assert!(m.is_present("mode"));
|
||||
}
|
||||
|
||||
/* This is used to be fixed in a hack, we need to find a better way to fix it.
|
||||
#[test]
|
||||
fn issue_1794() {
|
||||
let cmd = clap::Command::new("hello")
|
||||
.bin_name("deno")
|
||||
.arg(Arg::new("option1").long("option1").takes_value(false))
|
||||
.arg(Arg::new("pos1").takes_value(true))
|
||||
.arg(Arg::new("pos2").takes_value(true))
|
||||
.group(
|
||||
ArgGroup::new("arg1")
|
||||
.args(&["pos1", "option1"])
|
||||
.required(true),
|
||||
);
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(&["cmd", "pos1", "pos2"]).unwrap();
|
||||
assert_eq!(m.value_of("pos1"), Some("pos1"));
|
||||
assert_eq!(m.value_of("pos2"), Some("pos2"));
|
||||
assert!(!m.is_present("option1"));
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["cmd", "--option1", "positional"]).unwrap();
|
||||
assert_eq!(m.value_of("pos1"), None);
|
||||
assert_eq!(m.value_of("pos2"), Some("positional"));
|
||||
assert!(m.is_present("option1"));
|
||||
}
|
||||
*/
|
File diff suppressed because it is too large
Load diff
|
@ -1,227 +0,0 @@
|
|||
#![cfg(feature = "env")]
|
||||
|
||||
use std::env;
|
||||
|
||||
use clap::{Arg, Command};
|
||||
|
||||
use super::utils;
|
||||
|
||||
static HIDE_ENV: &str = "ctest 0.1
|
||||
|
||||
USAGE:
|
||||
ctest [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-c, --cafe <FILE> A coffeehouse, coffee shop, or café.
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static SHOW_ENV: &str = "ctest 0.1
|
||||
|
||||
USAGE:
|
||||
ctest [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-c, --cafe <FILE> A coffeehouse, coffee shop, or café. [env: ENVVAR=MYVAL]
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static HIDE_ENV_VALS: &str = "ctest 0.1
|
||||
|
||||
USAGE:
|
||||
ctest [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-c, --cafe <FILE> A coffeehouse, coffee shop, or café. [env: ENVVAR]
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static SHOW_ENV_VALS: &str = "ctest 0.1
|
||||
|
||||
USAGE:
|
||||
ctest [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-c, --cafe <FILE> A coffeehouse, coffee shop, or café. [env: ENVVAR=MYVAL]
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static HIDE_ENV_FLAG: &str = "ctest 0.1
|
||||
|
||||
USAGE:
|
||||
ctest [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-c, --cafe A coffeehouse, coffee shop, or café.
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static SHOW_ENV_FLAG: &str = "ctest 0.1
|
||||
|
||||
USAGE:
|
||||
ctest [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-c, --cafe A coffeehouse, coffee shop, or café. [env: ENVVAR=MYVAL]
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static HIDE_ENV_VALS_FLAG: &str = "ctest 0.1
|
||||
|
||||
USAGE:
|
||||
ctest [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-c, --cafe A coffeehouse, coffee shop, or café. [env: ENVVAR]
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static SHOW_ENV_VALS_FLAG: &str = "ctest 0.1
|
||||
|
||||
USAGE:
|
||||
ctest [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-c, --cafe A coffeehouse, coffee shop, or café. [env: ENVVAR=MYVAL]
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn hide_env() {
|
||||
env::set_var("ENVVAR", "MYVAL");
|
||||
|
||||
let cmd = Command::new("ctest").version("0.1").arg(
|
||||
Arg::new("cafe")
|
||||
.short('c')
|
||||
.long("cafe")
|
||||
.value_name("FILE")
|
||||
.hide_env(true)
|
||||
.env("ENVVAR")
|
||||
.help("A coffeehouse, coffee shop, or café.")
|
||||
.takes_value(true),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "ctest --help", HIDE_ENV, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn show_env() {
|
||||
env::set_var("ENVVAR", "MYVAL");
|
||||
|
||||
let cmd = Command::new("ctest").version("0.1").arg(
|
||||
Arg::new("cafe")
|
||||
.short('c')
|
||||
.long("cafe")
|
||||
.value_name("FILE")
|
||||
.env("ENVVAR")
|
||||
.help("A coffeehouse, coffee shop, or café.")
|
||||
.takes_value(true),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "ctest --help", SHOW_ENV, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hide_env_vals() {
|
||||
env::set_var("ENVVAR", "MYVAL");
|
||||
|
||||
let cmd = Command::new("ctest").version("0.1").arg(
|
||||
Arg::new("cafe")
|
||||
.short('c')
|
||||
.long("cafe")
|
||||
.value_name("FILE")
|
||||
.hide_env_values(true)
|
||||
.env("ENVVAR")
|
||||
.help("A coffeehouse, coffee shop, or café.")
|
||||
.takes_value(true),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "ctest --help", HIDE_ENV_VALS, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn show_env_vals() {
|
||||
env::set_var("ENVVAR", "MYVAL");
|
||||
|
||||
let cmd = Command::new("ctest").version("0.1").arg(
|
||||
Arg::new("cafe")
|
||||
.short('c')
|
||||
.long("cafe")
|
||||
.value_name("FILE")
|
||||
.env("ENVVAR")
|
||||
.help("A coffeehouse, coffee shop, or café.")
|
||||
.takes_value(true),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "ctest --help", SHOW_ENV_VALS, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hide_env_flag() {
|
||||
env::set_var("ENVVAR", "MYVAL");
|
||||
|
||||
let cmd = Command::new("ctest").version("0.1").arg(
|
||||
Arg::new("cafe")
|
||||
.short('c')
|
||||
.long("cafe")
|
||||
.hide_env(true)
|
||||
.env("ENVVAR")
|
||||
.help("A coffeehouse, coffee shop, or café."),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "ctest --help", HIDE_ENV_FLAG, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn show_env_flag() {
|
||||
env::set_var("ENVVAR", "MYVAL");
|
||||
|
||||
let cmd = Command::new("ctest").version("0.1").arg(
|
||||
Arg::new("cafe")
|
||||
.short('c')
|
||||
.long("cafe")
|
||||
.env("ENVVAR")
|
||||
.help("A coffeehouse, coffee shop, or café."),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "ctest --help", SHOW_ENV_FLAG, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hide_env_vals_flag() {
|
||||
env::set_var("ENVVAR", "MYVAL");
|
||||
|
||||
let cmd = Command::new("ctest").version("0.1").arg(
|
||||
Arg::new("cafe")
|
||||
.short('c')
|
||||
.long("cafe")
|
||||
.hide_env_values(true)
|
||||
.env("ENVVAR")
|
||||
.help("A coffeehouse, coffee shop, or café."),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "ctest --help", HIDE_ENV_VALS_FLAG, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn show_env_vals_flag() {
|
||||
env::set_var("ENVVAR", "MYVAL");
|
||||
|
||||
let cmd = Command::new("ctest").version("0.1").arg(
|
||||
Arg::new("cafe")
|
||||
.short('c')
|
||||
.long("cafe")
|
||||
.env("ENVVAR")
|
||||
.help("A coffeehouse, coffee shop, or café."),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "ctest --help", SHOW_ENV_VALS_FLAG, false);
|
||||
}
|
|
@ -1,290 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use clap::{arg, Arg, Command};
|
||||
|
||||
static HIDDEN_ARGS: &str = "test 1.4
|
||||
Kevin K.
|
||||
tests stuff
|
||||
|
||||
USAGE:
|
||||
test [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-F, --flag2 some other flag
|
||||
-h, --help Print help information
|
||||
--option <opt> some option
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn hide_args() {
|
||||
let cmd = Command::new("test")
|
||||
.author("Kevin K.")
|
||||
.about("tests stuff")
|
||||
.version("1.4")
|
||||
.args(&[
|
||||
arg!(-f --flag "some flag").hide(true),
|
||||
arg!(-F --flag2 "some other flag"),
|
||||
arg!(--option <opt> "some option").required(false),
|
||||
Arg::new("DUMMY").hide(true),
|
||||
]);
|
||||
utils::assert_output(cmd, "test --help", HIDDEN_ARGS, false);
|
||||
}
|
||||
|
||||
static HIDDEN_SHORT_ARGS: &str = "test 2.31.2
|
||||
Steve P.
|
||||
hides short args
|
||||
|
||||
USAGE:
|
||||
test [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-v, --visible This text should be visible
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
static HIDDEN_SHORT_ARGS_LONG_HELP: &str = "test 2.31.2
|
||||
Steve P.
|
||||
hides short args
|
||||
|
||||
USAGE:
|
||||
test [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-c, --config
|
||||
Some help text describing the --config arg
|
||||
|
||||
-h, --help
|
||||
Print help information
|
||||
|
||||
-v, --visible
|
||||
This text should be visible
|
||||
|
||||
-V, --version
|
||||
Print version information
|
||||
";
|
||||
|
||||
/// Ensure hide with short option
|
||||
#[test]
|
||||
fn hide_short_args() {
|
||||
let cmd = Command::new("test")
|
||||
.about("hides short args")
|
||||
.author("Steve P.")
|
||||
.version("2.31.2")
|
||||
.args(&[
|
||||
Arg::new("cfg")
|
||||
.short('c')
|
||||
.long("config")
|
||||
.hide_short_help(true)
|
||||
.help("Some help text describing the --config arg"),
|
||||
Arg::new("visible")
|
||||
.short('v')
|
||||
.long("visible")
|
||||
.help("This text should be visible"),
|
||||
]);
|
||||
|
||||
utils::assert_output(cmd, "test -h", HIDDEN_SHORT_ARGS, false);
|
||||
}
|
||||
|
||||
/// Ensure visible with opposite option
|
||||
#[test]
|
||||
fn hide_short_args_long_help() {
|
||||
let cmd = Command::new("test")
|
||||
.about("hides short args")
|
||||
.author("Steve P.")
|
||||
.version("2.31.2")
|
||||
.args(&[
|
||||
Arg::new("cfg")
|
||||
.short('c')
|
||||
.long("config")
|
||||
.hide_short_help(true)
|
||||
.help("Some help text describing the --config arg"),
|
||||
Arg::new("visible")
|
||||
.short('v')
|
||||
.long("visible")
|
||||
.help("This text should be visible"),
|
||||
]);
|
||||
|
||||
utils::assert_output(cmd, "test --help", HIDDEN_SHORT_ARGS_LONG_HELP, false);
|
||||
}
|
||||
|
||||
static HIDDEN_LONG_ARGS: &str = "test 2.31.2
|
||||
Steve P.
|
||||
hides long args
|
||||
|
||||
USAGE:
|
||||
test [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-h, --help
|
||||
Print help information
|
||||
|
||||
-v, --visible
|
||||
This text should be visible
|
||||
|
||||
-V, --version
|
||||
Print version information
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn hide_long_args() {
|
||||
let cmd = Command::new("test")
|
||||
.about("hides long args")
|
||||
.author("Steve P.")
|
||||
.version("2.31.2")
|
||||
.args(&[
|
||||
Arg::new("cfg")
|
||||
.short('c')
|
||||
.long("config")
|
||||
.hide_long_help(true)
|
||||
.help("Some help text describing the --config arg"),
|
||||
Arg::new("visible")
|
||||
.short('v')
|
||||
.long("visible")
|
||||
.help("This text should be visible"),
|
||||
]);
|
||||
|
||||
utils::assert_output(cmd, "test --help", HIDDEN_LONG_ARGS, false);
|
||||
}
|
||||
|
||||
static HIDDEN_LONG_ARGS_SHORT_HELP: &str = "test 2.31.2
|
||||
Steve P.
|
||||
hides long args
|
||||
|
||||
USAGE:
|
||||
test [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
-c, --config Some help text describing the --config arg
|
||||
-h, --help Print help information
|
||||
-v, --visible This text should be visible
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn hide_long_args_short_help() {
|
||||
let cmd = Command::new("test")
|
||||
.about("hides long args")
|
||||
.author("Steve P.")
|
||||
.version("2.31.2")
|
||||
.args(&[
|
||||
Arg::new("cfg")
|
||||
.short('c')
|
||||
.long("config")
|
||||
.hide_long_help(true)
|
||||
.help("Some help text describing the --config arg"),
|
||||
Arg::new("visible")
|
||||
.short('v')
|
||||
.long("visible")
|
||||
.help("This text should be visible"),
|
||||
]);
|
||||
|
||||
utils::assert_output(cmd, "test -h", HIDDEN_LONG_ARGS_SHORT_HELP, false);
|
||||
}
|
||||
|
||||
static HIDDEN_POS_ARGS: &str = "test 1.4
|
||||
|
||||
USAGE:
|
||||
test [another]
|
||||
|
||||
ARGS:
|
||||
<another> another pos
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn hide_pos_args() {
|
||||
let cmd = Command::new("test").version("1.4").args(&[
|
||||
Arg::new("pos").help("some pos").hide(true),
|
||||
Arg::new("another").help("another pos"),
|
||||
]);
|
||||
|
||||
utils::assert_output(cmd, "test --help", HIDDEN_POS_ARGS, false);
|
||||
}
|
||||
|
||||
static HIDDEN_SUBCMDS: &str = "test 1.4
|
||||
|
||||
USAGE:
|
||||
test
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn hide_subcmds() {
|
||||
let cmd = Command::new("test")
|
||||
.version("1.4")
|
||||
.subcommand(Command::new("sub").hide(true));
|
||||
|
||||
utils::assert_output(cmd, "test --help", HIDDEN_SUBCMDS, false);
|
||||
}
|
||||
|
||||
static HIDDEN_OPT_ARGS_ONLY: &str = "test 1.4
|
||||
|
||||
USAGE:
|
||||
test
|
||||
|
||||
After help
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn hide_opt_args_only() {
|
||||
let cmd = Command::new("test")
|
||||
.version("1.4")
|
||||
.after_help("After help")
|
||||
.mut_arg("help", |a| a.hide(true))
|
||||
.mut_arg("version", |a| a.hide(true))
|
||||
.arg(
|
||||
arg!(--option <opt> "some option")
|
||||
.required(false)
|
||||
.hide(true),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "test --help", HIDDEN_OPT_ARGS_ONLY, false);
|
||||
}
|
||||
|
||||
static HIDDEN_POS_ARGS_ONLY: &str = "test 1.4
|
||||
|
||||
USAGE:
|
||||
test
|
||||
|
||||
After help
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn hide_pos_args_only() {
|
||||
let cmd = Command::new("test")
|
||||
.version("1.4")
|
||||
.after_help("After help")
|
||||
.mut_arg("help", |a| a.hide(true))
|
||||
.mut_arg("version", |a| a.hide(true))
|
||||
.args(&[Arg::new("pos").help("some pos").hide(true)]);
|
||||
|
||||
utils::assert_output(cmd, "test --help", HIDDEN_POS_ARGS_ONLY, false);
|
||||
}
|
||||
|
||||
static HIDDEN_SUBCMDS_ONLY: &str = "test 1.4
|
||||
|
||||
USAGE:
|
||||
test
|
||||
|
||||
After help
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn hide_subcmds_only() {
|
||||
let cmd = Command::new("test")
|
||||
.version("1.4")
|
||||
.after_help("After help")
|
||||
.mut_arg("help", |a| a.hide(true))
|
||||
.mut_arg("version", |a| a.hide(true))
|
||||
.subcommand(Command::new("sub").hide(true));
|
||||
|
||||
utils::assert_output(cmd, "test --help", HIDDEN_SUBCMDS_ONLY, false);
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
use clap::{arg, Arg, Command};
|
||||
|
||||
#[test]
|
||||
fn single_short_arg_without_value() {
|
||||
let cmd = Command::new("cmd").ignore_errors(true).arg(arg!(
|
||||
-c --config [FILE] "Sets a custom config file"
|
||||
));
|
||||
|
||||
let r = cmd.try_get_matches_from(vec!["cmd", "-c" /* missing: , "config file" */]);
|
||||
|
||||
assert!(r.is_ok(), "unexpected error: {:?}", r);
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("config"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_long_arg_without_value() {
|
||||
let cmd = Command::new("cmd").ignore_errors(true).arg(arg!(
|
||||
-c --config [FILE] "Sets a custom config file"
|
||||
));
|
||||
|
||||
let r = cmd.try_get_matches_from(vec!["cmd", "--config" /* missing: , "config file" */]);
|
||||
|
||||
assert!(r.is_ok(), "unexpected error: {:?}", r);
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("config"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_args_and_final_arg_without_value() {
|
||||
let cmd = Command::new("cmd")
|
||||
.ignore_errors(true)
|
||||
.arg(arg!(
|
||||
-c --config [FILE] "Sets a custom config file"
|
||||
))
|
||||
.arg(arg!(
|
||||
-x --stuff [FILE] "Sets a custom stuff file"
|
||||
))
|
||||
.arg(arg!(f: -f "Flag"));
|
||||
|
||||
let r = cmd.try_get_matches_from(vec![
|
||||
"cmd", "-c", "file", "-f", "-x", /* missing: , "some stuff" */
|
||||
]);
|
||||
|
||||
assert!(r.is_ok(), "unexpected error: {:?}", r);
|
||||
let m = r.unwrap();
|
||||
assert_eq!(m.value_of("config"), Some("file"));
|
||||
assert!(m.is_present("f"));
|
||||
assert_eq!(m.value_of("stuff"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_args_and_intermittent_arg_without_value() {
|
||||
let cmd = Command::new("cmd")
|
||||
.ignore_errors(true)
|
||||
.arg(arg!(
|
||||
-c --config[FILE] "Sets a custom config file"
|
||||
))
|
||||
.arg(arg!(
|
||||
-x --stuff[FILE] "Sets a custom stuff file"
|
||||
))
|
||||
.arg(arg!(f: -f "Flag"));
|
||||
|
||||
let r = cmd.try_get_matches_from(vec![
|
||||
"cmd", "-x", /* missing: ,"some stuff" */
|
||||
"-c", "file", "-f",
|
||||
]);
|
||||
|
||||
assert!(r.is_ok(), "unexpected error: {:?}", r);
|
||||
let m = r.unwrap();
|
||||
assert_eq!(m.value_of("config"), Some("file"));
|
||||
assert!(m.is_present("f"));
|
||||
assert_eq!(m.value_of("stuff"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subcommand() {
|
||||
let cmd = Command::new("test")
|
||||
.ignore_errors(true)
|
||||
.subcommand(
|
||||
Command::new("some")
|
||||
.arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.takes_value(true)
|
||||
.help("testing testing"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("stuff")
|
||||
.short('x')
|
||||
.long("stuff")
|
||||
.takes_value(true)
|
||||
.help("stuf value"),
|
||||
),
|
||||
)
|
||||
.arg(Arg::new("other").long("other"));
|
||||
|
||||
let m = cmd
|
||||
.try_get_matches_from(vec![
|
||||
"myprog",
|
||||
"some",
|
||||
"--test", /* missing: ,"some val" */
|
||||
"-x",
|
||||
"some other val",
|
||||
])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(m.subcommand_name().unwrap(), "some");
|
||||
let sub_m = m.subcommand_matches("some").unwrap();
|
||||
assert!(
|
||||
sub_m.is_present("test"),
|
||||
"expected subcommand to be present due to partial parsing"
|
||||
);
|
||||
assert_eq!(sub_m.value_of("test"), None);
|
||||
assert_eq!(sub_m.value_of("stuff"), Some("some other val"));
|
||||
}
|
|
@ -1,202 +0,0 @@
|
|||
use clap::{Arg, Command};
|
||||
|
||||
#[test]
|
||||
fn indices_mult_opts() {
|
||||
let m = Command::new("ind")
|
||||
.arg(
|
||||
Arg::new("exclude")
|
||||
.short('e')
|
||||
.takes_value(true)
|
||||
.multiple_values(true)
|
||||
.multiple_occurrences(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("include")
|
||||
.short('i')
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["ind", "-e", "A", "B", "-i", "B", "C", "-e", "C"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
m.indices_of("exclude").unwrap().collect::<Vec<_>>(),
|
||||
&[2, 3, 8]
|
||||
);
|
||||
assert_eq!(
|
||||
m.indices_of("include").unwrap().collect::<Vec<_>>(),
|
||||
&[5, 6]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn index_mult_opts() {
|
||||
let m = Command::new("ind")
|
||||
.arg(
|
||||
Arg::new("exclude")
|
||||
.short('e')
|
||||
.takes_value(true)
|
||||
.multiple_values(true)
|
||||
.multiple_occurrences(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("include")
|
||||
.short('i')
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["ind", "-e", "A", "B", "-i", "B", "C", "-e", "C"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(m.index_of("exclude"), Some(2));
|
||||
assert_eq!(m.index_of("include"), Some(5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn index_flag() {
|
||||
let m = Command::new("ind")
|
||||
.arg(Arg::new("exclude").short('e'))
|
||||
.arg(Arg::new("include").short('i'))
|
||||
.try_get_matches_from(vec!["ind", "-e", "-i"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(m.index_of("exclude"), Some(1));
|
||||
assert_eq!(m.index_of("include"), Some(2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn index_flags() {
|
||||
let m = Command::new("ind")
|
||||
.arg(Arg::new("exclude").short('e').multiple_occurrences(true))
|
||||
.arg(Arg::new("include").short('i').multiple_occurrences(true))
|
||||
.try_get_matches_from(vec!["ind", "-e", "-i", "-e", "-e", "-i"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(m.index_of("exclude"), Some(1));
|
||||
assert_eq!(m.index_of("include"), Some(2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indices_mult_flags() {
|
||||
let m = Command::new("ind")
|
||||
.arg(Arg::new("exclude").short('e').multiple_occurrences(true))
|
||||
.arg(Arg::new("include").short('i').multiple_occurrences(true))
|
||||
.try_get_matches_from(vec!["ind", "-e", "-i", "-e", "-e", "-i"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
m.indices_of("exclude").unwrap().collect::<Vec<_>>(),
|
||||
&[1, 3, 4]
|
||||
);
|
||||
assert_eq!(
|
||||
m.indices_of("include").unwrap().collect::<Vec<_>>(),
|
||||
&[2, 5]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indices_mult_flags_combined() {
|
||||
let m = Command::new("ind")
|
||||
.arg(Arg::new("exclude").short('e').multiple_occurrences(true))
|
||||
.arg(Arg::new("include").short('i').multiple_occurrences(true))
|
||||
.try_get_matches_from(vec!["ind", "-eieei"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
m.indices_of("exclude").unwrap().collect::<Vec<_>>(),
|
||||
&[1, 3, 4]
|
||||
);
|
||||
assert_eq!(
|
||||
m.indices_of("include").unwrap().collect::<Vec<_>>(),
|
||||
&[2, 5]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indices_mult_flags_opt_combined() {
|
||||
let m = Command::new("ind")
|
||||
.arg(Arg::new("exclude").short('e').multiple_occurrences(true))
|
||||
.arg(Arg::new("include").short('i').multiple_occurrences(true))
|
||||
.arg(Arg::new("option").short('o').takes_value(true))
|
||||
.try_get_matches_from(vec!["ind", "-eieeio", "val"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
m.indices_of("exclude").unwrap().collect::<Vec<_>>(),
|
||||
&[1, 3, 4]
|
||||
);
|
||||
assert_eq!(
|
||||
m.indices_of("include").unwrap().collect::<Vec<_>>(),
|
||||
&[2, 5]
|
||||
);
|
||||
assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[7]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indices_mult_flags_opt_combined_eq() {
|
||||
let m = Command::new("ind")
|
||||
.arg(Arg::new("exclude").short('e').multiple_occurrences(true))
|
||||
.arg(Arg::new("include").short('i').multiple_occurrences(true))
|
||||
.arg(Arg::new("option").short('o').takes_value(true))
|
||||
.try_get_matches_from(vec!["ind", "-eieeio=val"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
m.indices_of("exclude").unwrap().collect::<Vec<_>>(),
|
||||
&[1, 3, 4]
|
||||
);
|
||||
assert_eq!(
|
||||
m.indices_of("include").unwrap().collect::<Vec<_>>(),
|
||||
&[2, 5]
|
||||
);
|
||||
assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[7]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indices_mult_opt_value_delim_eq() {
|
||||
let m = Command::new("myapp")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.takes_value(true)
|
||||
.use_value_delimiter(true)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["myapp", "-o=val1,val2,val3"])
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
m.indices_of("option").unwrap().collect::<Vec<_>>(),
|
||||
&[2, 3, 4]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indices_mult_opt_value_no_delim_eq() {
|
||||
let m = Command::new("myapp")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["myapp", "-o=val1,val2,val3"])
|
||||
.unwrap();
|
||||
assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indices_mult_opt_mult_flag() {
|
||||
let m = Command::new("myapp")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.takes_value(true)
|
||||
.multiple_occurrences(true),
|
||||
)
|
||||
.arg(Arg::new("flag").short('f').multiple_occurrences(true))
|
||||
.try_get_matches_from(vec!["myapp", "-o", "val1", "-f", "-o", "val2", "-f"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 5]);
|
||||
assert_eq!(m.indices_of("flag").unwrap().collect::<Vec<_>>(), &[3, 6]);
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
#![allow(deprecated)]
|
||||
#![cfg(not(feature = "unstable-v4"))]
|
||||
|
||||
mod app_from_crate;
|
||||
mod app_settings;
|
||||
mod arg_aliases;
|
||||
mod arg_aliases_short;
|
||||
mod arg_matcher_assertions;
|
||||
mod arg_settings;
|
||||
mod borrowed;
|
||||
mod cargo;
|
||||
mod command;
|
||||
mod conflicts;
|
||||
mod default_missing_vals;
|
||||
mod default_vals;
|
||||
mod delimiters;
|
||||
mod derive_order;
|
||||
mod display_order;
|
||||
mod double_require;
|
||||
mod empty_values;
|
||||
mod env;
|
||||
mod error;
|
||||
mod flag_subcommands;
|
||||
mod flags;
|
||||
mod global_args;
|
||||
mod grouped_values;
|
||||
mod groups;
|
||||
mod help;
|
||||
mod help_env;
|
||||
mod hidden_args;
|
||||
mod ignore_errors;
|
||||
mod indices;
|
||||
mod multiple_occurrences;
|
||||
mod multiple_values;
|
||||
mod opts;
|
||||
mod positionals;
|
||||
mod posix_compatible;
|
||||
mod possible_values;
|
||||
mod propagate_globals;
|
||||
mod regex;
|
||||
mod require;
|
||||
mod subcommands;
|
||||
mod template_help;
|
||||
mod tests;
|
||||
mod unicode;
|
||||
mod unique_args;
|
||||
mod utf16;
|
||||
mod utf8;
|
||||
mod utils;
|
||||
mod validators;
|
||||
mod version;
|
|
@ -1,241 +0,0 @@
|
|||
use clap::{arg, error::ErrorKind, Arg, Command};
|
||||
|
||||
#[test]
|
||||
fn multiple_occurrences_of_flags_long() {
|
||||
let m = Command::new("mo_flags_long")
|
||||
.arg(arg!(--multflag "allowed multiple flag").multiple_occurrences(true))
|
||||
.arg(arg!(--flag "disallowed multiple flag"))
|
||||
.try_get_matches_from(vec!["", "--multflag", "--flag", "--multflag"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("multflag"));
|
||||
assert_eq!(m.occurrences_of("multflag"), 2);
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.occurrences_of("flag"), 1)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_occurrences_of_flags_short() {
|
||||
let m = Command::new("mo_flags_short")
|
||||
.arg(arg!(-m --multflag "allowed multiple flag").multiple_occurrences(true))
|
||||
.arg(arg!(-f --flag "disallowed multiple flag"))
|
||||
.try_get_matches_from(vec!["", "-m", "-f", "-m"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("multflag"));
|
||||
assert_eq!(m.occurrences_of("multflag"), 2);
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.occurrences_of("flag"), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_occurrences_of_flags_mixed() {
|
||||
let m = Command::new("mo_flags_mixed")
|
||||
.arg(arg!(-m --multflag1 "allowed multiple flag").multiple_occurrences(true))
|
||||
.arg(arg!(-n --multflag2 "another allowed multiple flag").multiple_occurrences(true))
|
||||
.arg(arg!(-f --flag "disallowed multiple flag"))
|
||||
.try_get_matches_from(vec![
|
||||
"",
|
||||
"-m",
|
||||
"-f",
|
||||
"-n",
|
||||
"--multflag1",
|
||||
"-m",
|
||||
"--multflag2",
|
||||
])
|
||||
.unwrap();
|
||||
assert!(m.is_present("multflag1"));
|
||||
assert_eq!(m.occurrences_of("multflag1"), 3);
|
||||
assert!(m.is_present("multflag2"));
|
||||
assert_eq!(m.occurrences_of("multflag2"), 2);
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.occurrences_of("flag"), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_occurrences_of_positional() {
|
||||
let cmd = Command::new("test").arg(Arg::new("multi").multiple_occurrences(true));
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["test"])
|
||||
.expect("zero occurrences work");
|
||||
assert!(!m.is_present("multi"));
|
||||
assert_eq!(m.occurrences_of("multi"), 0);
|
||||
assert!(m.values_of("multi").is_none());
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["test", "one"])
|
||||
.expect("single occurrence work");
|
||||
assert!(m.is_present("multi"));
|
||||
assert_eq!(m.occurrences_of("multi"), 1);
|
||||
assert_eq!(m.values_of("multi").unwrap().collect::<Vec<_>>(), ["one"]);
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["test", "one", "two", "three", "four"])
|
||||
.expect("many occurrences work");
|
||||
assert!(m.is_present("multi"));
|
||||
assert_eq!(m.occurrences_of("multi"), 4);
|
||||
assert_eq!(
|
||||
m.values_of("multi").unwrap().collect::<Vec<_>>(),
|
||||
["one", "two", "three", "four"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_occurrences_of_flags_large_quantity() {
|
||||
let args: Vec<&str> = vec![""]
|
||||
.into_iter()
|
||||
.chain(vec!["-m"; 1024].into_iter())
|
||||
.collect();
|
||||
let m = Command::new("mo_flags_large_qty")
|
||||
.arg(arg!(-m --multflag "allowed multiple flag").multiple_occurrences(true))
|
||||
.try_get_matches_from(args)
|
||||
.unwrap();
|
||||
assert!(m.is_present("multflag"));
|
||||
assert_eq!(m.occurrences_of("multflag"), 1024);
|
||||
}
|
||||
|
||||
#[cfg(feature = "env")]
|
||||
#[test]
|
||||
fn multiple_occurrences_of_before_env() {
|
||||
let cmd = Command::new("mo_before_env").arg(
|
||||
Arg::new("verbose")
|
||||
.env("VERBOSE")
|
||||
.short('v')
|
||||
.long("verbose")
|
||||
.takes_value(false)
|
||||
.multiple_occurrences(true),
|
||||
);
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(vec![""]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 0);
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(vec!["", "-v"]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 1);
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(vec!["", "-vv"]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 2);
|
||||
let m = cmd.clone().try_get_matches_from(vec!["", "-vvv"]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 3);
|
||||
}
|
||||
|
||||
#[cfg(feature = "env")]
|
||||
#[test]
|
||||
fn multiple_occurrences_of_after_env() {
|
||||
let cmd = Command::new("mo_after_env").arg(
|
||||
Arg::new("verbose")
|
||||
.short('v')
|
||||
.long("verbose")
|
||||
.takes_value(false)
|
||||
.multiple_occurrences(true)
|
||||
.env("VERBOSE"),
|
||||
);
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(vec![""]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 0);
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(vec!["", "-v"]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 1);
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(vec!["", "-vv"]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 2);
|
||||
let m = cmd.clone().try_get_matches_from(vec!["", "-vvv"]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn max_occurrences_implies_multiple_occurrences() {
|
||||
let cmd = Command::new("prog").arg(
|
||||
Arg::new("verbose")
|
||||
.short('v')
|
||||
.long("verbose")
|
||||
.max_occurrences(3),
|
||||
);
|
||||
let m = cmd.try_get_matches_from(vec!["prog", "-vvv"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 3);
|
||||
|
||||
// One max should not imply multiple occurrences
|
||||
let cmd = Command::new("prog").arg(
|
||||
Arg::new("verbose")
|
||||
.short('v')
|
||||
.long("verbose")
|
||||
.max_occurrences(1),
|
||||
);
|
||||
|
||||
let m = cmd.try_get_matches_from(vec!["prog", "-vvv"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::UnexpectedMultipleUsage);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn max_occurrences_try_inputs() {
|
||||
let cmd = Command::new("prog").arg(
|
||||
Arg::new("verbose")
|
||||
.short('v')
|
||||
.long("verbose")
|
||||
.max_occurrences(3),
|
||||
);
|
||||
let m = cmd.clone().try_get_matches_from(vec!["prog", "-v"]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 1);
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(vec!["prog", "-vv"]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 2);
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(vec!["prog", "-vvv"]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 3);
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(vec!["prog", "-vvvv"]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::TooManyOccurrences);
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(vec!["prog", "-v", "-v", "-v"]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 3);
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(vec!["prog", "-v", "-vv", "-v"]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::TooManyOccurrences);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn max_occurrences_positional() {
|
||||
let cmd = Command::new("prog").arg(Arg::new("verbose").max_occurrences(3));
|
||||
let m = cmd.clone().try_get_matches_from(vec!["prog", "v"]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 1);
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(vec!["prog", "v", "v"]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 2);
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(vec!["prog", "v", "v", "v"]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(m.unwrap().occurrences_of("verbose"), 3);
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(vec!["prog", "v", "v", "v", "v"]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::TooManyOccurrences);
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,616 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use clap::{arg, error::ErrorKind, Arg, ArgMatches, Command};
|
||||
|
||||
#[cfg(feature = "suggestions")]
|
||||
static DYM: &str =
|
||||
"error: Found argument '--optio' which wasn't expected, or isn't valid in this context
|
||||
|
||||
\tDid you mean '--option'?
|
||||
|
||||
\tIf you tried to supply `--optio` as a value rather than a flag, use `-- --optio`
|
||||
|
||||
USAGE:
|
||||
clap-test --option <opt>...
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
#[cfg(feature = "suggestions")]
|
||||
static DYM_ISSUE_1073: &str =
|
||||
"error: Found argument '--files-without-matches' which wasn't expected, or isn't valid in this context
|
||||
|
||||
\tDid you mean '--files-without-match'?
|
||||
|
||||
\tIf you tried to supply `--files-without-matches` as a value rather than a flag, use `-- --files-without-matches`
|
||||
|
||||
USAGE:
|
||||
ripgrep-616 --files-without-match
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn require_equals_fail() {
|
||||
let res = Command::new("prog")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.require_equals(true)
|
||||
.forbid_empty_values(true)
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.try_get_matches_from(vec!["prog", "--config", "file.conf"]);
|
||||
assert!(res.is_err());
|
||||
assert_eq!(res.unwrap_err().kind(), ErrorKind::NoEquals);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn require_equals_fail_message() {
|
||||
static NO_EQUALS: &str =
|
||||
"error: Equal sign is needed when assigning values to '--config=<cfg>'.
|
||||
|
||||
USAGE:
|
||||
prog [OPTIONS]
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
let cmd = Command::new("prog").arg(
|
||||
Arg::new("cfg")
|
||||
.require_equals(true)
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
);
|
||||
utils::assert_output(cmd, "prog --config file.conf", NO_EQUALS, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn require_equals_min_values_zero() {
|
||||
let res = Command::new("prog")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.min_values(0)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::new("cmd"))
|
||||
.try_get_matches_from(vec!["prog", "--config", "cmd"]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("cfg"));
|
||||
assert_eq!(m.value_of("cmd"), Some("cmd"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn double_hyphen_as_value() {
|
||||
let res = Command::new("prog")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.long("config"),
|
||||
)
|
||||
.try_get_matches_from(vec!["prog", "--config", "--"]);
|
||||
assert!(res.is_ok(), "{:?}", res);
|
||||
assert_eq!(res.unwrap().value_of("cfg"), Some("--"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn require_equals_no_empty_values_fail() {
|
||||
let res = Command::new("prog")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.forbid_empty_values(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::new("some"))
|
||||
.try_get_matches_from(vec!["prog", "--config=", "file.conf"]);
|
||||
assert!(res.is_err());
|
||||
assert_eq!(res.unwrap_err().kind(), ErrorKind::EmptyValue);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn require_equals_empty_vals_pass() {
|
||||
let res = Command::new("prog")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.long("config"),
|
||||
)
|
||||
.try_get_matches_from(vec!["prog", "--config="]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn require_equals_pass() {
|
||||
let res = Command::new("prog")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.long("config"),
|
||||
)
|
||||
.try_get_matches_from(vec!["prog", "--config=file.conf"]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stdin_char() {
|
||||
let r = Command::new("opts")
|
||||
.arg(arg!(f: -f [flag] "some flag"))
|
||||
.try_get_matches_from(vec!["", "-f", "-"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("f"));
|
||||
assert_eq!(m.value_of("f").unwrap(), "-");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opts_using_short() {
|
||||
let r = Command::new("opts")
|
||||
.args(&[
|
||||
arg!(f: -f [flag] "some flag"),
|
||||
arg!(c: -c [color] "some other flag"),
|
||||
])
|
||||
.try_get_matches_from(vec!["", "-f", "some", "-c", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("f"));
|
||||
assert_eq!(m.value_of("f").unwrap(), "some");
|
||||
assert!(m.is_present("c"));
|
||||
assert_eq!(m.value_of("c").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lots_o_vals() {
|
||||
let r = Command::new("opts")
|
||||
.arg(arg!(o: -o <opt> "some opt").multiple_values(true))
|
||||
.try_get_matches_from(vec![
|
||||
"", "-o", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some",
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.values_of("o").unwrap().count(), 297); // i.e. more than u8
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opts_using_long_space() {
|
||||
let r = Command::new("opts")
|
||||
.args(&[
|
||||
arg!(--flag [flag] "some flag"),
|
||||
arg!(--color [color] "some other flag"),
|
||||
])
|
||||
.try_get_matches_from(vec!["", "--flag", "some", "--color", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.value_of("flag").unwrap(), "some");
|
||||
assert!(m.is_present("color"));
|
||||
assert_eq!(m.value_of("color").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opts_using_long_equals() {
|
||||
let r = Command::new("opts")
|
||||
.args(&[
|
||||
arg!(--flag [flag] "some flag"),
|
||||
arg!(--color [color] "some other flag"),
|
||||
])
|
||||
.try_get_matches_from(vec!["", "--flag=some", "--color=other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.value_of("flag").unwrap(), "some");
|
||||
assert!(m.is_present("color"));
|
||||
assert_eq!(m.value_of("color").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opts_using_mixed() {
|
||||
let r = Command::new("opts")
|
||||
.args(&[
|
||||
arg!(-f --flag [flag] "some flag"),
|
||||
arg!(-c --color [color] "some other flag"),
|
||||
])
|
||||
.try_get_matches_from(vec!["", "-f", "some", "--color", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.value_of("flag").unwrap(), "some");
|
||||
assert!(m.is_present("color"));
|
||||
assert_eq!(m.value_of("color").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opts_using_mixed2() {
|
||||
let r = Command::new("opts")
|
||||
.args(&[
|
||||
arg!(-f --flag [flag] "some flag"),
|
||||
arg!(-c --color [color] "some other flag"),
|
||||
])
|
||||
.try_get_matches_from(vec!["", "--flag=some", "-c", "other"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.value_of("flag").unwrap(), "some");
|
||||
assert!(m.is_present("color"));
|
||||
assert_eq!(m.value_of("color").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_values_user_value() {
|
||||
let r = Command::new("df")
|
||||
.arg(arg!(o: -o [opt] "some opt").default_value("default"))
|
||||
.try_get_matches_from(vec!["", "-o", "value"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.value_of("o").unwrap(), "value");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_vals_pos_arg_equals() {
|
||||
let r = Command::new("mvae")
|
||||
.arg(arg!(o: -o [opt] ... "some opt"))
|
||||
.arg(arg!([file] "some file"))
|
||||
.try_get_matches_from(vec!["", "-o=1", "some"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.value_of("o").unwrap(), "1");
|
||||
assert!(m.is_present("file"));
|
||||
assert_eq!(m.value_of("file").unwrap(), "some");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_vals_pos_arg_delim() {
|
||||
let r = Command::new("mvae")
|
||||
.arg(
|
||||
arg!(o: -o <opt> "some opt")
|
||||
.multiple_values(true)
|
||||
.use_value_delimiter(true),
|
||||
)
|
||||
.arg(arg!([file] "some file"))
|
||||
.try_get_matches_from(vec!["", "-o", "1,2", "some"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.values_of("o").unwrap().collect::<Vec<_>>(), &["1", "2"]);
|
||||
assert!(m.is_present("file"));
|
||||
assert_eq!(m.value_of("file").unwrap(), "some");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn require_delims_no_delim() {
|
||||
let r = Command::new("mvae")
|
||||
.arg(
|
||||
arg!(o: -o [opt] ... "some opt")
|
||||
.use_value_delimiter(true)
|
||||
.require_value_delimiter(true),
|
||||
)
|
||||
.arg(arg!([file] "some file"))
|
||||
.try_get_matches_from(vec!["mvae", "-o", "1", "2", "some"]);
|
||||
assert!(r.is_err());
|
||||
let err = r.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn require_delims() {
|
||||
let r = Command::new("mvae")
|
||||
.arg(
|
||||
arg!(o: -o <opt> "some opt")
|
||||
.multiple_values(true)
|
||||
.use_value_delimiter(true)
|
||||
.require_value_delimiter(true),
|
||||
)
|
||||
.arg(arg!([file] "some file"))
|
||||
.try_get_matches_from(vec!["", "-o", "1,2", "some"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.values_of("o").unwrap().collect::<Vec<_>>(), &["1", "2"]);
|
||||
assert!(m.is_present("file"));
|
||||
assert_eq!(m.value_of("file").unwrap(), "some");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leading_hyphen_pass() {
|
||||
let r = Command::new("mvae")
|
||||
.arg(
|
||||
arg!(o: -o <opt> "some opt")
|
||||
.multiple_values(true)
|
||||
.allow_hyphen_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "-o", "-2", "3"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.values_of("o").unwrap().collect::<Vec<_>>(), &["-2", "3"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leading_hyphen_fail() {
|
||||
let r = Command::new("mvae")
|
||||
.arg(arg!(o: -o <opt> "some opt"))
|
||||
.try_get_matches_from(vec!["", "-o", "-2"]);
|
||||
assert!(r.is_err());
|
||||
let m = r.unwrap_err();
|
||||
assert_eq!(m.kind(), ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leading_hyphen_with_flag_after() {
|
||||
let r = Command::new("mvae")
|
||||
.arg(
|
||||
arg!(o: -o <opt> "some opt")
|
||||
.multiple_values(true)
|
||||
.allow_hyphen_values(true),
|
||||
)
|
||||
.arg(arg!(f: -f "some flag"))
|
||||
.try_get_matches_from(vec!["", "-o", "-2", "-f"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.values_of("o").unwrap().collect::<Vec<_>>(), &["-2", "-f"]);
|
||||
assert!(!m.is_present("f"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leading_hyphen_with_flag_before() {
|
||||
let r = Command::new("mvae")
|
||||
.arg(arg!(o: -o [opt] ... "some opt").allow_hyphen_values(true))
|
||||
.arg(arg!(f: -f "some flag"))
|
||||
.try_get_matches_from(vec!["", "-f", "-o", "-2"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.values_of("o").unwrap().collect::<Vec<_>>(), &["-2"]);
|
||||
assert!(m.is_present("f"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leading_hyphen_with_only_pos_follows() {
|
||||
let r = Command::new("mvae")
|
||||
.arg(
|
||||
arg!(o: -o [opt] ... "some opt")
|
||||
.number_of_values(1)
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true),
|
||||
)
|
||||
.arg(arg!([arg] "some arg"))
|
||||
.try_get_matches_from(vec!["", "-o", "-2", "--", "val"]);
|
||||
assert!(r.is_ok(), "{:?}", r);
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
assert_eq!(m.values_of("o").unwrap().collect::<Vec<_>>(), &["-2"]);
|
||||
assert_eq!(m.value_of("arg"), Some("val"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "suggestions")]
|
||||
fn did_you_mean() {
|
||||
utils::assert_output(utils::complex_app(), "clap-test --optio=foo", DYM, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1047_min_zero_vals_default_val() {
|
||||
let m = Command::new("foo")
|
||||
.arg(
|
||||
Arg::new("del")
|
||||
.short('d')
|
||||
.long("del")
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.min_values(0)
|
||||
.default_missing_value("default"),
|
||||
)
|
||||
.try_get_matches_from(vec!["foo", "-d"])
|
||||
.unwrap();
|
||||
assert_eq!(m.occurrences_of("del"), 1);
|
||||
assert_eq!(m.value_of("del"), Some("default"));
|
||||
}
|
||||
|
||||
fn issue_1105_setup(argv: Vec<&'static str>) -> Result<ArgMatches, clap::Error> {
|
||||
Command::new("opts")
|
||||
.arg(arg!(-o --option <opt> "some option"))
|
||||
.arg(arg!(--flag "some flag"))
|
||||
.try_get_matches_from(argv)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1105_empty_value_long_fail() {
|
||||
let r = issue_1105_setup(vec!["cmd", "--option", "--flag"]);
|
||||
assert!(r.is_err());
|
||||
assert_eq!(r.unwrap_err().kind(), ErrorKind::EmptyValue);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1105_empty_value_long_explicit() {
|
||||
let r = issue_1105_setup(vec!["cmd", "--option", ""]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert_eq!(m.value_of("option"), Some(""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1105_empty_value_long_equals() {
|
||||
let r = issue_1105_setup(vec!["cmd", "--option="]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert_eq!(m.value_of("option"), Some(""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1105_empty_value_short_fail() {
|
||||
let r = issue_1105_setup(vec!["cmd", "-o", "--flag"]);
|
||||
assert!(r.is_err());
|
||||
assert_eq!(r.unwrap_err().kind(), ErrorKind::EmptyValue);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1105_empty_value_short_explicit() {
|
||||
let r = issue_1105_setup(vec!["cmd", "-o", ""]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert_eq!(m.value_of("option"), Some(""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1105_empty_value_short_equals() {
|
||||
let r = issue_1105_setup(vec!["cmd", "-o="]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert_eq!(m.value_of("option"), Some(""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1105_empty_value_short_explicit_no_space() {
|
||||
let r = issue_1105_setup(vec!["cmd", "-o", ""]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert_eq!(m.value_of("option"), Some(""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "suggestions")]
|
||||
fn issue_1073_suboptimal_flag_suggestion() {
|
||||
let cmd = Command::new("ripgrep-616")
|
||||
.arg(Arg::new("files-with-matches").long("files-with-matches"))
|
||||
.arg(Arg::new("files-without-match").long("files-without-match"));
|
||||
utils::assert_output(
|
||||
cmd,
|
||||
"ripgrep-616 --files-without-matches",
|
||||
DYM_ISSUE_1073,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_non_ascii_no_space() {
|
||||
let matches = Command::new("cmd")
|
||||
.arg(arg!(opt: -'磨' <opt>))
|
||||
.try_get_matches_from(&["test", "-磨VALUE"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!("VALUE", matches.value_of("opt").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_eq_val_starts_with_eq() {
|
||||
let matches = Command::new("cmd")
|
||||
.arg(arg!(opt: -f <opt>))
|
||||
.try_get_matches_from(&["test", "-f==value"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!("=value", matches.value_of("opt").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn long_eq_val_starts_with_eq() {
|
||||
let matches = Command::new("cmd")
|
||||
.arg(arg!(opt: --foo <opt>))
|
||||
.try_get_matches_from(&["test", "--foo==value"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!("=value", matches.value_of("opt").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_2022_get_flags_misuse() {
|
||||
let cmd = Command::new("test")
|
||||
.next_help_heading(Some("test"))
|
||||
.arg(Arg::new("a").long("a").default_value("32"));
|
||||
let matches = cmd.try_get_matches_from(&[""]).unwrap();
|
||||
assert!(matches.value_of("a").is_some())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_2279() {
|
||||
let before_help_heading = Command::new("cmd")
|
||||
.arg(Arg::new("foo").short('f').default_value("bar"))
|
||||
.next_help_heading(Some("This causes default_value to be ignored"))
|
||||
.try_get_matches_from(&[""])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(before_help_heading.value_of("foo"), Some("bar"));
|
||||
|
||||
let after_help_heading = Command::new("cmd")
|
||||
.next_help_heading(Some("This causes default_value to be ignored"))
|
||||
.arg(Arg::new("foo").short('f').default_value("bar"))
|
||||
.try_get_matches_from(&[""])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(after_help_heading.value_of("foo"), Some("bar"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_long_arg() {
|
||||
let cmd = Command::new("test")
|
||||
.infer_long_args(true)
|
||||
.arg(Arg::new("racetrack").long("racetrack").alias("autobahn"))
|
||||
.arg(Arg::new("racecar").long("racecar").takes_value(true));
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["test", "--racec=hello"])
|
||||
.unwrap();
|
||||
assert!(!matches.is_present("racetrack"));
|
||||
assert_eq!(matches.value_of("racecar"), Some("hello"));
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["test", "--racet"])
|
||||
.unwrap();
|
||||
assert!(matches.is_present("racetrack"));
|
||||
assert_eq!(matches.value_of("racecar"), None);
|
||||
|
||||
let matches = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["test", "--auto"])
|
||||
.unwrap();
|
||||
assert!(matches.is_present("racetrack"));
|
||||
assert_eq!(matches.value_of("racecar"), None);
|
||||
|
||||
let cmd = Command::new("test")
|
||||
.infer_long_args(true)
|
||||
.arg(Arg::new("arg").long("arg"));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(&["test", "--"]).unwrap();
|
||||
assert!(!matches.is_present("arg"));
|
||||
|
||||
let matches = cmd.clone().try_get_matches_from(&["test", "--a"]).unwrap();
|
||||
assert!(matches.is_present("arg"));
|
||||
}
|
|
@ -1,310 +0,0 @@
|
|||
use clap::{arg, error::ErrorKind, Arg, Command};
|
||||
|
||||
#[test]
|
||||
fn only_pos_follow() {
|
||||
let r = Command::new("onlypos")
|
||||
.args(&[arg!(f: -f [flag] "some opt"), arg!([arg] "some arg")])
|
||||
.try_get_matches_from(vec!["", "--", "-f"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert!(!m.is_present("f"));
|
||||
assert_eq!(m.value_of("arg").unwrap(), "-f");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_946() {
|
||||
let r = Command::new("compiletest")
|
||||
.allow_hyphen_values(true)
|
||||
.arg(arg!(--exact "filters match exactly"))
|
||||
.arg(
|
||||
clap::Arg::new("filter")
|
||||
.index(1)
|
||||
.takes_value(true)
|
||||
.help("filters to apply to output"),
|
||||
)
|
||||
.try_get_matches_from(vec!["compiletest", "--exact"]);
|
||||
assert!(r.is_ok(), "{:#?}", r);
|
||||
let matches = r.unwrap();
|
||||
|
||||
assert!(matches.is_present("exact"));
|
||||
assert!(matches.value_of("filter").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positional() {
|
||||
let r = Command::new("positional")
|
||||
.args(&[arg!(-f --flag "some flag"), Arg::new("positional").index(1)])
|
||||
.try_get_matches_from(vec!["", "-f", "test"]);
|
||||
assert!(r.is_ok(), "{:#?}", r);
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("positional"));
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.value_of("positional").unwrap(), "test");
|
||||
|
||||
let m = Command::new("positional")
|
||||
.args(&[arg!(-f --flag "some flag"), Arg::new("positional").index(1)])
|
||||
.try_get_matches_from(vec!["", "test", "--flag"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("positional"));
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.value_of("positional").unwrap(), "test");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lots_o_vals() {
|
||||
let r = Command::new("opts")
|
||||
.arg(arg!(<opt>... "some pos"))
|
||||
.try_get_matches_from(vec![
|
||||
"", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some",
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("opt"));
|
||||
assert_eq!(m.values_of("opt").unwrap().count(), 297); // i.e. more than u8
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positional_multiple() {
|
||||
let r = Command::new("positional_multiple")
|
||||
.args(&[
|
||||
arg!(-f --flag "some flag"),
|
||||
Arg::new("positional")
|
||||
.index(1)
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
])
|
||||
.try_get_matches_from(vec!["", "-f", "test1", "test2", "test3"]);
|
||||
assert!(r.is_ok(), "{:#?}", r);
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("positional"));
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(
|
||||
&*m.values_of("positional").unwrap().collect::<Vec<_>>(),
|
||||
&["test1", "test2", "test3"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positional_multiple_3() {
|
||||
let r = Command::new("positional_multiple")
|
||||
.args(&[
|
||||
arg!(-f --flag "some flag"),
|
||||
Arg::new("positional")
|
||||
.index(1)
|
||||
.takes_value(true)
|
||||
.multiple_values(true),
|
||||
])
|
||||
.try_get_matches_from(vec!["", "test1", "test2", "test3", "--flag"]);
|
||||
assert!(r.is_ok(), "{:#?}", r);
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("positional"));
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(
|
||||
&*m.values_of("positional").unwrap().collect::<Vec<_>>(),
|
||||
&["test1", "test2", "test3"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positional_multiple_2() {
|
||||
let result = Command::new("positional_multiple")
|
||||
.args(&[arg!(-f --flag "some flag"), Arg::new("positional").index(1)])
|
||||
.try_get_matches_from(vec!["", "-f", "test1", "test2", "test3"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positional_possible_values() {
|
||||
let r = Command::new("positional_possible_values")
|
||||
.args(&[
|
||||
arg!(-f --flag "some flag"),
|
||||
Arg::new("positional").index(1).possible_value("test123"),
|
||||
])
|
||||
.try_get_matches_from(vec!["", "-f", "test123"]);
|
||||
assert!(r.is_ok(), "{:#?}", r);
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("positional"));
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(
|
||||
&*m.values_of("positional").unwrap().collect::<Vec<_>>(),
|
||||
&["test123"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_positional() {
|
||||
let _ = Command::new("test")
|
||||
.arg(Arg::new("test").index(1).help("testing testing"))
|
||||
.try_get_matches_from(vec![""])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positional_hyphen_does_not_panic() {
|
||||
let _ = Command::new("test")
|
||||
.arg(Arg::new("dummy"))
|
||||
.try_get_matches_from(vec!["test", "-"])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_positional_usage_string() {
|
||||
let mut cmd = Command::new("test").arg(arg!([FILE] "some file"));
|
||||
assert_eq!(cmd.render_usage(), "USAGE:\n test [FILE]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_positional_multiple_usage_string() {
|
||||
let mut cmd = Command::new("test").arg(arg!([FILE]... "some file"));
|
||||
assert_eq!(cmd.render_usage(), "USAGE:\n test [FILE]...");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_positional_usage_string() {
|
||||
let mut cmd = Command::new("test")
|
||||
.arg(arg!([FILE] "some file"))
|
||||
.arg(arg!([FILES]... "some file"));
|
||||
assert_eq!(cmd.render_usage(), "USAGE:\n test [ARGS]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_positional_one_required_usage_string() {
|
||||
let mut cmd = Command::new("test")
|
||||
.arg(arg!(<FILE> "some file"))
|
||||
.arg(arg!([FILES]... "some file"));
|
||||
assert_eq!(cmd.render_usage(), "USAGE:\n test <FILE> [FILES]...");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_positional_required_usage_string() {
|
||||
let mut cmd = Command::new("test").arg(arg!(<FILE> "some file"));
|
||||
assert_eq!(cmd.render_usage(), "USAGE:\n test <FILE>");
|
||||
}
|
||||
|
||||
// This tests a programmer error and will only succeed with debug_assertions
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Found non-required positional argument \
|
||||
with a lower index than a required positional argument"]
|
||||
fn missing_required() {
|
||||
let _ = Command::new("test")
|
||||
.arg(arg!([FILE1] "some file"))
|
||||
.arg(arg!(<FILE2> "some file"))
|
||||
.try_get_matches_from(vec![""]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_required_2() {
|
||||
let r = Command::new("test")
|
||||
.arg(arg!(<FILE1> "some file"))
|
||||
.arg(arg!(<FILE2> "some file"))
|
||||
.try_get_matches_from(vec!["test", "file"]);
|
||||
assert!(r.is_err());
|
||||
assert_eq!(r.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn last_positional() {
|
||||
let r = Command::new("test")
|
||||
.arg(arg!(<TARGET> "some target"))
|
||||
.arg(arg!([CORPUS] "some corpus"))
|
||||
.arg(arg!([ARGS]... "some file").last(true))
|
||||
.try_get_matches_from(vec!["test", "tgt", "--", "arg"]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert_eq!(m.values_of("ARGS").unwrap().collect::<Vec<_>>(), &["arg"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn last_positional_no_double_dash() {
|
||||
let r = Command::new("test")
|
||||
.arg(arg!(<TARGET> "some target"))
|
||||
.arg(arg!([CORPUS] "some corpus"))
|
||||
.arg(arg!([ARGS]... "some file").last(true))
|
||||
.try_get_matches_from(vec!["test", "tgt", "crp", "arg"]);
|
||||
assert!(r.is_err());
|
||||
assert_eq!(r.unwrap_err().kind(), ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn last_positional_second_to_last_mult() {
|
||||
let r = Command::new("test")
|
||||
.arg(arg!(<TARGET> "some target"))
|
||||
.arg(arg!([CORPUS]... "some corpus"))
|
||||
.arg(arg!([ARGS]... "some file").last(true))
|
||||
.try_get_matches_from(vec!["test", "tgt", "crp1", "crp2", "--", "arg"]);
|
||||
assert!(r.is_ok(), "{:?}", r.unwrap_err().kind());
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument 'arg' is a positional argument and can't have short or long name versions"]
|
||||
fn positional_arg_with_long() {
|
||||
use clap::{Arg, Command};
|
||||
|
||||
let _ = Command::new("test")
|
||||
.arg(Arg::new("arg").index(1).long("arg"))
|
||||
.try_get_matches();
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument 'arg' is a positional argument and can't have short or long name versions"]
|
||||
fn positional_arg_with_short() {
|
||||
use clap::{Arg, Command};
|
||||
|
||||
let _ = Command::new("test")
|
||||
.arg(Arg::new("arg").index(1).short('a'))
|
||||
.try_get_matches();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_hyphen_values_on_last() {
|
||||
let cmd = clap::Command::new("foo")
|
||||
.arg(
|
||||
clap::Arg::new("cmd")
|
||||
.multiple_values(true)
|
||||
.last(true)
|
||||
.allow_hyphen_values(true),
|
||||
)
|
||||
.arg(
|
||||
clap::Arg::new("name")
|
||||
.long("name")
|
||||
.short('n')
|
||||
.takes_value(true)
|
||||
.required(false),
|
||||
);
|
||||
|
||||
let matches = cmd.try_get_matches_from(["test", "-n", "foo"]).unwrap();
|
||||
assert_eq!(matches.value_of("name"), Some("foo"));
|
||||
}
|
|
@ -1,401 +0,0 @@
|
|||
use clap::{arg, error::ErrorKind, Arg, Command};
|
||||
|
||||
#[test]
|
||||
fn flag_overrides_itself() {
|
||||
let res = Command::new("posix")
|
||||
.arg(
|
||||
arg!(--flag "some flag"
|
||||
)
|
||||
.overrides_with("flag"),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--flag", "--flag"]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.occurrences_of("flag"), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mult_flag_overrides_itself() {
|
||||
let res = Command::new("posix")
|
||||
.arg(arg!(--flag ... "some flag").overrides_with("flag"))
|
||||
.try_get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.occurrences_of("flag"), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn option_overrides_itself() {
|
||||
let res = Command::new("posix")
|
||||
.arg(
|
||||
arg!(--opt <val> "some option")
|
||||
.required(false)
|
||||
.overrides_with("opt"),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt=some", "--opt=other"]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("opt"));
|
||||
assert_eq!(m.occurrences_of("opt"), 1);
|
||||
assert_eq!(m.value_of("opt"), Some("other"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mult_option_require_delim_overrides_itself() {
|
||||
let res = Command::new("posix")
|
||||
.arg(
|
||||
arg!(--opt <val> ... "some option")
|
||||
.required(false)
|
||||
.overrides_with("opt")
|
||||
.number_of_values(1)
|
||||
.takes_value(true)
|
||||
.use_value_delimiter(true)
|
||||
.require_value_delimiter(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt=some", "--opt=other", "--opt=one,two"]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("opt"));
|
||||
assert_eq!(m.occurrences_of("opt"), 3);
|
||||
assert_eq!(
|
||||
m.values_of("opt").unwrap().collect::<Vec<_>>(),
|
||||
&["some", "other", "one", "two"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mult_option_overrides_itself() {
|
||||
let res = Command::new("posix")
|
||||
.arg(
|
||||
arg!(--opt <val> ... "some option")
|
||||
.required(false)
|
||||
.multiple_values(true)
|
||||
.overrides_with("opt"),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
"",
|
||||
"--opt",
|
||||
"first",
|
||||
"overrides",
|
||||
"--opt",
|
||||
"some",
|
||||
"other",
|
||||
"val",
|
||||
]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("opt"));
|
||||
assert_eq!(m.occurrences_of("opt"), 2);
|
||||
assert_eq!(
|
||||
m.values_of("opt").unwrap().collect::<Vec<_>>(),
|
||||
&["first", "overrides", "some", "other", "val"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn option_use_delim_false_override_itself() {
|
||||
let m = Command::new("posix")
|
||||
.arg(
|
||||
arg!(--opt <val> "some option")
|
||||
.required(false)
|
||||
.overrides_with("opt"),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--opt=some,other", "--opt=one,two"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("opt"));
|
||||
assert_eq!(m.occurrences_of("opt"), 1);
|
||||
assert_eq!(
|
||||
m.values_of("opt").unwrap().collect::<Vec<_>>(),
|
||||
&["one,two"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pos_mult_overrides_itself() {
|
||||
// opts with multiple
|
||||
let res = Command::new("posix")
|
||||
.arg(arg!([val] ... "some pos").overrides_with("val"))
|
||||
.try_get_matches_from(vec!["", "some", "other", "value"]);
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("val"));
|
||||
assert_eq!(m.occurrences_of("val"), 3);
|
||||
assert_eq!(
|
||||
m.values_of("val").unwrap().collect::<Vec<_>>(),
|
||||
&["some", "other", "value"]
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn posix_compatible_flags_long() {
|
||||
let m = Command::new("posix")
|
||||
.arg(arg!(--flag "some flag").overrides_with("color"))
|
||||
.arg(arg!(--color "some other flag"))
|
||||
.try_get_matches_from(vec!["", "--flag", "--color"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("color"));
|
||||
assert!(!m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_flags_long_rev() {
|
||||
let m = Command::new("posix")
|
||||
.arg(arg!(--flag "some flag").overrides_with("color"))
|
||||
.arg(arg!(--color "some other flag"))
|
||||
.try_get_matches_from(vec!["", "--color", "--flag"])
|
||||
.unwrap();
|
||||
assert!(!m.is_present("color"));
|
||||
assert!(m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_flags_short() {
|
||||
let m = Command::new("posix")
|
||||
.arg(arg!(-f --flag "some flag").overrides_with("color"))
|
||||
.arg(arg!(-c --color "some other flag"))
|
||||
.try_get_matches_from(vec!["", "-f", "-c"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("color"));
|
||||
assert!(!m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_flags_short_rev() {
|
||||
let m = Command::new("posix")
|
||||
.arg(arg!(-f --flag "some flag").overrides_with("color"))
|
||||
.arg(arg!(-c --color "some other flag"))
|
||||
.try_get_matches_from(vec!["", "-c", "-f"])
|
||||
.unwrap();
|
||||
assert!(!m.is_present("color"));
|
||||
assert!(m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_opts_long() {
|
||||
let m = Command::new("posix")
|
||||
.arg(
|
||||
arg!(--flag <flag> "some flag")
|
||||
.required(false)
|
||||
.overrides_with("color"),
|
||||
)
|
||||
.arg(arg!(--color <color> "some other flag").required(false))
|
||||
.try_get_matches_from(vec!["", "--flag", "some", "--color", "other"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("color"));
|
||||
assert_eq!(m.value_of("color").unwrap(), "other");
|
||||
assert!(!m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_opts_long_rev() {
|
||||
let m = Command::new("posix")
|
||||
.arg(
|
||||
arg!(--flag <flag> "some flag")
|
||||
.required(false)
|
||||
.overrides_with("color"),
|
||||
)
|
||||
.arg(arg!(--color <color> "some other flag").required(false))
|
||||
.try_get_matches_from(vec!["", "--color", "some", "--flag", "other"])
|
||||
.unwrap();
|
||||
assert!(!m.is_present("color"));
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.value_of("flag").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_opts_long_equals() {
|
||||
let m = Command::new("posix")
|
||||
.arg(
|
||||
arg!(--flag <flag> "some flag")
|
||||
.required(false)
|
||||
.overrides_with("color"),
|
||||
)
|
||||
.arg(arg!(--color <color> "some other flag").required(false))
|
||||
.try_get_matches_from(vec!["", "--flag=some", "--color=other"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("color"));
|
||||
assert_eq!(m.value_of("color").unwrap(), "other");
|
||||
assert!(!m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_opts_long_equals_rev() {
|
||||
let m = Command::new("posix")
|
||||
.arg(
|
||||
arg!(--flag <flag> "some flag")
|
||||
.required(false)
|
||||
.overrides_with("color"),
|
||||
)
|
||||
.arg(arg!(--color <color> "some other flag").required(false))
|
||||
.try_get_matches_from(vec!["", "--color=some", "--flag=other"])
|
||||
.unwrap();
|
||||
assert!(!m.is_present("color"));
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.value_of("flag").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_opts_short() {
|
||||
let m = Command::new("posix")
|
||||
.arg(
|
||||
arg!(f: -f <flag> "some flag")
|
||||
.required(false)
|
||||
.overrides_with("c"),
|
||||
)
|
||||
.arg(arg!(c: -c <color> "some other flag").required(false))
|
||||
.try_get_matches_from(vec!["", "-f", "some", "-c", "other"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("c"));
|
||||
assert_eq!(m.value_of("c").unwrap(), "other");
|
||||
assert!(!m.is_present("f"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_opts_short_rev() {
|
||||
let m = Command::new("posix")
|
||||
.arg(
|
||||
arg!(f: -f <flag> "some flag")
|
||||
.required(false)
|
||||
.overrides_with("c"),
|
||||
)
|
||||
.arg(arg!(c: -c <color> "some other flag").required(false))
|
||||
.try_get_matches_from(vec!["", "-c", "some", "-f", "other"])
|
||||
.unwrap();
|
||||
assert!(!m.is_present("c"));
|
||||
assert!(m.is_present("f"));
|
||||
assert_eq!(m.value_of("f").unwrap(), "other");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conflict_overridden() {
|
||||
let m = Command::new("conflict_overridden")
|
||||
.arg(arg!(-f --flag "some flag").conflicts_with("debug"))
|
||||
.arg(arg!(-d --debug "other flag"))
|
||||
.arg(arg!(-c --color "third flag").overrides_with("flag"))
|
||||
.try_get_matches_from(vec!["", "-f", "-c", "-d"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("color"));
|
||||
assert!(!m.is_present("flag"));
|
||||
assert!(m.is_present("debug"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conflict_overridden_2() {
|
||||
let result = Command::new("conflict_overridden")
|
||||
.arg(arg!(-f --flag "some flag").conflicts_with("debug"))
|
||||
.arg(arg!(-d --debug "other flag"))
|
||||
.arg(arg!(-c --color "third flag").overrides_with("flag"))
|
||||
.try_get_matches_from(vec!["", "-f", "-d", "-c"]);
|
||||
assert!(result.is_ok(), "{}", result.unwrap_err());
|
||||
let m = result.unwrap();
|
||||
assert!(m.is_present("color"));
|
||||
assert!(m.is_present("debug"));
|
||||
assert!(!m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conflict_overridden_3() {
|
||||
let result = Command::new("conflict_overridden")
|
||||
.arg(arg!(-f --flag "some flag").conflicts_with("debug"))
|
||||
.arg(arg!(-d --debug "other flag"))
|
||||
.arg(arg!(-c --color "third flag").overrides_with("flag"))
|
||||
.try_get_matches_from(vec!["", "-d", "-c", "-f"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conflict_overridden_4() {
|
||||
let m = Command::new("conflict_overridden")
|
||||
.arg(arg!(-f --flag "some flag").conflicts_with("debug"))
|
||||
.arg(arg!(-d --debug "other flag"))
|
||||
.arg(arg!(-c --color "third flag").overrides_with("flag"))
|
||||
.try_get_matches_from(vec!["", "-d", "-f", "-c"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("color"));
|
||||
assert!(!m.is_present("flag"));
|
||||
assert!(m.is_present("debug"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pos_required_overridden_by_flag() {
|
||||
let result = Command::new("require_overridden")
|
||||
.arg(Arg::new("pos").index(1).required(true))
|
||||
.arg(arg!(-c --color "some flag").overrides_with("pos"))
|
||||
.try_get_matches_from(vec!["", "test", "-c"]);
|
||||
assert!(result.is_ok(), "{:?}", result.unwrap_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn require_overridden_2() {
|
||||
let m = Command::new("require_overridden")
|
||||
.arg(Arg::new("req_pos").required(true))
|
||||
.arg(arg!(-c --color "other flag").overrides_with("req_pos"))
|
||||
.try_get_matches_from(vec!["", "-c", "req_pos"])
|
||||
.unwrap();
|
||||
assert!(!m.is_present("color"));
|
||||
assert!(m.is_present("req_pos"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn require_overridden_3() {
|
||||
let m = Command::new("require_overridden")
|
||||
.arg(arg!(-f --flag "some flag").requires("debug"))
|
||||
.arg(arg!(-d --debug "other flag"))
|
||||
.arg(arg!(-c --color "third flag").overrides_with("flag"))
|
||||
.try_get_matches_from(vec!["", "-f", "-c"])
|
||||
.unwrap();
|
||||
assert!(m.is_present("color"));
|
||||
assert!(!m.is_present("flag"));
|
||||
assert!(!m.is_present("debug"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn require_overridden_4() {
|
||||
let result = Command::new("require_overridden")
|
||||
.arg(arg!(-f --flag "some flag").requires("debug"))
|
||||
.arg(arg!(-d --debug "other flag"))
|
||||
.arg(arg!(-c --color "third flag").overrides_with("flag"))
|
||||
.try_get_matches_from(vec!["", "-c", "-f"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1374_overrides_self_with_multiple_values() {
|
||||
let cmd = Command::new("test").arg(
|
||||
Arg::new("input")
|
||||
.long("input")
|
||||
.takes_value(true)
|
||||
.overrides_with("input")
|
||||
.min_values(0),
|
||||
);
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["test", "--input", "a", "b", "c", "--input", "d"])
|
||||
.unwrap();
|
||||
assert_eq!(m.values_of("input").unwrap().collect::<Vec<_>>(), &["d"]);
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["test", "--input", "a", "b", "--input", "c", "d"])
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
m.values_of("input").unwrap().collect::<Vec<_>>(),
|
||||
&["c", "d"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn incremental_override() {
|
||||
let mut cmd = Command::new("test")
|
||||
.arg(arg!(--name <NAME>).multiple_occurrences(true))
|
||||
.arg(arg!(--"no-name").overrides_with("name"));
|
||||
let m = cmd
|
||||
.try_get_matches_from_mut(&["test", "--name=ahmed", "--no-name", "--name=ali"])
|
||||
.unwrap();
|
||||
assert_eq!(m.values_of("name").unwrap().collect::<Vec<_>>(), &["ali"]);
|
||||
assert!(!m.is_present("no-name"));
|
||||
}
|
|
@ -1,393 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use clap::{error::ErrorKind, Arg, Command, PossibleValue};
|
||||
|
||||
#[cfg(feature = "suggestions")]
|
||||
static PV_ERROR: &str = "error: \"slo\" isn't a valid value for '-O <option>'
|
||||
\t[possible values: slow, fast, \"ludicrous speed\"]
|
||||
|
||||
\tDid you mean \"slow\"?
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
#[cfg(not(feature = "suggestions"))]
|
||||
static PV_ERROR: &str = "error: \"slo\" isn't a valid value for '-O <option>'
|
||||
\t[possible values: slow, fast, \"ludicrous speed\"]
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
#[cfg(feature = "suggestions")]
|
||||
static PV_ERROR_ESCAPED: &str = "error: \"ludicrous\" isn't a valid value for '-O <option>'
|
||||
\t[possible values: slow, fast, \"ludicrous speed\"]
|
||||
|
||||
\tDid you mean \"ludicrous speed\"?
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
#[cfg(not(feature = "suggestions"))]
|
||||
static PV_ERROR_ESCAPED: &str = "error: \"ludicrous\" isn't a valid value for '-O <option>'
|
||||
\t[possible values: slow, fast, \"ludicrous speed\"]
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn possible_values_of_positional() {
|
||||
let m = Command::new("possible_values")
|
||||
.arg(Arg::new("positional").index(1).possible_value("test123"))
|
||||
.try_get_matches_from(vec!["myprog", "test123"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
||||
assert!(m.is_present("positional"));
|
||||
assert_eq!(m.value_of("positional"), Some("test123"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn possible_value_arg_value() {
|
||||
let m = Command::new("possible_values")
|
||||
.arg(
|
||||
Arg::new("arg_value").index(1).possible_value(
|
||||
PossibleValue::new("test123")
|
||||
.hide(false)
|
||||
.help("It's just a test"),
|
||||
),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "test123"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
||||
assert!(m.is_present("arg_value"));
|
||||
assert_eq!(m.value_of("arg_value"), Some("test123"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn possible_values_of_positional_fail() {
|
||||
let m = Command::new("possible_values")
|
||||
.arg(Arg::new("positional").index(1).possible_value("test123"))
|
||||
.try_get_matches_from(vec!["myprog", "notest"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn possible_values_of_positional_multiple() {
|
||||
let m = Command::new("possible_values")
|
||||
.arg(
|
||||
Arg::new("positional")
|
||||
.index(1)
|
||||
.takes_value(true)
|
||||
.possible_value("test123")
|
||||
.possible_value("test321")
|
||||
.multiple_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "test123", "test321"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
||||
assert!(m.is_present("positional"));
|
||||
assert_eq!(
|
||||
m.values_of("positional").unwrap().collect::<Vec<_>>(),
|
||||
vec!["test123", "test321"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn possible_values_of_positional_multiple_fail() {
|
||||
let m = Command::new("possible_values")
|
||||
.arg(
|
||||
Arg::new("positional")
|
||||
.index(1)
|
||||
.takes_value(true)
|
||||
.possible_value("test123")
|
||||
.possible_value("test321")
|
||||
.multiple_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "test123", "notest"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn possible_values_of_option() {
|
||||
let m = Command::new("possible_values")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.possible_value("test123"),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "--option", "test123"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
||||
assert!(m.is_present("option"));
|
||||
assert_eq!(m.value_of("option"), Some("test123"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn possible_values_of_option_fail() {
|
||||
let m = Command::new("possible_values")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.possible_value("test123"),
|
||||
)
|
||||
.try_get_matches_from(vec!["myprog", "--option", "notest"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn possible_values_of_option_multiple() {
|
||||
let m = Command::new("possible_values")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.possible_value("test123")
|
||||
.possible_value("test321")
|
||||
.multiple_occurrences(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--option", "test123", "--option", "test321"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
||||
assert!(m.is_present("option"));
|
||||
assert_eq!(
|
||||
m.values_of("option").unwrap().collect::<Vec<_>>(),
|
||||
vec!["test123", "test321"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn possible_values_of_option_multiple_fail() {
|
||||
let m = Command::new("possible_values")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.possible_value("test123")
|
||||
.possible_value("test321")
|
||||
.multiple_occurrences(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--option", "test123", "--option", "notest"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn possible_values_output() {
|
||||
utils::assert_output(
|
||||
Command::new("test").arg(Arg::new("option").short('O').possible_values([
|
||||
"slow",
|
||||
"fast",
|
||||
"ludicrous speed",
|
||||
])),
|
||||
"clap-test -O slo",
|
||||
PV_ERROR,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn possible_values_alias_output() {
|
||||
utils::assert_output(
|
||||
Command::new("test").arg(
|
||||
Arg::new("option")
|
||||
.short('O')
|
||||
.possible_value("slow")
|
||||
.possible_value(PossibleValue::new("fast").alias("fost"))
|
||||
.possible_value(PossibleValue::new("ludicrous speed").aliases(["ls", "lcs"])),
|
||||
),
|
||||
"clap-test -O slo",
|
||||
PV_ERROR,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn possible_values_hidden_output() {
|
||||
utils::assert_output(
|
||||
Command::new("test").arg(
|
||||
Arg::new("option")
|
||||
.short('O')
|
||||
.possible_values(["slow", "fast"])
|
||||
.possible_value(PossibleValue::new("ludicrous speed"))
|
||||
.possible_value(PossibleValue::new("forbidden speed").hide(true)),
|
||||
),
|
||||
"clap-test -O slo",
|
||||
PV_ERROR,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escaped_possible_values_output() {
|
||||
utils::assert_output(
|
||||
Command::new("test").arg(Arg::new("option").short('O').possible_values([
|
||||
"slow",
|
||||
"fast",
|
||||
"ludicrous speed",
|
||||
])),
|
||||
"clap-test -O ludicrous",
|
||||
PV_ERROR_ESCAPED,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_possible_value_error() {
|
||||
utils::assert_output(
|
||||
Command::new("test").arg(
|
||||
Arg::new("option")
|
||||
.short('O')
|
||||
.possible_value("slow")
|
||||
.possible_value(PossibleValue::new("fast").alias("fost"))
|
||||
.possible_value(PossibleValue::new("ludicrous speed"))
|
||||
.possible_value(PossibleValue::new("forbidden speed").hide(true)),
|
||||
),
|
||||
"clap-test -O",
|
||||
MISSING_PV_ERROR,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
static MISSING_PV_ERROR: &str =
|
||||
"error: The argument '-O <option>' requires a value but none was supplied
|
||||
\t[possible values: slow, fast, \"ludicrous speed\"]
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn alias() {
|
||||
let m = Command::new("pv")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.possible_value(PossibleValue::new("test123").alias("123"))
|
||||
.possible_value("test321")
|
||||
.ignore_case(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["pv", "--option", "123"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert!(m.unwrap().value_of("option").unwrap().eq("123"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn aliases() {
|
||||
let m = Command::new("pv")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.possible_value(PossibleValue::new("test123").aliases(["1", "2", "3"]))
|
||||
.possible_value("test321")
|
||||
.ignore_case(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["pv", "--option", "2"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert!(m.unwrap().value_of("option").unwrap().eq("2"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_case() {
|
||||
let m = Command::new("pv")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.possible_value("test123")
|
||||
.possible_value("test321")
|
||||
.ignore_case(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["pv", "--option", "TeSt123"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert!(m
|
||||
.unwrap()
|
||||
.value_of("option")
|
||||
.unwrap()
|
||||
.eq_ignore_ascii_case("test123"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_case_fail() {
|
||||
let m = Command::new("pv")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.possible_value("test123")
|
||||
.possible_value("test321"),
|
||||
)
|
||||
.try_get_matches_from(vec!["pv", "--option", "TeSt123"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_case_multiple() {
|
||||
let m = Command::new("pv")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.possible_value("test123")
|
||||
.possible_value("test321")
|
||||
.multiple_values(true)
|
||||
.ignore_case(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["pv", "--option", "TeSt123", "teST123", "tESt321"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert_eq!(
|
||||
m.unwrap().values_of("option").unwrap().collect::<Vec<_>>(),
|
||||
&["TeSt123", "teST123", "tESt321"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_case_multiple_fail() {
|
||||
let m = Command::new("pv")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.short('o')
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.possible_value("test123")
|
||||
.possible_value("test321")
|
||||
.multiple_values(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["pv", "--option", "test123", "teST123", "test321"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidValue);
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
use clap::{Arg, ArgMatches, Command};
|
||||
|
||||
fn get_app() -> Command<'static> {
|
||||
Command::new("myprog")
|
||||
.arg(
|
||||
Arg::new("GLOBAL_ARG")
|
||||
.long("global-arg")
|
||||
.help("Specifies something needed by the subcommands")
|
||||
.global(true)
|
||||
.takes_value(true)
|
||||
.default_value("default_value"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("GLOBAL_FLAG")
|
||||
.long("global-flag")
|
||||
.help("Specifies something needed by the subcommands")
|
||||
.global(true)
|
||||
.multiple_occurrences(true),
|
||||
)
|
||||
.subcommand(Command::new("outer").subcommand(Command::new("inner")))
|
||||
}
|
||||
|
||||
fn get_matches(cmd: Command<'static>, argv: &'static str) -> ArgMatches {
|
||||
cmd.try_get_matches_from(argv.split(' ').collect::<Vec<_>>())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn get_outer_matches(m: &ArgMatches) -> &ArgMatches {
|
||||
m.subcommand_matches("outer")
|
||||
.expect("could not access outer subcommand")
|
||||
}
|
||||
|
||||
fn get_inner_matches(m: &ArgMatches) -> &ArgMatches {
|
||||
get_outer_matches(m)
|
||||
.subcommand_matches("inner")
|
||||
.expect("could not access inner subcommand")
|
||||
}
|
||||
|
||||
fn top_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
|
||||
m.value_of("GLOBAL_ARG") == val.into()
|
||||
}
|
||||
|
||||
fn inner_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
|
||||
get_inner_matches(m).value_of("GLOBAL_ARG") == val.into()
|
||||
}
|
||||
|
||||
fn outer_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
|
||||
get_outer_matches(m).value_of("GLOBAL_ARG") == val.into()
|
||||
}
|
||||
|
||||
fn top_can_access_flag(m: &ArgMatches, present: bool, occurrences: u64) -> bool {
|
||||
(m.is_present("GLOBAL_FLAG") == present) && (m.occurrences_of("GLOBAL_FLAG") == occurrences)
|
||||
}
|
||||
|
||||
fn inner_can_access_flag(m: &ArgMatches, present: bool, occurrences: u64) -> bool {
|
||||
let m = get_inner_matches(m);
|
||||
(m.is_present("GLOBAL_FLAG") == present) && (m.occurrences_of("GLOBAL_FLAG") == occurrences)
|
||||
}
|
||||
|
||||
fn outer_can_access_flag(m: &ArgMatches, present: bool, occurrences: u64) -> bool {
|
||||
let m = get_outer_matches(m);
|
||||
(m.is_present("GLOBAL_FLAG") == present) && (m.occurrences_of("GLOBAL_FLAG") == occurrences)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_arg_used_top_level() {
|
||||
let m = get_matches(get_app(), "myprog --global-arg=some_value outer inner");
|
||||
|
||||
assert!(top_can_access_arg(&m, "some_value"));
|
||||
assert!(inner_can_access_arg(&m, "some_value"));
|
||||
assert!(outer_can_access_arg(&m, "some_value"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_arg_used_outer() {
|
||||
let m = get_matches(get_app(), "myprog outer --global-arg=some_value inner");
|
||||
|
||||
assert!(top_can_access_arg(&m, "some_value"));
|
||||
assert!(inner_can_access_arg(&m, "some_value"));
|
||||
assert!(outer_can_access_arg(&m, "some_value"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_arg_used_inner() {
|
||||
let m = get_matches(get_app(), "myprog outer inner --global-arg=some_value");
|
||||
|
||||
assert!(top_can_access_arg(&m, "some_value"));
|
||||
assert!(inner_can_access_arg(&m, "some_value"));
|
||||
assert!(outer_can_access_arg(&m, "some_value"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_arg_default_value() {
|
||||
let m = get_matches(get_app(), "myprog outer inner");
|
||||
|
||||
assert!(top_can_access_arg(&m, "default_value"));
|
||||
assert!(inner_can_access_arg(&m, "default_value"));
|
||||
assert!(outer_can_access_arg(&m, "default_value"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_flag_used_top_level() {
|
||||
let m = get_matches(get_app(), "myprog --global-flag outer inner");
|
||||
|
||||
assert!(top_can_access_flag(&m, true, 1));
|
||||
assert!(inner_can_access_flag(&m, true, 1));
|
||||
assert!(outer_can_access_flag(&m, true, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_flag_used_outer() {
|
||||
let m = get_matches(get_app(), "myprog outer --global-flag inner");
|
||||
|
||||
assert!(top_can_access_flag(&m, true, 1));
|
||||
assert!(inner_can_access_flag(&m, true, 1));
|
||||
assert!(outer_can_access_flag(&m, true, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_flag_used_inner() {
|
||||
let m = get_matches(get_app(), "myprog outer inner --global-flag");
|
||||
|
||||
assert!(top_can_access_flag(&m, true, 1));
|
||||
assert!(inner_can_access_flag(&m, true, 1));
|
||||
assert!(outer_can_access_flag(&m, true, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_flag_2x_used_top_level() {
|
||||
let m = get_matches(get_app(), "myprog --global-flag --global-flag outer inner");
|
||||
|
||||
assert!(top_can_access_flag(&m, true, 2));
|
||||
assert!(inner_can_access_flag(&m, true, 2));
|
||||
assert!(outer_can_access_flag(&m, true, 2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_flag_2x_used_inner() {
|
||||
let m = get_matches(get_app(), "myprog outer inner --global-flag --global-flag");
|
||||
|
||||
assert!(top_can_access_flag(&m, true, 2));
|
||||
assert!(inner_can_access_flag(&m, true, 2));
|
||||
assert!(outer_can_access_flag(&m, true, 2));
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
#![cfg(feature = "regex")]
|
||||
|
||||
use clap::{error::ErrorKind, Arg, Command};
|
||||
use regex::{Regex, RegexSet};
|
||||
|
||||
#[test]
|
||||
fn validator_regex() {
|
||||
let priority = Regex::new(r"[A-C]").unwrap();
|
||||
|
||||
let m = Command::new("prog")
|
||||
.arg(
|
||||
Arg::new("priority")
|
||||
.index(1)
|
||||
.validator_regex(priority, "A, B or C are allowed"),
|
||||
)
|
||||
.try_get_matches_from(vec!["prog", "12345"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.err().unwrap().kind(), ErrorKind::ValueValidation)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validator_regex_with_regex_set() {
|
||||
let priority = RegexSet::new(&[r"[A-C]", r"[X-Z]"]).unwrap();
|
||||
|
||||
let m = Command::new("prog")
|
||||
.arg(
|
||||
Arg::new("priority")
|
||||
.index(1)
|
||||
.validator_regex(priority, "A, B, C, X, Y or Z are allowed"),
|
||||
)
|
||||
.try_get_matches_from(vec!["prog", "12345"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.err().unwrap().kind(), ErrorKind::ValueValidation)
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,696 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use clap::{arg, error::ErrorKind, Arg, Command};
|
||||
|
||||
static VISIBLE_ALIAS_HELP: &str = "clap-test 2.6
|
||||
|
||||
USAGE:
|
||||
clap-test [SUBCOMMAND]
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
|
||||
SUBCOMMANDS:
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
test Some help [aliases: dongle, done]
|
||||
";
|
||||
|
||||
static INVISIBLE_ALIAS_HELP: &str = "clap-test 2.6
|
||||
|
||||
USAGE:
|
||||
clap-test [SUBCOMMAND]
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
|
||||
SUBCOMMANDS:
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
test Some help
|
||||
";
|
||||
|
||||
static SUBCMD_ALPHA_ORDER: &str = "test 1
|
||||
|
||||
USAGE:
|
||||
test [SUBCOMMAND]
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
|
||||
SUBCOMMANDS:
|
||||
a1 blah a1
|
||||
b1 blah b1
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
";
|
||||
|
||||
static SUBCMD_DECL_ORDER: &str = "test 1
|
||||
|
||||
USAGE:
|
||||
test [SUBCOMMAND]
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
|
||||
SUBCOMMANDS:
|
||||
b1 blah b1
|
||||
a1 blah a1
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
";
|
||||
|
||||
#[cfg(feature = "suggestions")]
|
||||
static DYM_SUBCMD: &str = "error: The subcommand 'subcm' wasn't recognized
|
||||
|
||||
Did you mean 'subcmd'?
|
||||
|
||||
If you believe you received this message in error, try re-running with 'dym -- subcm'
|
||||
|
||||
USAGE:
|
||||
dym [SUBCOMMAND]
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
#[cfg(feature = "suggestions")]
|
||||
static DYM_SUBCMD_AMBIGUOUS: &str = "error: The subcommand 'te' wasn't recognized
|
||||
|
||||
Did you mean 'test' or 'temp'?
|
||||
|
||||
If you believe you received this message in error, try re-running with 'dym -- te'
|
||||
|
||||
USAGE:
|
||||
dym [SUBCOMMAND]
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
static SUBCMD_AFTER_DOUBLE_DASH: &str =
|
||||
"error: Found argument 'subcmd' which wasn't expected, or isn't valid in this context
|
||||
|
||||
\tIf you tried to supply `subcmd` as a subcommand, remove the '--' before it.
|
||||
|
||||
USAGE:
|
||||
cmd [SUBCOMMAND]
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn subcommand() {
|
||||
let m = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some").arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.takes_value(true)
|
||||
.help("testing testing"),
|
||||
),
|
||||
)
|
||||
.arg(Arg::new("other").long("other"))
|
||||
.try_get_matches_from(vec!["myprog", "some", "--test", "testing"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(m.subcommand_name().unwrap(), "some");
|
||||
let sub_m = m.subcommand_matches("some").unwrap();
|
||||
assert!(sub_m.is_present("test"));
|
||||
assert_eq!(sub_m.value_of("test").unwrap(), "testing");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subcommand_none_given() {
|
||||
let m = Command::new("test")
|
||||
.subcommand(
|
||||
Command::new("some").arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.takes_value(true)
|
||||
.help("testing testing"),
|
||||
),
|
||||
)
|
||||
.arg(Arg::new("other").long("other"))
|
||||
.try_get_matches_from(vec![""])
|
||||
.unwrap();
|
||||
|
||||
assert!(m.subcommand_name().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subcommand_multiple() {
|
||||
let m = Command::new("test")
|
||||
.subcommands(vec![
|
||||
Command::new("some").arg(
|
||||
Arg::new("test")
|
||||
.short('t')
|
||||
.long("test")
|
||||
.takes_value(true)
|
||||
.help("testing testing"),
|
||||
),
|
||||
Command::new("add").arg(Arg::new("roster").short('r')),
|
||||
])
|
||||
.arg(Arg::new("other").long("other"))
|
||||
.try_get_matches_from(vec!["myprog", "some", "--test", "testing"])
|
||||
.unwrap();
|
||||
|
||||
assert!(m.subcommand_matches("some").is_some());
|
||||
assert!(m.subcommand_matches("add").is_none());
|
||||
assert_eq!(m.subcommand_name().unwrap(), "some");
|
||||
let sub_m = m.subcommand_matches("some").unwrap();
|
||||
assert!(sub_m.is_present("test"));
|
||||
assert_eq!(sub_m.value_of("test").unwrap(), "testing");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subcommand_display_order() {
|
||||
let app_subcmd_alpha_order = Command::new("test").version("1").subcommands(vec![
|
||||
Command::new("b1")
|
||||
.about("blah b1")
|
||||
.arg(Arg::new("test").short('t')),
|
||||
Command::new("a1")
|
||||
.about("blah a1")
|
||||
.arg(Arg::new("roster").short('r')),
|
||||
]);
|
||||
|
||||
utils::assert_output(
|
||||
app_subcmd_alpha_order,
|
||||
"test --help",
|
||||
SUBCMD_ALPHA_ORDER,
|
||||
false,
|
||||
);
|
||||
|
||||
let app_subcmd_decl_order = Command::new("test")
|
||||
.version("1")
|
||||
.setting(clap::AppSettings::DeriveDisplayOrder)
|
||||
.subcommands(vec![
|
||||
Command::new("b1")
|
||||
.about("blah b1")
|
||||
.arg(Arg::new("test").short('t')),
|
||||
Command::new("a1")
|
||||
.about("blah a1")
|
||||
.arg(Arg::new("roster").short('r')),
|
||||
]);
|
||||
|
||||
utils::assert_output(
|
||||
app_subcmd_decl_order,
|
||||
"test --help",
|
||||
SUBCMD_DECL_ORDER,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_alias() {
|
||||
let m = Command::new("myprog")
|
||||
.subcommand(Command::new("test").alias("do-stuff"))
|
||||
.try_get_matches_from(vec!["myprog", "do-stuff"])
|
||||
.unwrap();
|
||||
assert_eq!(m.subcommand_name(), Some("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_aliases() {
|
||||
let m = Command::new("myprog")
|
||||
.subcommand(Command::new("test").aliases(&["do-stuff", "test-stuff"]))
|
||||
.try_get_matches_from(vec!["myprog", "test-stuff"])
|
||||
.unwrap();
|
||||
assert_eq!(m.subcommand_name(), Some("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "suggestions")]
|
||||
fn subcmd_did_you_mean_output() {
|
||||
let cmd = Command::new("dym").subcommand(Command::new("subcmd"));
|
||||
utils::assert_output(cmd, "dym subcm", DYM_SUBCMD, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "suggestions")]
|
||||
fn subcmd_did_you_mean_output_ambiguous() {
|
||||
let cmd = Command::new("dym")
|
||||
.subcommand(Command::new("test"))
|
||||
.subcommand(Command::new("temp"));
|
||||
utils::assert_output(cmd, "dym te", DYM_SUBCMD_AMBIGUOUS, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "suggestions")]
|
||||
fn subcmd_did_you_mean_output_arg() {
|
||||
static EXPECTED: &str =
|
||||
"error: Found argument '--subcmarg' which wasn't expected, or isn't valid in this context
|
||||
|
||||
\tDid you mean to put '--subcmdarg' after the subcommand 'subcmd'?
|
||||
|
||||
\tIf you tried to supply `--subcmarg` as a value rather than a flag, use `-- --subcmarg`
|
||||
|
||||
USAGE:
|
||||
dym [SUBCOMMAND]
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
let cmd = Command::new("dym").subcommand(
|
||||
Command::new("subcmd").arg(arg!(-s --subcmdarg <subcmdarg> "tests").required(false)),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "dym --subcmarg subcmd", EXPECTED, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "suggestions")]
|
||||
fn subcmd_did_you_mean_output_arg_false_positives() {
|
||||
static EXPECTED: &str =
|
||||
"error: Found argument '--subcmarg' which wasn't expected, or isn't valid in this context
|
||||
|
||||
\tIf you tried to supply `--subcmarg` as a value rather than a flag, use `-- --subcmarg`
|
||||
|
||||
USAGE:
|
||||
dym [SUBCOMMAND]
|
||||
|
||||
For more information try --help
|
||||
";
|
||||
|
||||
let cmd = Command::new("dym").subcommand(
|
||||
Command::new("subcmd").arg(arg!(-s --subcmdarg <subcmdarg> "tests").required(false)),
|
||||
);
|
||||
|
||||
utils::assert_output(cmd, "dym --subcmarg foo", EXPECTED, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn alias_help() {
|
||||
let m = Command::new("myprog")
|
||||
.subcommand(Command::new("test").alias("do-stuff"))
|
||||
.try_get_matches_from(vec!["myprog", "help", "do-stuff"]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::DisplayHelp);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn visible_aliases_help_output() {
|
||||
let cmd = Command::new("clap-test").version("2.6").subcommand(
|
||||
Command::new("test")
|
||||
.about("Some help")
|
||||
.alias("invisible")
|
||||
.visible_alias("dongle")
|
||||
.visible_alias("done"),
|
||||
);
|
||||
utils::assert_output(cmd, "clap-test --help", VISIBLE_ALIAS_HELP, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invisible_aliases_help_output() {
|
||||
let cmd = Command::new("clap-test")
|
||||
.version("2.6")
|
||||
.subcommand(Command::new("test").about("Some help").alias("invisible"));
|
||||
utils::assert_output(cmd, "clap-test --help", INVISIBLE_ALIAS_HELP, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "unstable-replace")]
|
||||
fn replace() {
|
||||
let m = Command::new("prog")
|
||||
.subcommand(
|
||||
Command::new("module").subcommand(Command::new("install").about("Install module")),
|
||||
)
|
||||
.replace("install", &["module", "install"])
|
||||
.try_get_matches_from(vec!["prog", "install"])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(m.subcommand_name(), Some("module"));
|
||||
assert_eq!(
|
||||
m.subcommand_matches("module").unwrap().subcommand_name(),
|
||||
Some("install")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1031_args_with_same_name() {
|
||||
let res = Command::new("prog")
|
||||
.arg(arg!(--"ui-path" <PATH>))
|
||||
.subcommand(Command::new("signer"))
|
||||
.try_get_matches_from(vec!["prog", "--ui-path", "signer"]);
|
||||
|
||||
assert!(res.is_ok(), "{:?}", res.unwrap_err().kind());
|
||||
let m = res.unwrap();
|
||||
assert_eq!(m.value_of("ui-path"), Some("signer"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1031_args_with_same_name_no_more_vals() {
|
||||
let res = Command::new("prog")
|
||||
.arg(arg!(--"ui-path" <PATH>))
|
||||
.subcommand(Command::new("signer"))
|
||||
.try_get_matches_from(vec!["prog", "--ui-path", "value", "signer"]);
|
||||
|
||||
assert!(res.is_ok(), "{:?}", res.unwrap_err().kind());
|
||||
let m = res.unwrap();
|
||||
assert_eq!(m.value_of("ui-path"), Some("value"));
|
||||
assert_eq!(m.subcommand_name(), Some("signer"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1161_multiple_hyphen_hyphen() {
|
||||
// from example 22
|
||||
let res = Command::new("myprog")
|
||||
.arg(Arg::new("eff").short('f'))
|
||||
.arg(Arg::new("pea").short('p').takes_value(true))
|
||||
.arg(
|
||||
Arg::new("slop")
|
||||
.takes_value(true)
|
||||
.multiple_values(true)
|
||||
.last(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
"-f",
|
||||
"-p=bob",
|
||||
"--",
|
||||
"sloppy",
|
||||
"slop",
|
||||
"-a",
|
||||
"--",
|
||||
"subprogram",
|
||||
"position",
|
||||
"args",
|
||||
]);
|
||||
|
||||
assert!(res.is_ok(), "{:?}", res.unwrap_err().kind());
|
||||
let m = res.unwrap();
|
||||
|
||||
let expected = Some(vec![
|
||||
"sloppy",
|
||||
"slop",
|
||||
"-a",
|
||||
"--",
|
||||
"subprogram",
|
||||
"position",
|
||||
"args",
|
||||
]);
|
||||
let actual = m.values_of("slop").map(|vals| vals.collect::<Vec<_>>());
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1722_not_emit_error_when_arg_follows_similar_to_a_subcommand() {
|
||||
let m = Command::new("myprog")
|
||||
.subcommand(Command::new("subcommand"))
|
||||
.arg(Arg::new("argument"))
|
||||
.try_get_matches_from(vec!["myprog", "--", "subcommand"]);
|
||||
assert_eq!(m.unwrap().value_of("argument"), Some("subcommand"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subcommand_placeholder_test() {
|
||||
let mut cmd = Command::new("myprog")
|
||||
.subcommand(Command::new("subcommand"))
|
||||
.subcommand_value_name("TEST_PLACEHOLDER")
|
||||
.subcommand_help_heading("TEST_HEADER");
|
||||
|
||||
assert_eq!(&cmd.render_usage(), "USAGE:\n myprog [TEST_PLACEHOLDER]");
|
||||
|
||||
let mut help_text = Vec::new();
|
||||
cmd.write_help(&mut help_text)
|
||||
.expect("Failed to write to internal buffer");
|
||||
|
||||
assert!(String::from_utf8(help_text)
|
||||
.unwrap()
|
||||
.contains("TEST_HEADER:"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subcommand_used_after_double_dash() {
|
||||
let cmd = Command::new("cmd").subcommand(Command::new("subcmd"));
|
||||
|
||||
utils::assert_output(cmd, "cmd -- subcmd", SUBCMD_AFTER_DOUBLE_DASH, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subcommand_after_argument() {
|
||||
let m = Command::new("myprog")
|
||||
.arg(Arg::new("some_text"))
|
||||
.subcommand(Command::new("test"))
|
||||
.try_get_matches_from(vec!["myprog", "teat", "test"])
|
||||
.unwrap();
|
||||
assert_eq!(m.value_of("some_text"), Some("teat"));
|
||||
assert_eq!(m.subcommand().unwrap().0, "test");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subcommand_after_argument_looks_like_help() {
|
||||
let m = Command::new("myprog")
|
||||
.arg(Arg::new("some_text"))
|
||||
.subcommand(Command::new("test"))
|
||||
.try_get_matches_from(vec!["myprog", "helt", "test"])
|
||||
.unwrap();
|
||||
assert_eq!(m.value_of("some_text"), Some("helt"));
|
||||
assert_eq!(m.subcommand().unwrap().0, "test");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_2494_subcommand_is_present() {
|
||||
let cmd = Command::new("opt")
|
||||
.arg(Arg::new("global").long("global"))
|
||||
.subcommand(Command::new("global"));
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["opt", "--global", "global"])
|
||||
.unwrap();
|
||||
assert_eq!(m.subcommand_name().unwrap(), "global");
|
||||
assert!(m.is_present("global"));
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["opt", "--global"])
|
||||
.unwrap();
|
||||
assert!(m.subcommand_name().is_none());
|
||||
assert!(m.is_present("global"));
|
||||
|
||||
let m = cmd.try_get_matches_from(&["opt", "global"]).unwrap();
|
||||
assert_eq!(m.subcommand_name().unwrap(), "global");
|
||||
assert!(!m.is_present("global"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subcommand_not_recognized() {
|
||||
let cmd = Command::new("fake")
|
||||
.subcommand(Command::new("sub"))
|
||||
.disable_help_subcommand(true)
|
||||
.infer_subcommands(true);
|
||||
utils::assert_output(
|
||||
cmd,
|
||||
"fake help",
|
||||
"error: The subcommand 'help' wasn't recognized
|
||||
|
||||
USAGE:
|
||||
fake [SUBCOMMAND]
|
||||
|
||||
For more information try --help
|
||||
",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-multicall")]
|
||||
#[test]
|
||||
fn busybox_like_multicall() {
|
||||
fn applet_commands() -> [Command<'static>; 2] {
|
||||
[Command::new("true"), Command::new("false")]
|
||||
}
|
||||
let cmd = Command::new("busybox")
|
||||
.multicall(true)
|
||||
.subcommand(Command::new("busybox").subcommands(applet_commands()))
|
||||
.subcommands(applet_commands());
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["busybox", "true"])
|
||||
.unwrap();
|
||||
assert_eq!(m.subcommand_name(), Some("busybox"));
|
||||
assert_eq!(m.subcommand().unwrap().1.subcommand_name(), Some("true"));
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(&["true"]).unwrap();
|
||||
assert_eq!(m.subcommand_name(), Some("true"));
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(&["a.out"]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::UnrecognizedSubcommand);
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-multicall")]
|
||||
#[test]
|
||||
fn hostname_like_multicall() {
|
||||
let mut cmd = Command::new("hostname")
|
||||
.multicall(true)
|
||||
.subcommand(Command::new("hostname"))
|
||||
.subcommand(Command::new("dnsdomainname"));
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(&["hostname"]).unwrap();
|
||||
assert_eq!(m.subcommand_name(), Some("hostname"));
|
||||
|
||||
let m = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["dnsdomainname"])
|
||||
.unwrap();
|
||||
assert_eq!(m.subcommand_name(), Some("dnsdomainname"));
|
||||
|
||||
let m = cmd.clone().try_get_matches_from(&["a.out"]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::UnrecognizedSubcommand);
|
||||
|
||||
let m = cmd.try_get_matches_from_mut(&["hostname", "hostname"]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::UnknownArgument);
|
||||
|
||||
let m = cmd.try_get_matches_from(&["hostname", "dnsdomainname"]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind(), ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-multicall")]
|
||||
#[test]
|
||||
fn bad_multicall_command_error() {
|
||||
let cmd = Command::new("repl")
|
||||
.version("1.0.0")
|
||||
.propagate_version(true)
|
||||
.multicall(true)
|
||||
.subcommand(Command::new("foo"))
|
||||
.subcommand(Command::new("bar"));
|
||||
|
||||
let err = cmd.clone().try_get_matches_from(&["world"]).unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::UnrecognizedSubcommand);
|
||||
static HELLO_EXPECTED: &str = "\
|
||||
error: The subcommand 'world' wasn't recognized
|
||||
|
||||
USAGE:
|
||||
<SUBCOMMAND>
|
||||
|
||||
For more information try help
|
||||
";
|
||||
utils::assert_eq(HELLO_EXPECTED, err.to_string());
|
||||
|
||||
let err = cmd.clone().try_get_matches_from(&["baz"]).unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::InvalidSubcommand);
|
||||
static BAZ_EXPECTED: &str = "\
|
||||
error: The subcommand 'baz' wasn't recognized
|
||||
|
||||
\tDid you mean 'bar'?
|
||||
|
||||
If you believe you received this message in error, try re-running with ' -- baz'
|
||||
|
||||
USAGE:
|
||||
<SUBCOMMAND>
|
||||
|
||||
For more information try help
|
||||
";
|
||||
utils::assert_eq(BAZ_EXPECTED, err.to_string());
|
||||
|
||||
// Verify whatever we did to get the above to work didn't disable `--help` and `--version`.
|
||||
|
||||
let err = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["foo", "--help"])
|
||||
.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayHelp);
|
||||
|
||||
let err = cmd
|
||||
.clone()
|
||||
.try_get_matches_from(&["foo", "--version"])
|
||||
.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayVersion);
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-multicall")]
|
||||
#[test]
|
||||
#[should_panic = "Command repl: Arguments like oh-no cannot be set on a multicall command"]
|
||||
fn cant_have_args_with_multicall() {
|
||||
let mut cmd = Command::new("repl")
|
||||
.version("1.0.0")
|
||||
.propagate_version(true)
|
||||
.multicall(true)
|
||||
.subcommand(Command::new("foo"))
|
||||
.subcommand(Command::new("bar"))
|
||||
.arg(Arg::new("oh-no"));
|
||||
cmd.build();
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-multicall")]
|
||||
#[test]
|
||||
fn multicall_help_flag() {
|
||||
static EXPECTED: &str = "\
|
||||
foo-bar 1.0.0
|
||||
|
||||
USAGE:
|
||||
foo bar [value]
|
||||
|
||||
ARGS:
|
||||
<value>
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
let cmd = Command::new("repl")
|
||||
.version("1.0.0")
|
||||
.propagate_version(true)
|
||||
.multicall(true)
|
||||
.subcommand(Command::new("foo").subcommand(Command::new("bar").arg(Arg::new("value"))));
|
||||
utils::assert_output(cmd, "foo bar --help", EXPECTED, false);
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-multicall")]
|
||||
#[test]
|
||||
fn multicall_help_subcommand() {
|
||||
static EXPECTED: &str = "\
|
||||
foo-bar 1.0.0
|
||||
|
||||
USAGE:
|
||||
foo bar [value]
|
||||
|
||||
ARGS:
|
||||
<value>
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
let cmd = Command::new("repl")
|
||||
.version("1.0.0")
|
||||
.propagate_version(true)
|
||||
.multicall(true)
|
||||
.subcommand(Command::new("foo").subcommand(Command::new("bar").arg(Arg::new("value"))));
|
||||
utils::assert_output(cmd, "help foo bar", EXPECTED, false);
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-multicall")]
|
||||
#[test]
|
||||
fn multicall_render_help() {
|
||||
static EXPECTED: &str = "\
|
||||
foo-bar 1.0.0
|
||||
|
||||
USAGE:
|
||||
foo bar [value]
|
||||
|
||||
ARGS:
|
||||
<value>
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
let mut cmd = Command::new("repl")
|
||||
.version("1.0.0")
|
||||
.propagate_version(true)
|
||||
.multicall(true)
|
||||
.subcommand(Command::new("foo").subcommand(Command::new("bar").arg(Arg::new("value"))));
|
||||
cmd.build();
|
||||
let subcmd = cmd.find_subcommand_mut("foo").unwrap();
|
||||
let subcmd = subcmd.find_subcommand_mut("bar").unwrap();
|
||||
|
||||
let mut buf = Vec::new();
|
||||
subcmd.write_help(&mut buf).unwrap();
|
||||
utils::assert_eq(EXPECTED, String::from_utf8(buf).unwrap());
|
||||
}
|
|
@ -1,149 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use clap::{arg, Command};
|
||||
|
||||
static EXAMPLE1_TMPL_S: &str = "{bin} {version}
|
||||
{author}
|
||||
{about}
|
||||
|
||||
USAGE:
|
||||
{usage}
|
||||
|
||||
{all-args}";
|
||||
|
||||
static EXAMPLE1_TMPS_F: &str = "{bin} {version}
|
||||
{author}
|
||||
{about}
|
||||
|
||||
USAGE:
|
||||
{usage}
|
||||
|
||||
OPTIONS:
|
||||
{options}
|
||||
ARGS:
|
||||
{positionals}
|
||||
SUBCOMMANDS:
|
||||
{subcommands}";
|
||||
|
||||
static CUSTOM_TEMPL_HELP: &str = "MyApp 1.0
|
||||
Kevin K. <kbknapp@gmail.com>
|
||||
Does awesome things
|
||||
|
||||
USAGE:
|
||||
MyApp [OPTIONS] <output> [SUBCOMMAND]
|
||||
|
||||
OPTIONS:
|
||||
-c, --config <FILE> Sets a custom config file
|
||||
-d Turn debugging information on
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
ARGS:
|
||||
<output> Sets an optional output file
|
||||
SUBCOMMANDS:
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
test does testing things
|
||||
";
|
||||
|
||||
static SIMPLE_TEMPLATE: &str = "MyApp 1.0
|
||||
Kevin K. <kbknapp@gmail.com>
|
||||
Does awesome things
|
||||
|
||||
USAGE:
|
||||
MyApp [OPTIONS] <output> [SUBCOMMAND]
|
||||
|
||||
ARGS:
|
||||
<output> Sets an optional output file
|
||||
|
||||
OPTIONS:
|
||||
-c, --config <FILE> Sets a custom config file
|
||||
-d Turn debugging information on
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
|
||||
SUBCOMMANDS:
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
test does testing things
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn with_template() {
|
||||
let cmd = get_app().help_template(EXAMPLE1_TMPL_S);
|
||||
utils::assert_output(cmd, "MyApp --help", SIMPLE_TEMPLATE, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_template() {
|
||||
let cmd = get_app().help_template(EXAMPLE1_TMPS_F);
|
||||
utils::assert_output(cmd, "MyApp --help", CUSTOM_TEMPL_HELP, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn template_empty() {
|
||||
let cmd = Command::new("MyApp")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.help_template("");
|
||||
utils::assert_output(cmd, "MyApp --help", "\n", false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn template_notag() {
|
||||
let cmd = Command::new("MyApp")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.help_template("test no tag test");
|
||||
utils::assert_output(cmd, "MyApp --help", "test no tag test\n", false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn template_unknowntag() {
|
||||
let cmd = Command::new("MyApp")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.help_template("test {unknown_tag} test");
|
||||
utils::assert_output(cmd, "MyApp --help", "test {unknown_tag} test\n", false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn template_author_version() {
|
||||
let cmd = Command::new("MyApp")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.help_template("{author}\n{version}\n{about}\n{bin}");
|
||||
utils::assert_output(
|
||||
cmd,
|
||||
"MyApp --help",
|
||||
"Kevin K. <kbknapp@gmail.com>\n1.0\nDoes awesome things\nMyApp\n",
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
// ----------
|
||||
|
||||
fn get_app() -> Command<'static> {
|
||||
Command::new("MyApp")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.arg(
|
||||
arg!(
|
||||
-c --config <FILE> "Sets a custom config file"
|
||||
)
|
||||
.required(false),
|
||||
)
|
||||
.arg(arg!(
|
||||
<output> "Sets an optional output file"
|
||||
))
|
||||
.arg(arg!(
|
||||
d: -d ... "Turn debugging information on"
|
||||
))
|
||||
.subcommand(
|
||||
Command::new("test")
|
||||
.about("does testing things")
|
||||
.arg(arg!(-l --list "lists test values")),
|
||||
)
|
||||
}
|
|
@ -1,426 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use std::io::Write;
|
||||
use std::str;
|
||||
|
||||
use clap::{Arg, Command};
|
||||
|
||||
static SCF2OP: &str = "flag present 2 times
|
||||
option NOT present
|
||||
positional NOT present
|
||||
flag2 NOT present
|
||||
option2 maybe present with value of: Nothing
|
||||
positional2 maybe present with value of: Nothing
|
||||
option3 NOT present
|
||||
positional3 NOT present
|
||||
option NOT present
|
||||
positional NOT present
|
||||
subcmd present
|
||||
flag present 2 times
|
||||
scoption present with value: some
|
||||
An scoption: some
|
||||
scpositional present with value: value
|
||||
";
|
||||
|
||||
static SCFOP: &str = "flag present 1 times
|
||||
option NOT present
|
||||
positional NOT present
|
||||
flag2 NOT present
|
||||
option2 maybe present with value of: Nothing
|
||||
positional2 maybe present with value of: Nothing
|
||||
option3 NOT present
|
||||
positional3 NOT present
|
||||
option NOT present
|
||||
positional NOT present
|
||||
subcmd present
|
||||
flag present 1 times
|
||||
scoption present with value: some
|
||||
An scoption: some
|
||||
scpositional present with value: value
|
||||
";
|
||||
|
||||
static O2P: &str = "flag NOT present
|
||||
option present 2 times with value: some
|
||||
An option: some
|
||||
An option: other
|
||||
positional present with value: value
|
||||
flag2 NOT present
|
||||
option2 maybe present with value of: Nothing
|
||||
positional2 maybe present with value of: Nothing
|
||||
option3 NOT present
|
||||
positional3 NOT present
|
||||
option present 2 times with value: some
|
||||
An option: some
|
||||
An option: other
|
||||
positional present with value: value
|
||||
subcmd NOT present
|
||||
";
|
||||
|
||||
static F2OP: &str = "flag present 2 times
|
||||
option present 1 times with value: some
|
||||
An option: some
|
||||
positional present with value: value
|
||||
flag2 NOT present
|
||||
option2 maybe present with value of: Nothing
|
||||
positional2 maybe present with value of: Nothing
|
||||
option3 NOT present
|
||||
positional3 NOT present
|
||||
option present 1 times with value: some
|
||||
An option: some
|
||||
positional present with value: value
|
||||
subcmd NOT present
|
||||
";
|
||||
|
||||
static FOP: &str = "flag present 1 times
|
||||
option present 1 times with value: some
|
||||
An option: some
|
||||
positional present with value: value
|
||||
flag2 NOT present
|
||||
option2 maybe present with value of: Nothing
|
||||
positional2 maybe present with value of: Nothing
|
||||
option3 NOT present
|
||||
positional3 NOT present
|
||||
option present 1 times with value: some
|
||||
An option: some
|
||||
positional present with value: value
|
||||
subcmd NOT present
|
||||
";
|
||||
|
||||
pub fn check_complex_output(args: &str, out: &str) {
|
||||
let mut w = vec![];
|
||||
let matches = utils::complex_app()
|
||||
.try_get_matches_from(args.split(' ').collect::<Vec<_>>())
|
||||
.unwrap();
|
||||
if matches.is_present("flag") {
|
||||
writeln!(w, "flag present {} times", matches.occurrences_of("flag")).unwrap();
|
||||
} else {
|
||||
writeln!(w, "flag NOT present").unwrap();
|
||||
}
|
||||
|
||||
if matches.is_present("option") {
|
||||
if let Some(v) = matches.value_of("option") {
|
||||
writeln!(
|
||||
w,
|
||||
"option present {} times with value: {}",
|
||||
matches.occurrences_of("option"),
|
||||
v
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
if let Some(ov) = matches.values_of("option") {
|
||||
for o in ov {
|
||||
writeln!(w, "An option: {}", o).unwrap();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
writeln!(w, "option NOT present").unwrap();
|
||||
}
|
||||
|
||||
if let Some(p) = matches.value_of("positional") {
|
||||
writeln!(w, "positional present with value: {}", p).unwrap();
|
||||
} else {
|
||||
writeln!(w, "positional NOT present").unwrap();
|
||||
}
|
||||
|
||||
if matches.is_present("flag2") {
|
||||
writeln!(w, "flag2 present").unwrap();
|
||||
writeln!(
|
||||
w,
|
||||
"option2 present with value of: {}",
|
||||
matches.value_of("long-option-2").unwrap()
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
w,
|
||||
"positional2 present with value of: {}",
|
||||
matches.value_of("positional2").unwrap()
|
||||
)
|
||||
.unwrap();
|
||||
} else {
|
||||
writeln!(w, "flag2 NOT present").unwrap();
|
||||
writeln!(
|
||||
w,
|
||||
"option2 maybe present with value of: {}",
|
||||
matches.value_of("long-option-2").unwrap_or("Nothing")
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
w,
|
||||
"positional2 maybe present with value of: {}",
|
||||
matches.value_of("positional2").unwrap_or("Nothing")
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let _ = match matches.value_of("option3").unwrap_or("") {
|
||||
"fast" => writeln!(w, "option3 present quickly"),
|
||||
"slow" => writeln!(w, "option3 present slowly"),
|
||||
_ => writeln!(w, "option3 NOT present"),
|
||||
};
|
||||
|
||||
let _ = match matches.value_of("positional3").unwrap_or("") {
|
||||
"vi" => writeln!(w, "positional3 present in vi mode"),
|
||||
"emacs" => writeln!(w, "positional3 present in emacs mode"),
|
||||
_ => writeln!(w, "positional3 NOT present"),
|
||||
};
|
||||
|
||||
if matches.is_present("option") {
|
||||
if let Some(v) = matches.value_of("option") {
|
||||
writeln!(
|
||||
w,
|
||||
"option present {} times with value: {}",
|
||||
matches.occurrences_of("option"),
|
||||
v
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
if let Some(ov) = matches.values_of("option") {
|
||||
for o in ov {
|
||||
writeln!(w, "An option: {}", o).unwrap();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
writeln!(w, "option NOT present").unwrap();
|
||||
}
|
||||
|
||||
if let Some(p) = matches.value_of("positional") {
|
||||
writeln!(w, "positional present with value: {}", p).unwrap();
|
||||
} else {
|
||||
writeln!(w, "positional NOT present").unwrap();
|
||||
}
|
||||
if let Some("subcmd") = matches.subcommand_name() {
|
||||
writeln!(w, "subcmd present").unwrap();
|
||||
if let Some(matches) = matches.subcommand_matches("subcmd") {
|
||||
if matches.is_present("flag") {
|
||||
writeln!(w, "flag present {} times", matches.occurrences_of("flag")).unwrap();
|
||||
} else {
|
||||
writeln!(w, "flag NOT present").unwrap();
|
||||
}
|
||||
|
||||
if matches.is_present("option") {
|
||||
if let Some(v) = matches.value_of("option") {
|
||||
writeln!(w, "scoption present with value: {}", v).unwrap();
|
||||
}
|
||||
if let Some(ov) = matches.values_of("option") {
|
||||
for o in ov {
|
||||
writeln!(w, "An scoption: {}", o).unwrap();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
writeln!(w, "scoption NOT present").unwrap();
|
||||
}
|
||||
|
||||
if let Some(p) = matches.value_of("scpositional") {
|
||||
writeln!(w, "scpositional present with value: {}", p).unwrap();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
writeln!(w, "subcmd NOT present").unwrap();
|
||||
}
|
||||
|
||||
let res = str::from_utf8(&w).unwrap();
|
||||
assert_eq!(res, out);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_app() {
|
||||
let _ = Command::new("test")
|
||||
.version("1.0")
|
||||
.author("kevin")
|
||||
.about("does awesome things")
|
||||
.try_get_matches_from(vec![""])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_multiple_arg() {
|
||||
let _ = Command::new("test")
|
||||
.args(&[Arg::new("test").short('s'), Arg::new("test2").short('l')])
|
||||
.try_get_matches_from(vec![""])
|
||||
.unwrap();
|
||||
}
|
||||
#[test]
|
||||
fn flag_x2_opt() {
|
||||
check_complex_output(
|
||||
"clap-test value -f -f -o some",
|
||||
"flag present 2 times
|
||||
option present 1 times with value: some
|
||||
An option: some
|
||||
positional present with value: value
|
||||
flag2 NOT present
|
||||
option2 maybe present with value of: Nothing
|
||||
positional2 maybe present with value of: Nothing
|
||||
option3 NOT present
|
||||
positional3 NOT present
|
||||
option present 1 times with value: some
|
||||
An option: some
|
||||
positional present with value: value
|
||||
subcmd NOT present
|
||||
",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn long_opt_x2_pos() {
|
||||
check_complex_output("clap-test value --option some --option other", O2P);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn long_opt_eq_x2_pos() {
|
||||
check_complex_output("clap-test value --option=some --option=other", O2P);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_opt_x2_pos() {
|
||||
check_complex_output("clap-test value -o some -o other", O2P);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_opt_eq_x2_pos() {
|
||||
check_complex_output("clap-test value -o=some -o=other", O2P);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_flag_x2_comb_short_opt_pos() {
|
||||
check_complex_output("clap-test value -ff -o some", F2OP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_flag_short_opt_pos() {
|
||||
check_complex_output("clap-test value -f -o some", FOP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn long_flag_long_opt_pos() {
|
||||
check_complex_output("clap-test value --flag --option some", FOP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn long_flag_long_opt_eq_pos() {
|
||||
check_complex_output("clap-test value --flag --option=some", FOP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_long_flag_long_opt() {
|
||||
check_complex_output("clap-test subcmd value --flag --option some", SCFOP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_long_flag_short_opt_pos() {
|
||||
check_complex_output("clap-test subcmd value --flag -o some", SCFOP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_long_flag_long_opt_eq_pos() {
|
||||
check_complex_output("clap-test subcmd value --flag --option=some", SCFOP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_short_flag_long_opt_pos() {
|
||||
check_complex_output("clap-test subcmd value -f --option some", SCFOP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_short_flag_short_opt_pos() {
|
||||
check_complex_output("clap-test subcmd value -f -o some", SCFOP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_short_flag_short_opt_eq_pos() {
|
||||
check_complex_output("clap-test subcmd value -f -o=some", SCFOP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_short_flag_long_opt_eq_pos() {
|
||||
check_complex_output("clap-test subcmd value -f --option=some", SCFOP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_short_flag_x2_comb_long_opt_pos() {
|
||||
check_complex_output("clap-test subcmd value -ff --option some", SCF2OP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_short_flag_x2_comb_short_opt_pos() {
|
||||
check_complex_output("clap-test subcmd value -ff -o some", SCF2OP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_short_flag_x2_comb_long_opt_eq_pos() {
|
||||
check_complex_output("clap-test subcmd value -ff --option=some", SCF2OP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_short_flag_x2_comb_short_opt_eq_pos() {
|
||||
check_complex_output("clap-test subcmd value -ff -o=some", SCF2OP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_long_flag_x2_long_opt_pos() {
|
||||
check_complex_output("clap-test subcmd value --flag --flag --option some", SCF2OP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_long_flag_x2_short_opt_pos() {
|
||||
check_complex_output("clap-test subcmd value --flag --flag -o some", SCF2OP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_long_flag_x2_short_opt_eq_pos() {
|
||||
check_complex_output("clap-test subcmd value --flag --flag -o=some", SCF2OP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_long_flag_x2_long_opt_eq_pos() {
|
||||
check_complex_output("clap-test subcmd value --flag --flag --option=some", SCF2OP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_short_flag_x2_long_opt_pos() {
|
||||
check_complex_output("clap-test subcmd value -f -f --option some", SCF2OP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_short_flag_x2_short_opt_pos() {
|
||||
check_complex_output("clap-test subcmd value -f -f -o some", SCF2OP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_short_flag_x2_short_opt_eq_pos() {
|
||||
check_complex_output("clap-test subcmd value -f -f -o=some", SCF2OP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sc_short_flag_x2_long_opt_eq_pos() {
|
||||
check_complex_output("clap-test subcmd value -f -f --option=some", SCF2OP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mut_arg_all() {
|
||||
let mut cmd = utils::complex_app();
|
||||
let arg_names = cmd
|
||||
.get_arguments()
|
||||
.map(|a| a.get_id())
|
||||
.filter(|a| *a != "version" && *a != "help")
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for arg_name in arg_names {
|
||||
cmd = cmd.mut_arg(arg_name, |arg| arg.hide_possible_values(true));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_3669_command_build_recurses() {
|
||||
let mut cmd = Command::new("ctest").subcommand(
|
||||
Command::new("subcmd").subcommand(
|
||||
Command::new("multi")
|
||||
.about("tests subcommands")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.version("0.1")
|
||||
.arg(clap::arg!(
|
||||
<FLAG> "tests flags"
|
||||
)),
|
||||
),
|
||||
);
|
||||
cmd.build();
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#![cfg(feature = "unicode")]
|
||||
|
||||
#[test]
|
||||
fn possible_values_ignore_case() {
|
||||
let m = clap::Command::new("pv")
|
||||
.arg(
|
||||
clap::Arg::new("option")
|
||||
.short('o')
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.possible_value("ä")
|
||||
.ignore_case(true),
|
||||
)
|
||||
.try_get_matches_from(vec!["pv", "--option", "Ä"]);
|
||||
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
assert!(m.unwrap().value_of("option").is_some());
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument names must be unique, but 'arg1' is in use by more than one argument or group"]
|
||||
fn unique_arg_names() {
|
||||
use clap::{Arg, Command};
|
||||
|
||||
let _ = Command::new("some")
|
||||
.args(&[Arg::new("arg1").short('a'), Arg::new("arg1").short('b')])
|
||||
.try_get_matches();
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Short option names must be unique for each argument, but '-a' is in use by both 'arg1' and 'arg2'"]
|
||||
fn unique_arg_shorts() {
|
||||
use clap::{Arg, Command};
|
||||
|
||||
let _ = Command::new("some")
|
||||
.args(&[Arg::new("arg1").short('a'), Arg::new("arg2").short('a')])
|
||||
.try_get_matches();
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Long option names must be unique for each argument, but '--long' is in use by both 'arg1' and 'arg2'"]
|
||||
fn unique_arg_longs() {
|
||||
use clap::{Arg, Command};
|
||||
|
||||
let _ = Command::new("some")
|
||||
.args(&[Arg::new("arg1").long("long"), Arg::new("arg2").long("long")])
|
||||
.try_get_matches();
|
||||
}
|
|
@ -1,169 +0,0 @@
|
|||
//! These Windows-only tests are ported from the Unix-only tests in
|
||||
//! tests/utf16.rs. The tests that use StrictUtf8 mode are omitted here,
|
||||
//! because that's a Unix-only feature.
|
||||
|
||||
#![cfg(windows)]
|
||||
|
||||
use clap::{arg, Command};
|
||||
use std::ffi::OsString;
|
||||
use std::os::windows::ffi::OsStringExt;
|
||||
|
||||
// Take a slice of ASCII bytes, convert them to UTF-16, and then append a
|
||||
// dangling surrogate character to make the result invalid UTF-16.
|
||||
fn bad_osstring(ascii: &[u8]) -> OsString {
|
||||
let mut wide_chars: Vec<u16> = ascii.iter().map(|&c| c as u16).collect();
|
||||
// UTF-16 surrogate characters are only valid in pairs.
|
||||
let surrogate_char: u16 = 0xDC00;
|
||||
wide_chars.push(surrogate_char);
|
||||
let os = OsString::from_wide(&wide_chars);
|
||||
assert!(os.to_str().is_none(), "invalid Unicode");
|
||||
os
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf16_lossy_positional() {
|
||||
let r = Command::new("bad_utf16")
|
||||
.arg(arg!(<arg> "some arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"")]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_lossy("arg").unwrap(), "\u{FFFD}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf16_lossy_option_short_space() {
|
||||
let r = Command::new("bad_utf16")
|
||||
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("-a"),
|
||||
bad_osstring(b""),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_lossy("arg").unwrap(), "\u{FFFD}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf16_lossy_option_short_equals() {
|
||||
let r = Command::new("bad_utf16")
|
||||
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a=")]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_lossy("arg").unwrap(), "\u{FFFD}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf16_lossy_option_short_no_space() {
|
||||
let r = Command::new("bad_utf16")
|
||||
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a")]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_lossy("arg").unwrap(), "\u{FFFD}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf16_lossy_option_long_space() {
|
||||
let r = Command::new("bad_utf16")
|
||||
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("--arg"),
|
||||
bad_osstring(b""),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_lossy("arg").unwrap(), "\u{FFFD}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf16_lossy_option_long_equals() {
|
||||
let r = Command::new("bad_utf16")
|
||||
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"--arg=")]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_lossy("arg").unwrap(), "\u{FFFD}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf16_positional() {
|
||||
let r = Command::new("bad_utf16")
|
||||
.arg(arg!(<arg> "some arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"")]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_os("arg").unwrap(), &*bad_osstring(b""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf16_option_short_space() {
|
||||
let r = Command::new("bad_utf16")
|
||||
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("-a"),
|
||||
bad_osstring(b""),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_os("arg").unwrap(), &*bad_osstring(b""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf16_option_short_equals() {
|
||||
let r = Command::new("bad_utf16")
|
||||
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a=")]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_os("arg").unwrap(), &*bad_osstring(b""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf16_option_short_no_space() {
|
||||
let r = Command::new("bad_utf16")
|
||||
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a")]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_os("arg").unwrap(), &*bad_osstring(b""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf16_option_long_space() {
|
||||
let r = Command::new("bad_utf16")
|
||||
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("--arg"),
|
||||
bad_osstring(b""),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_os("arg").unwrap(), &*bad_osstring(b""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf16_option_long_equals() {
|
||||
let r = Command::new("bad_utf16")
|
||||
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"--arg=")]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_os("arg").unwrap(), &*bad_osstring(b""));
|
||||
}
|
|
@ -1,480 +0,0 @@
|
|||
#![cfg(not(windows))]
|
||||
|
||||
use clap::{arg, error::ErrorKind, Arg, Command};
|
||||
use std::ffi::OsString;
|
||||
use std::os::unix::ffi::OsStringExt;
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_strict_positional() {
|
||||
let m = Command::new("bad_utf8")
|
||||
.arg(Arg::new("arg"))
|
||||
.try_get_matches_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 = Command::new("bad_utf8")
|
||||
.arg(Arg::new("arg").short('a').long("arg").takes_value(true))
|
||||
.try_get_matches_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 = Command::new("bad_utf8")
|
||||
.arg(Arg::new("arg").short('a').long("arg").takes_value(true))
|
||||
.try_get_matches_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 = Command::new("bad_utf8")
|
||||
.arg(Arg::new("arg").short('a').long("arg").takes_value(true))
|
||||
.try_get_matches_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 = Command::new("bad_utf8")
|
||||
.arg(Arg::new("arg").short('a').long("arg").takes_value(true))
|
||||
.try_get_matches_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 = Command::new("bad_utf8")
|
||||
.arg(Arg::new("arg").short('a').long("arg").takes_value(true))
|
||||
.try_get_matches_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);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_lossy_positional() {
|
||||
let r = Command::new("bad_utf8")
|
||||
.arg(Arg::new("arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![OsString::from(""), OsString::from_vec(vec![0xe9])]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_lossy("arg").unwrap(), "\u{FFFD}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_lossy_option_short_space() {
|
||||
let r = Command::new("bad_utf8")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.short('a')
|
||||
.long("arg")
|
||||
.takes_value(true)
|
||||
.allow_invalid_utf8(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("-a"),
|
||||
OsString::from_vec(vec![0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_lossy("arg").unwrap(), "\u{FFFD}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_lossy_option_short_equals() {
|
||||
let r = Command::new("bad_utf8")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.short('a')
|
||||
.long("arg")
|
||||
.takes_value(true)
|
||||
.allow_invalid_utf8(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_lossy("arg").unwrap(), "\u{FFFD}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_lossy_option_short_no_space() {
|
||||
let r = Command::new("bad_utf8")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.short('a')
|
||||
.long("arg")
|
||||
.takes_value(true)
|
||||
.allow_invalid_utf8(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_lossy("arg").unwrap(), "\u{FFFD}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_lossy_option_long_space() {
|
||||
let r = Command::new("bad_utf8")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.short('a')
|
||||
.long("arg")
|
||||
.takes_value(true)
|
||||
.allow_invalid_utf8(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("--arg"),
|
||||
OsString::from_vec(vec![0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_lossy("arg").unwrap(), "\u{FFFD}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_lossy_option_long_equals() {
|
||||
let r = Command::new("bad_utf8")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.short('a')
|
||||
.long("arg")
|
||||
.takes_value(true)
|
||||
.allow_invalid_utf8(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_lossy("arg").unwrap(), "\u{FFFD}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_positional() {
|
||||
let r = Command::new("bad_utf8")
|
||||
.arg(Arg::new("arg").allow_invalid_utf8(true))
|
||||
.try_get_matches_from(vec![OsString::from(""), OsString::from_vec(vec![0xe9])]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(
|
||||
&*m.value_of_os("arg").unwrap(),
|
||||
&*OsString::from_vec(vec![0xe9])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_option_short_space() {
|
||||
let r = Command::new("bad_utf8")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.short('a')
|
||||
.long("arg")
|
||||
.takes_value(true)
|
||||
.allow_invalid_utf8(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("-a"),
|
||||
OsString::from_vec(vec![0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(
|
||||
&*m.value_of_os("arg").unwrap(),
|
||||
&*OsString::from_vec(vec![0xe9])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_option_short_equals() {
|
||||
let r = Command::new("bad_utf8")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.short('a')
|
||||
.long("arg")
|
||||
.takes_value(true)
|
||||
.allow_invalid_utf8(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(
|
||||
&*m.value_of_os("arg").unwrap(),
|
||||
&*OsString::from_vec(vec![0xe9])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_option_short_no_space() {
|
||||
let r = Command::new("bad_utf8")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.short('a')
|
||||
.long("arg")
|
||||
.takes_value(true)
|
||||
.allow_invalid_utf8(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(
|
||||
&*m.value_of_os("arg").unwrap(),
|
||||
&*OsString::from_vec(vec![0xe9])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_option_long_space() {
|
||||
let r = Command::new("bad_utf8")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.short('a')
|
||||
.long("arg")
|
||||
.takes_value(true)
|
||||
.allow_invalid_utf8(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("--arg"),
|
||||
OsString::from_vec(vec![0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(
|
||||
&*m.value_of_os("arg").unwrap(),
|
||||
&*OsString::from_vec(vec![0xe9])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_option_long_equals() {
|
||||
let r = Command::new("bad_utf8")
|
||||
.arg(
|
||||
Arg::new("arg")
|
||||
.short('a')
|
||||
.long("arg")
|
||||
.takes_value(true)
|
||||
.allow_invalid_utf8(true),
|
||||
)
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok(), "{}", r.unwrap_err());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(
|
||||
&*m.value_of_os("arg").unwrap(),
|
||||
&*OsString::from_vec(vec![0xe9])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn refuse_invalid_utf8_subcommand_with_allow_external_subcommands() {
|
||||
let m = Command::new("bad_utf8")
|
||||
.allow_external_subcommands(true)
|
||||
.try_get_matches_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_when_args_are_allowed_with_allow_external_subcommands() {
|
||||
let m = Command::new("bad_utf8")
|
||||
.allow_external_subcommands(true)
|
||||
.allow_invalid_utf8_for_external_subcommands(true)
|
||||
.try_get_matches_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 = Command::new("bad_utf8")
|
||||
.allow_external_subcommands(true)
|
||||
.try_get_matches_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);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_invalid_utf8_subcommand_args_with_allow_external_subcommands() {
|
||||
let m = Command::new("bad_utf8")
|
||||
.allow_external_subcommands(true)
|
||||
.allow_invalid_utf8_for_external_subcommands(true)
|
||||
.try_get_matches_from(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("subcommand"),
|
||||
OsString::from("normal"),
|
||||
OsString::from_vec(vec![0xe9]),
|
||||
OsString::from("--another_normal"),
|
||||
]);
|
||||
assert!(m.is_ok(), "{}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
let (subcommand, args) = m.subcommand().unwrap();
|
||||
let args = args.values_of_os("").unwrap().collect::<Vec<_>>();
|
||||
assert_eq!(subcommand, OsString::from("subcommand"));
|
||||
assert_eq!(
|
||||
args,
|
||||
vec![
|
||||
OsString::from("normal"),
|
||||
OsString::from_vec(vec![0xe9]),
|
||||
OsString::from("--another_normal"),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_validated_utf8_value_of() {
|
||||
let a = Command::new("test").arg(arg!(--name <NAME>));
|
||||
let m = a.try_get_matches_from(["test", "--name", "me"]).unwrap();
|
||||
let _ = m.value_of("name");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Must use `Arg::allow_invalid_utf8` with `_os` lookups at `name`"]
|
||||
fn panic_validated_utf8_value_of_os() {
|
||||
let a = Command::new("test").arg(arg!(--name <NAME>));
|
||||
let m = a.try_get_matches_from(["test", "--name", "me"]).unwrap();
|
||||
let _ = m.value_of_os("name");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Must use `Arg::allow_invalid_utf8` with `_os` lookups at `value`"]
|
||||
fn panic_validated_utf8_with_defaults() {
|
||||
let a = Command::new("test").arg(arg!(--value <VALUE>).required(false).default_value("foo"));
|
||||
let m = a.try_get_matches_from(["test"]).unwrap();
|
||||
let _ = m.value_of("value");
|
||||
let _ = m.value_of_os("value");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_invalid_utf8_value_of_os() {
|
||||
let a = Command::new("test").arg(arg!(--name <NAME>).allow_invalid_utf8(true));
|
||||
let m = a.try_get_matches_from(["test", "--name", "me"]).unwrap();
|
||||
let _ = m.value_of_os("name");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Must use `_os` lookups with `Arg::allow_invalid_utf8` at `name`"]
|
||||
fn panic_invalid_utf8_value_of() {
|
||||
let a = Command::new("test").arg(arg!(--name <NAME>).allow_invalid_utf8(true));
|
||||
let m = a.try_get_matches_from(["test", "--name", "me"]).unwrap();
|
||||
let _ = m.value_of("name");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Must use `_os` lookups with `Arg::allow_invalid_utf8` at `value`"]
|
||||
fn panic_invalid_utf8_with_defaults() {
|
||||
let a = Command::new("test").arg(
|
||||
arg!(--value <VALUE>)
|
||||
.required(false)
|
||||
.default_value("foo")
|
||||
.allow_invalid_utf8(true),
|
||||
);
|
||||
let m = a.try_get_matches_from(["test"]).unwrap();
|
||||
let _ = m.value_of("value");
|
||||
let _ = m.value_of_os("value");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_validated_utf8_external_subcommand_values_of() {
|
||||
let a = Command::new("test").allow_external_subcommands(true);
|
||||
let m = a.try_get_matches_from(vec!["test", "cmd", "arg"]).unwrap();
|
||||
let (_ext, args) = m.subcommand().unwrap();
|
||||
let _ = args.values_of("").unwrap_or_default().count();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Must use `Arg::allow_invalid_utf8` with `_os` lookups"]
|
||||
fn panic_validated_utf8_external_subcommand_values_of_os() {
|
||||
let a = Command::new("test").allow_external_subcommands(true);
|
||||
let m = a.try_get_matches_from(vec!["test", "cmd", "arg"]).unwrap();
|
||||
let (_ext, args) = m.subcommand().unwrap();
|
||||
let _ = args.values_of_os("").unwrap_or_default().count();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_invalid_utf8_external_subcommand_values_of_os() {
|
||||
let a = Command::new("test")
|
||||
.allow_external_subcommands(true)
|
||||
.allow_invalid_utf8_for_external_subcommands(true);
|
||||
let m = a.try_get_matches_from(vec!["test", "cmd", "arg"]).unwrap();
|
||||
let (_ext, args) = m.subcommand().unwrap();
|
||||
let _ = args.values_of_os("").unwrap_or_default().count();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Must use `_os` lookups with `Arg::allow_invalid_utf8`"]
|
||||
fn panic_invalid_utf8_external_subcommand_values_of() {
|
||||
let a = Command::new("test")
|
||||
.allow_external_subcommands(true)
|
||||
.allow_invalid_utf8_for_external_subcommands(true);
|
||||
let m = a.try_get_matches_from(vec!["test", "cmd", "arg"]).unwrap();
|
||||
let (_ext, args) = m.subcommand().unwrap();
|
||||
let _ = args.values_of("").unwrap_or_default().count();
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
#![allow(unused_imports, dead_code)]
|
||||
|
||||
use std::io::{BufRead, Cursor, Write};
|
||||
use std::str;
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
use clap::{arg, Arg, ArgGroup, Command};
|
||||
|
||||
#[track_caller]
|
||||
pub fn assert_eq<S, S2>(expected: S, actual: S2)
|
||||
where
|
||||
S: AsRef<str>,
|
||||
S2: AsRef<str>,
|
||||
{
|
||||
let expected = expected.as_ref();
|
||||
let actual = actual.as_ref();
|
||||
snapbox::assert_eq(expected, actual);
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn assert_output(l: Command, args: &str, expected: &str, stderr: bool) {
|
||||
let mut buf = Cursor::new(Vec::with_capacity(50));
|
||||
let res = l.try_get_matches_from(args.split(' ').collect::<Vec<_>>());
|
||||
let err = res.unwrap_err();
|
||||
write!(&mut buf, "{}", err).unwrap();
|
||||
let actual = buf.into_inner();
|
||||
let actual = String::from_utf8(actual).unwrap();
|
||||
assert_eq!(
|
||||
stderr,
|
||||
err.use_stderr(),
|
||||
"Should Use STDERR failed. Should be {} but is {}",
|
||||
stderr,
|
||||
err.use_stderr()
|
||||
);
|
||||
assert_eq(expected, actual)
|
||||
}
|
||||
|
||||
// Legacy tests from the python script days
|
||||
|
||||
pub fn complex_app() -> Command<'static> {
|
||||
let opt3_vals = ["fast", "slow"];
|
||||
let pos3_vals = ["vi", "emacs"];
|
||||
|
||||
Command::new("clap-test")
|
||||
.version("v1.4.8")
|
||||
.about("tests clap library")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.arg(
|
||||
arg!(
|
||||
-o --option <opt> "tests options"
|
||||
)
|
||||
.required(false)
|
||||
.multiple_values(true)
|
||||
.multiple_occurrences(true),
|
||||
)
|
||||
.arg(arg!([positional] "tests positionals"))
|
||||
.arg(arg!(-f --flag ... "tests flags").global(true))
|
||||
.args(&[
|
||||
arg!(flag2: -F "tests flags with exclusions")
|
||||
.conflicts_with("flag")
|
||||
.requires("long-option-2"),
|
||||
arg!(--"long-option-2" <option2> "tests long options with exclusions")
|
||||
.required(false)
|
||||
.conflicts_with("option")
|
||||
.requires("positional2"),
|
||||
arg!([positional2] "tests positionals with exclusions"),
|
||||
arg!(-O --option3 <option3> "specific vals")
|
||||
.required(false)
|
||||
.possible_values(opt3_vals),
|
||||
arg!([positional3] ... "tests specific values").possible_values(pos3_vals),
|
||||
arg!(--multvals "Tests multiple values, not mult occs")
|
||||
.value_names(&["one", "two"])
|
||||
.required(false),
|
||||
arg!(--multvalsmo ... "Tests multiple values, and mult occs")
|
||||
.value_names(&["one", "two"])
|
||||
.required(false),
|
||||
arg!(--minvals2 <minvals> "Tests 2 min vals")
|
||||
.required(false)
|
||||
.min_values(2),
|
||||
arg!(--maxvals3 <maxvals> "Tests 3 max vals")
|
||||
.required(false)
|
||||
.max_values(3),
|
||||
arg!(--optvaleq <optval> "Tests optional value, require = sign")
|
||||
.required(false)
|
||||
.min_values(0)
|
||||
.number_of_values(1)
|
||||
.require_equals(true),
|
||||
arg!(--optvalnoeq <optval> "Tests optional value")
|
||||
.required(false)
|
||||
.min_values(0)
|
||||
.number_of_values(1),
|
||||
])
|
||||
.subcommand(
|
||||
Command::new("subcmd")
|
||||
.about("tests subcommands")
|
||||
.version("0.1")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.arg(
|
||||
arg!(-o --option <scoption> "tests options")
|
||||
.required(false)
|
||||
.multiple_values(true),
|
||||
)
|
||||
.arg(arg!(-s --subcmdarg <subcmdarg> "tests other args").required(false))
|
||||
.arg(arg!([scpositional] "tests positionals")),
|
||||
)
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
use clap::{Arg, Command};
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument 'test' has both `validator` and `validator_os` set which is not allowed"]
|
||||
fn both_validator_and_validator_os() {
|
||||
let _ = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("test")
|
||||
.validator(|val| val.parse::<u32>().map_err(|e| e.to_string()))
|
||||
.validator_os(|val| {
|
||||
val.to_str()
|
||||
.unwrap()
|
||||
.parse::<u32>()
|
||||
.map_err(|e| e.to_string())
|
||||
}),
|
||||
)
|
||||
.try_get_matches_from(&["cmd", "1"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validator_fromstr_trait() {
|
||||
use std::str::FromStr;
|
||||
|
||||
let matches = Command::new("test")
|
||||
.arg(Arg::new("from_str").validator(u32::from_str))
|
||||
.try_get_matches_from(&["cmd", "1234"])
|
||||
.expect("match failed");
|
||||
|
||||
assert_eq!(matches.value_of_t::<u32>("from_str").ok(), Some(1234));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validator_msg_newline() {
|
||||
let res = Command::new("test")
|
||||
.arg(Arg::new("test").validator(|val| val.parse::<u32>().map_err(|e| e.to_string())))
|
||||
.try_get_matches_from(&["cmd", "f"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
|
||||
assert!(
|
||||
err.to_string()
|
||||
.contains("Invalid value \"f\" for '<test>': invalid digit found in string"),
|
||||
"{}",
|
||||
err
|
||||
);
|
||||
|
||||
// This message is the only thing that gets printed -- make sure it ends with a newline
|
||||
let msg = format!("{}", err);
|
||||
assert!(msg.ends_with('\n'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stateful_validator() {
|
||||
let mut state = false;
|
||||
Command::new("test")
|
||||
.arg(Arg::new("test").validator(|val| {
|
||||
state = true;
|
||||
val.parse::<u32>().map_err(|e| e.to_string())
|
||||
}))
|
||||
.try_get_matches_from(&["cmd", "10"])
|
||||
.unwrap();
|
||||
|
||||
assert!(state);
|
||||
}
|
|
@ -1,235 +0,0 @@
|
|||
use super::utils;
|
||||
|
||||
use std::str;
|
||||
|
||||
use clap::{error::ErrorKind, AppSettings, Arg, Command};
|
||||
|
||||
fn common() -> Command<'static> {
|
||||
Command::new("foo")
|
||||
}
|
||||
|
||||
fn with_version() -> Command<'static> {
|
||||
common().version("3.0")
|
||||
}
|
||||
|
||||
fn with_long_version() -> Command<'static> {
|
||||
common().long_version("3.0 (abcdefg)")
|
||||
}
|
||||
|
||||
fn with_subcommand() -> Command<'static> {
|
||||
with_version().subcommand(Command::new("bar").subcommand(Command::new("baz")))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_version_flag_short() {
|
||||
let res = common().try_get_matches_from("foo -V".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), clap::error::ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_version_flag_long() {
|
||||
let res = common().try_get_matches_from("foo --version".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), clap::error::ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_flag_from_version_short() {
|
||||
let res = with_version().try_get_matches_from("foo -V".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayVersion);
|
||||
assert_eq!(err.to_string(), "foo 3.0\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_flag_from_version_long() {
|
||||
let res = with_version().try_get_matches_from("foo --version".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayVersion);
|
||||
assert_eq!(err.to_string(), "foo 3.0\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_flag_from_long_version_short() {
|
||||
let res = with_long_version().try_get_matches_from("foo -V".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayVersion);
|
||||
assert_eq!(err.to_string(), "foo 3.0 (abcdefg)\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_flag_from_long_version_long() {
|
||||
let res = with_long_version().try_get_matches_from("foo --version".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayVersion);
|
||||
assert_eq!(err.to_string(), "foo 3.0 (abcdefg)\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn override_version_long_with_user_flag() {
|
||||
let res = with_version()
|
||||
.arg(Arg::new("ver").long("version"))
|
||||
.try_get_matches_from("foo --version".split(' '));
|
||||
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("ver"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn override_version_long_with_user_flag_no_version_flag() {
|
||||
let res = with_version()
|
||||
.arg(Arg::new("ver").long("version"))
|
||||
.try_get_matches_from("foo -V".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn override_version_short_with_user_flag() {
|
||||
let res = with_version()
|
||||
.arg(Arg::new("ver").short('V'))
|
||||
.try_get_matches_from("foo -V".split(' '));
|
||||
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("ver"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn override_version_short_with_user_flag_long_still_works() {
|
||||
let res = with_version()
|
||||
.arg(Arg::new("ver").short('V'))
|
||||
.try_get_matches_from("foo --version".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayVersion);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mut_version_short() {
|
||||
let res = with_version()
|
||||
.mut_arg("version", |a| a.short('z'))
|
||||
.try_get_matches_from("foo -z".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayVersion);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mut_version_long() {
|
||||
let res = with_version()
|
||||
.mut_arg("version", |a| a.long("qux"))
|
||||
.try_get_matches_from("foo --qux".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayVersion);
|
||||
}
|
||||
|
||||
static VERSION_ABOUT_MULTI_SC: &str = "foo-bar-baz 3.0
|
||||
|
||||
USAGE:
|
||||
foo bar baz
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Print help information
|
||||
-V, --version Print custom version about text
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn version_about_multi_subcmd() {
|
||||
let cmd = with_subcommand()
|
||||
.mut_arg("version", |a| a.help("Print custom version about text"))
|
||||
.propagate_version(true);
|
||||
|
||||
utils::assert_output(cmd, "foo bar baz -h", VERSION_ABOUT_MULTI_SC, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_propagation_by_default_long() {
|
||||
// Version Flag should not be propagated to subcommands
|
||||
let res = with_subcommand().try_get_matches_from("foo bar --version".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_propagation_by_default_short() {
|
||||
let res = with_subcommand().try_get_matches_from("foo bar -V".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn propagate_version_long() {
|
||||
let res = with_subcommand()
|
||||
.propagate_version(true)
|
||||
.try_get_matches_from("foo bar --version".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayVersion);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn propagate_version_short() {
|
||||
let res = with_subcommand()
|
||||
.propagate_version(true)
|
||||
.try_get_matches_from("foo bar -V".split(' '));
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
assert_eq!(err.kind(), ErrorKind::DisplayVersion);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "`ArgAction::Version` used without providing Command::version or Command::long_version"]
|
||||
fn mut_arg_version_panic() {
|
||||
let _res = common()
|
||||
.mut_arg("version", |v| v.short('z'))
|
||||
.try_get_matches_from("foo -z".split(' '));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mut_arg_version_no_auto_version() {
|
||||
let res = common()
|
||||
.mut_arg("version", |v| v.short('z'))
|
||||
.setting(AppSettings::NoAutoVersion)
|
||||
.try_get_matches_from("foo -z".split(' '));
|
||||
|
||||
assert!(res.is_ok(), "{}", res.unwrap_err());
|
||||
assert!(res.unwrap().is_present("version"));
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "No version information via Command::version or Command::long_version to propagate"]
|
||||
fn propagate_version_no_version_info() {
|
||||
let _res = common()
|
||||
.propagate_version(true)
|
||||
.subcommand(Command::new("bar"))
|
||||
.try_get_matches_from("foo".split(' '));
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
#![allow(clippy::bool_assert_comparison)]
|
||||
|
||||
mod action;
|
||||
mod app_from_crate;
|
||||
mod app_settings;
|
||||
mod arg_aliases;
|
||||
mod arg_aliases_short;
|
||||
mod arg_matcher_assertions;
|
||||
mod arg_settings;
|
||||
mod borrowed;
|
||||
mod cargo;
|
||||
mod command;
|
||||
|
@ -30,7 +28,6 @@ mod help_env;
|
|||
mod hidden_args;
|
||||
mod ignore_errors;
|
||||
mod indices;
|
||||
mod legacy;
|
||||
mod multiple_occurrences;
|
||||
mod multiple_values;
|
||||
mod opts;
|
||||
|
@ -38,7 +35,6 @@ mod positionals;
|
|||
mod posix_compatible;
|
||||
mod possible_values;
|
||||
mod propagate_globals;
|
||||
mod regex;
|
||||
mod require;
|
||||
mod subcommands;
|
||||
mod template_help;
|
||||
|
@ -48,5 +44,4 @@ mod unique_args;
|
|||
mod utf16;
|
||||
mod utf8;
|
||||
mod utils;
|
||||
mod validators;
|
||||
mod version;
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
#![cfg(feature = "regex")]
|
||||
#![allow(deprecated)]
|
||||
|
||||
use clap::{error::ErrorKind, Arg, Command};
|
||||
use regex::{Regex, RegexSet};
|
||||
|
||||
#[test]
|
||||
fn validator_regex() {
|
||||
let priority = Regex::new(r"[A-C]").unwrap();
|
||||
|
||||
let m = Command::new("prog")
|
||||
.arg(
|
||||
Arg::new("priority")
|
||||
.index(1)
|
||||
.validator_regex(priority, "A, B or C are allowed"),
|
||||
)
|
||||
.try_get_matches_from(vec!["prog", "12345"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.err().unwrap().kind(), ErrorKind::ValueValidation)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validator_regex_with_regex_set() {
|
||||
let priority = RegexSet::new(&[r"[A-C]", r"[X-Z]"]).unwrap();
|
||||
|
||||
let m = Command::new("prog")
|
||||
.arg(
|
||||
Arg::new("priority")
|
||||
.index(1)
|
||||
.validator_regex(priority, "A, B, C, X, Y or Z are allowed"),
|
||||
)
|
||||
.try_get_matches_from(vec!["prog", "12345"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.err().unwrap().kind(), ErrorKind::ValueValidation)
|
||||
}
|
|
@ -287,57 +287,6 @@ fn allow_validated_utf8_value_of() {
|
|||
let _ = m.get_one::<String>("name").map(|v| v.as_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Must use `Arg::allow_invalid_utf8` with `_os` lookups at `name`"]
|
||||
fn panic_validated_utf8_value_of_os() {
|
||||
#![allow(deprecated)]
|
||||
let a = Command::new("test").arg(arg!(--name <NAME>));
|
||||
let m = a.try_get_matches_from(["test", "--name", "me"]).unwrap();
|
||||
let _ = m.value_of_os("name");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Must use `Arg::allow_invalid_utf8` with `_os` lookups at `value`"]
|
||||
fn panic_validated_utf8_with_defaults() {
|
||||
#![allow(deprecated)]
|
||||
let a = Command::new("test").arg(arg!(--value <VALUE>).required(false).default_value("foo"));
|
||||
let m = a.try_get_matches_from(["test"]).unwrap();
|
||||
let _ = m.get_one::<String>("value").map(|v| v.as_str());
|
||||
let _ = m.value_of_os("value");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_invalid_utf8_value_of_os() {
|
||||
#![allow(deprecated)]
|
||||
let a = Command::new("test").arg(arg!(--name <NAME>).allow_invalid_utf8(true));
|
||||
let m = a.try_get_matches_from(["test", "--name", "me"]).unwrap();
|
||||
let _ = m.value_of_os("name");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Mismatch between definition and access of `name`. Could not downcast to alloc::string::String, need to downcast to std::ffi::os_str::OsString"]
|
||||
fn panic_invalid_utf8_value_of() {
|
||||
#![allow(deprecated)]
|
||||
let a = Command::new("test").arg(arg!(--name <NAME>).allow_invalid_utf8(true));
|
||||
let m = a.try_get_matches_from(["test", "--name", "me"]).unwrap();
|
||||
let _ = m.get_one::<String>("name").map(|v| v.as_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Mismatch between definition and access of `value`. Could not downcast to alloc::string::String, need to downcast to std::ffi::os_str::OsString"]
|
||||
fn panic_invalid_utf8_with_defaults() {
|
||||
#![allow(deprecated)]
|
||||
let a = Command::new("test").arg(
|
||||
arg!(--value <VALUE>)
|
||||
.required(false)
|
||||
.default_value("foo")
|
||||
.allow_invalid_utf8(true),
|
||||
);
|
||||
let m = a.try_get_matches_from(["test"]).unwrap();
|
||||
let _ = m.value_of_os("value");
|
||||
let _ = m.get_one::<String>("value").map(|v| v.as_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_validated_utf8_external_subcommand_values_of() {
|
||||
let a = Command::new("test").allow_external_subcommands(true);
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
use std::io::{BufRead, Cursor, Write};
|
||||
use std::str;
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
use clap::{arg, Arg, ArgAction, ArgGroup, Command};
|
||||
|
||||
#[track_caller]
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
#![allow(deprecated)]
|
||||
|
||||
use clap::{Arg, Command};
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument 'test' has both `validator` and `validator_os` set which is not allowed"]
|
||||
fn both_validator_and_validator_os() {
|
||||
let _ = Command::new("test")
|
||||
.arg(
|
||||
Arg::new("test")
|
||||
.validator(|val| val.parse::<u32>().map_err(|e| e.to_string()))
|
||||
.validator_os(|val| {
|
||||
val.to_str()
|
||||
.unwrap()
|
||||
.parse::<u32>()
|
||||
.map_err(|e| e.to_string())
|
||||
}),
|
||||
)
|
||||
.try_get_matches_from(&["cmd", "1"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validator_fromstr_trait() {
|
||||
use std::str::FromStr;
|
||||
|
||||
let matches = Command::new("test")
|
||||
.arg(Arg::new("from_str").validator(u32::from_str))
|
||||
.try_get_matches_from(&["cmd", "1234"])
|
||||
.expect("match failed");
|
||||
|
||||
assert_eq!(matches.value_of_t::<u32>("from_str").ok(), Some(1234));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validator_msg_newline() {
|
||||
let res = Command::new("test")
|
||||
.arg(Arg::new("test").validator(|val| val.parse::<u32>().map_err(|e| e.to_string())))
|
||||
.try_get_matches_from(&["cmd", "f"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
let err = res.unwrap_err();
|
||||
|
||||
assert!(
|
||||
err.to_string()
|
||||
.contains("Invalid value \"f\" for '<test>': invalid digit found in string"),
|
||||
"{}",
|
||||
err
|
||||
);
|
||||
|
||||
// This message is the only thing that gets printed -- make sure it ends with a newline
|
||||
let msg = format!("{}", err);
|
||||
assert!(msg.ends_with('\n'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stateful_validator() {
|
||||
let mut state = false;
|
||||
Command::new("test")
|
||||
.arg(Arg::new("test").validator(|val| {
|
||||
state = true;
|
||||
val.parse::<u32>().map_err(|e| e.to_string())
|
||||
}))
|
||||
.try_get_matches_from(&["cmd", "10"])
|
||||
.unwrap();
|
||||
|
||||
assert!(state);
|
||||
}
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
use clap::Parser;
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::num::ParseIntError;
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
@ -204,116 +203,3 @@ fn test_parser_occurrences() {
|
|||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_custom_bool() {
|
||||
fn parse_bool(s: &str) -> Result<bool, String> {
|
||||
match s {
|
||||
"true" => Ok(true),
|
||||
"false" => Ok(false),
|
||||
_ => Err(format!("invalid bool {}", s)),
|
||||
}
|
||||
}
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(short, parse(try_from_str = parse_bool))]
|
||||
debug: bool,
|
||||
#[clap(
|
||||
short,
|
||||
default_value = "false",
|
||||
parse(try_from_str = parse_bool)
|
||||
)]
|
||||
verbose: bool,
|
||||
#[clap(short, parse(try_from_str = parse_bool))]
|
||||
tribool: Option<bool>,
|
||||
#[clap(short, parse(try_from_str = parse_bool), multiple_occurrences(true))]
|
||||
bitset: Vec<bool>,
|
||||
}
|
||||
|
||||
assert!(Opt::try_parse_from(&["test"]).is_err());
|
||||
assert!(Opt::try_parse_from(&["test", "-d"]).is_err());
|
||||
assert!(Opt::try_parse_from(&["test", "-dfoo"]).is_err());
|
||||
assert_eq!(
|
||||
Opt {
|
||||
debug: false,
|
||||
verbose: false,
|
||||
tribool: None,
|
||||
bitset: vec![],
|
||||
},
|
||||
Opt::try_parse_from(&["test", "-dfalse"]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
Opt {
|
||||
debug: true,
|
||||
verbose: false,
|
||||
tribool: None,
|
||||
bitset: vec![],
|
||||
},
|
||||
Opt::try_parse_from(&["test", "-dtrue"]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
Opt {
|
||||
debug: true,
|
||||
verbose: false,
|
||||
tribool: None,
|
||||
bitset: vec![],
|
||||
},
|
||||
Opt::try_parse_from(&["test", "-dtrue", "-vfalse"]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
Opt {
|
||||
debug: true,
|
||||
verbose: true,
|
||||
tribool: None,
|
||||
bitset: vec![],
|
||||
},
|
||||
Opt::try_parse_from(&["test", "-dtrue", "-vtrue"]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
Opt {
|
||||
debug: true,
|
||||
verbose: false,
|
||||
tribool: Some(false),
|
||||
bitset: vec![],
|
||||
},
|
||||
Opt::try_parse_from(&["test", "-dtrue", "-tfalse"]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
Opt {
|
||||
debug: true,
|
||||
verbose: false,
|
||||
tribool: Some(true),
|
||||
bitset: vec![],
|
||||
},
|
||||
Opt::try_parse_from(&["test", "-dtrue", "-ttrue"]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
Opt {
|
||||
debug: true,
|
||||
verbose: false,
|
||||
tribool: None,
|
||||
bitset: vec![false, true, false, false],
|
||||
},
|
||||
Opt::try_parse_from(&["test", "-dtrue", "-bfalse", "-btrue", "-bfalse", "-bfalse"])
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cstring() {
|
||||
#[derive(Parser)]
|
||||
struct Opt {
|
||||
#[clap(parse(try_from_str = CString::new))]
|
||||
c_string: CString,
|
||||
}
|
||||
|
||||
assert!(Opt::try_parse_from(&["test"]).is_err());
|
||||
assert_eq!(
|
||||
Opt::try_parse_from(&["test", "bla"])
|
||||
.unwrap()
|
||||
.c_string
|
||||
.to_bytes(),
|
||||
b"bla"
|
||||
);
|
||||
assert!(Opt::try_parse_from(&["test", "bla\0bla"]).is_err());
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
}
|
|
@ -1,526 +0,0 @@
|
|||
// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
|
||||
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
|
||||
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
enum ArgChoice {
|
||||
Foo,
|
||||
Bar,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
enum ArgChoice {
|
||||
Foo,
|
||||
Bar,
|
||||
}
|
||||
|
||||
impl Default for ArgChoice {
|
||||
fn default() -> Self {
|
||||
Self::Bar
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
#[allow(non_camel_case_types)]
|
||||
enum ArgChoice {
|
||||
FooBar,
|
||||
BAR_BAZ,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
enum ArgChoice {
|
||||
#[clap(rename_all = "screaming_snake")]
|
||||
FooBar,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
#[clap(rename_all = "screaming_snake")]
|
||||
enum ArgChoice {
|
||||
FooBar,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
#[clap(rename_all = "screaming_snake")]
|
||||
enum ArgChoice {
|
||||
#[clap(rename_all = "camel")]
|
||||
FooBar,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
enum ArgChoice {
|
||||
Foo,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
enum ArgChoice {
|
||||
Foo,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
enum ArgChoice {
|
||||
#[clap(alias = "TOTP")]
|
||||
Totp,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
enum ArgChoice {
|
||||
#[clap(alias = "TOTP", alias = "t")]
|
||||
Totp,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
#[allow(dead_code)] // silence warning about `Baz` being unused
|
||||
enum ArgChoice {
|
||||
Foo,
|
||||
Bar,
|
||||
#[clap(skip)]
|
||||
Baz,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
<ArgChoice as clap::ArgEnum>::value_variants()
|
||||
.iter()
|
||||
.map(clap::ArgEnum::to_possible_value)
|
||||
.map(Option::unwrap)
|
||||
.collect::<Vec<_>>(),
|
||||
vec![
|
||||
clap::PossibleValue::new("foo"),
|
||||
clap::PossibleValue::new("bar")
|
||||
]
|
||||
);
|
||||
|
||||
{
|
||||
use clap::ArgEnum;
|
||||
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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
#[allow(dead_code)] // silence warning about `Baz` being unused
|
||||
enum ArgChoice {
|
||||
Foo,
|
||||
Bar,
|
||||
#[clap(skip)]
|
||||
Baz(usize),
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
<ArgChoice as clap::ArgEnum>::value_variants()
|
||||
.iter()
|
||||
.map(clap::ArgEnum::to_possible_value)
|
||||
.map(Option::unwrap)
|
||||
.collect::<Vec<_>>(),
|
||||
vec![
|
||||
clap::PossibleValue::new("foo"),
|
||||
clap::PossibleValue::new("bar")
|
||||
]
|
||||
);
|
||||
|
||||
{
|
||||
use clap::ArgEnum;
|
||||
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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
enum ArgChoice {
|
||||
Foo,
|
||||
}
|
||||
|
||||
{
|
||||
use clap::ArgEnum;
|
||||
assert!(ArgChoice::from_str("bar", true).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn option_type() {
|
||||
#[derive(clap::ArgEnum, PartialEq, Debug, Clone)]
|
||||
enum ArgChoice {
|
||||
Foo,
|
||||
Bar,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_enum)]
|
||||
arg: Option<ArgChoice>,
|
||||
}
|
||||
|
||||
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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
enum ArgChoice {
|
||||
Foo,
|
||||
Bar,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_enum, long)]
|
||||
arg: Option<Option<ArgChoice>>,
|
||||
}
|
||||
|
||||
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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
enum ArgChoice {
|
||||
Foo,
|
||||
Bar,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_enum, short, long)]
|
||||
arg: Vec<ArgChoice>,
|
||||
}
|
||||
|
||||
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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
enum ArgChoice {
|
||||
Foo,
|
||||
Bar,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(arg_enum, short, long)]
|
||||
arg: Option<Vec<ArgChoice>>,
|
||||
}
|
||||
|
||||
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::ArgEnum, PartialEq, Debug, Clone)]
|
||||
enum ArgChoice {
|
||||
Foo,
|
||||
Bar,
|
||||
Baz,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Debug)]
|
||||
struct Opt {
|
||||
#[clap(
|
||||
arg_enum,
|
||||
short,
|
||||
long,
|
||||
default_value = "foo,bar",
|
||||
value_delimiter = ','
|
||||
)]
|
||||
arg: Vec<ArgChoice>,
|
||||
}
|
||||
|
||||
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()
|
||||
);
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
|
||||
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
|
||||
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<i32>,
|
||||
}
|
||||
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<i32>,
|
||||
}
|
||||
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()
|
||||
);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue