mirror of
https://github.com/clap-rs/clap
synced 2024-12-14 14:52:33 +00:00
470531b515
This reduces ambiguity in how the different "multiple" parts of the API interact and lowrs the amount of API surface area users have to dig through to use clap. For now, this is only a matter of cleaning up the public API. Cleaning up the implementation is the next step.
252 lines
7.4 KiB
Rust
252 lines
7.4 KiB
Rust
#![cfg(feature = "unstable-grouped")]
|
|
|
|
use clap::{Arg, ArgAction, Command};
|
|
|
|
#[test]
|
|
fn grouped_value_works() {
|
|
let m = Command::new("cli")
|
|
.arg(
|
|
Arg::new("option")
|
|
.long("option")
|
|
.action(ArgAction::Set)
|
|
.number_of_values(1..)
|
|
.action(ArgAction::Append),
|
|
)
|
|
.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').action(ArgAction::Set))
|
|
.arg(Arg::new("user").short('u').action(ArgAction::Set))
|
|
.arg(
|
|
Arg::new("target")
|
|
.long("target")
|
|
.action(ArgAction::Set)
|
|
.number_of_values(1..)
|
|
.action(ArgAction::Append),
|
|
)
|
|
.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")
|
|
.action(ArgAction::Set)
|
|
.use_value_delimiter(true)
|
|
.number_of_values(1..)
|
|
.action(ArgAction::Append),
|
|
)
|
|
.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')
|
|
.action(ArgAction::Set)
|
|
.use_value_delimiter(true)
|
|
.number_of_values(1..)
|
|
.action(ArgAction::Append),
|
|
)
|
|
.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")
|
|
.action(ArgAction::Set)
|
|
.number_of_values(1..),
|
|
)
|
|
.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")
|
|
.action(ArgAction::Set)
|
|
.number_of_values(1..),
|
|
)
|
|
.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")
|
|
.action(ArgAction::Set)
|
|
.number_of_values(1..)
|
|
.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 grouped_interleaved_positional_values() {
|
|
let cmd = clap::Command::new("foo")
|
|
.arg(clap::Arg::new("pos").number_of_values(1..))
|
|
.arg(
|
|
clap::Arg::new("flag")
|
|
.short('f')
|
|
.long("flag")
|
|
.action(ArgAction::Set)
|
|
.action(ArgAction::Append),
|
|
);
|
|
|
|
let m = cmd
|
|
.try_get_matches_from(["foo", "1", "2", "-f", "a", "3", "-f", "b", "4"])
|
|
.unwrap();
|
|
|
|
let pos: Vec<_> = m.grouped_values_of("pos").unwrap().collect();
|
|
assert_eq!(pos, vec![vec!["1", "2"], vec!["3"], vec!["4"]]);
|
|
|
|
let flag: Vec<_> = m.grouped_values_of("flag").unwrap().collect();
|
|
assert_eq!(flag, vec![vec!["a"], vec!["b"]]);
|
|
}
|
|
|
|
#[test]
|
|
fn grouped_interleaved_positional_occurrences() {
|
|
let cmd = clap::Command::new("foo")
|
|
.arg(clap::Arg::new("pos").number_of_values(1..))
|
|
.arg(
|
|
clap::Arg::new("flag")
|
|
.short('f')
|
|
.long("flag")
|
|
.action(ArgAction::Set)
|
|
.action(ArgAction::Append),
|
|
);
|
|
|
|
let m = cmd
|
|
.try_get_matches_from(["foo", "1", "2", "-f", "a", "3", "-f", "b", "4"])
|
|
.unwrap();
|
|
|
|
let pos: Vec<_> = m.grouped_values_of("pos").unwrap().collect();
|
|
assert_eq!(pos, vec![vec!["1", "2"], vec!["3"], vec!["4"]]);
|
|
|
|
let flag: Vec<_> = m.grouped_values_of("flag").unwrap().collect();
|
|
assert_eq!(flag, vec![vec!["a"], vec!["b"]]);
|
|
}
|
|
|
|
#[test]
|
|
fn issue_2171() {
|
|
let schema = Command::new("ripgrep#1701 reproducer")
|
|
.arg(
|
|
Arg::new("pretty")
|
|
.short('p')
|
|
.long("pretty")
|
|
.action(ArgAction::SetTrue),
|
|
)
|
|
.arg(
|
|
Arg::new("search_zip")
|
|
.short('z')
|
|
.long("search-zip")
|
|
.action(ArgAction::SetTrue),
|
|
);
|
|
|
|
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();
|
|
}
|
|
}
|