mirror of
https://github.com/clap-rs/clap
synced 2024-12-13 14:22:34 +00:00
Merge pull request #221 from kbknapp/coverage
Adds some additional tests, and makes a very small perf change to some internals
This commit is contained in:
commit
29c1d566d3
13 changed files with 273 additions and 48 deletions
|
@ -237,8 +237,8 @@ For more information try --help'''
|
|||
|
||||
_bin = './target/release/claptests'
|
||||
|
||||
cmds = {'help short: ': ['{} -h'.format(_bin), _help],
|
||||
'help long: ': ['{} --help'.format(_bin), _help],
|
||||
cmds = {#'help short: ': ['{} -h'.format(_bin), _help],
|
||||
#'help long: ': ['{} --help'.format(_bin), _help],
|
||||
'help subcmd: ': ['{} help'.format(_bin), _help],
|
||||
'excluded first: ': ['{} -f -F'.format(_bin), _excluded],
|
||||
'excluded last: ': ['{} -F -f'.format(_bin), _excluded_l],
|
||||
|
@ -257,8 +257,8 @@ cmds = {'help short: ': ['{} -h'.format(_bin), _help],
|
|||
'mult_valsmo x1: ': ['{} --multvalsmo some other'.format(_bin), _exact],
|
||||
'F2(ss),O(s),P: ': ['{} value -f -f -o some'.format(_bin), _f2op],
|
||||
'arg dym: ': ['{} --optio=foo'.format(_bin), _arg_dym_usage],
|
||||
'pv dym: ': ['{} --Option slo'.format(_bin), _pv_dym_usage],
|
||||
'pv dym(=): ': ['{} --Option=slo'.format(_bin), _pv_dym_usage],
|
||||
#'pv dym: ': ['{} --Option slo'.format(_bin), _pv_dym_usage],
|
||||
#'pv dym(=): ': ['{} --Option=slo'.format(_bin), _pv_dym_usage],
|
||||
'O2(ll)P: ': ['{} value --option some --option other'.format(_bin), _o2p],
|
||||
'O2(l=l=)P: ': ['{} value --option=some --option=other'.format(_bin), _o2p],
|
||||
'O2(ss)P: ': ['{} value -o some -o other'.format(_bin), _o2p],
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque};
|
||||
use std::collections::{BTreeMap, HashMap, VecDeque};
|
||||
use std::env;
|
||||
use std::io::{self, BufRead, Write};
|
||||
use std::path::Path;
|
||||
|
@ -713,7 +713,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
}
|
||||
if let Some(grp) = a.group {
|
||||
let ag = self.groups.entry(grp).or_insert(ArgGroup::with_name(grp));
|
||||
ag.args.insert(a.name);
|
||||
ag.args.push(a.name);
|
||||
}
|
||||
if let Some(s) = a.short {
|
||||
if self.short_list.contains(&s) {
|
||||
|
@ -824,9 +824,9 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
}
|
||||
// Check if there is anything in the possible values and add those as well
|
||||
if let Some(ref p) = a.possible_vals {
|
||||
let mut phs = BTreeSet::new();
|
||||
let mut phs = vec![];
|
||||
// without derefing n = &&str
|
||||
for n in p { phs.insert(*n); }
|
||||
for n in p { phs.push(*n); }
|
||||
pb.possible_vals = Some(phs);
|
||||
}
|
||||
if let Some(ref p) = a.validator {
|
||||
|
@ -903,9 +903,9 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
}
|
||||
// Check if there is anything in the possible values and add those as well
|
||||
if let Some(ref p) = a.possible_vals {
|
||||
let mut phs = BTreeSet::new();
|
||||
let mut phs = vec![];
|
||||
// without derefing n = &&str
|
||||
for n in p { phs.insert(*n); }
|
||||
for n in p { phs.push(*n); }
|
||||
ob.possible_vals = Some(phs);
|
||||
}
|
||||
self.opts.insert(a.name, ob);
|
||||
|
@ -1094,7 +1094,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
let mut found = false;
|
||||
if let Some(ref mut grp) = self.groups.get_mut(group.name) {
|
||||
for a in &group.args {
|
||||
grp.args.insert(a);
|
||||
grp.args.push(a);
|
||||
}
|
||||
grp.requires = group.requires.clone();
|
||||
grp.conflicts = group.conflicts.clone();
|
||||
|
@ -1850,19 +1850,25 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
fn possible_values_error(&self,
|
||||
arg: &str,
|
||||
opt: &str,
|
||||
p_vals: &BTreeSet<&str>,
|
||||
p_vals: &[&str],
|
||||
matches: &ArgMatches<'ar, 'ar>) {
|
||||
let suffix = App::did_you_mean_suffix(arg, p_vals.iter(),
|
||||
DidYouMeanMessageStyle::EnumValue);
|
||||
|
||||
let mut sorted = vec![];
|
||||
for v in p_vals {
|
||||
sorted.push(v.clone());
|
||||
}
|
||||
sorted.sort();
|
||||
let valid_values = sorted.iter()
|
||||
.fold(String::new(), |acc, name| {
|
||||
acc + &format!(" {}",name)[..]
|
||||
});
|
||||
|
||||
self.report_error(format!("'{}' isn't a valid value for '{}'{}{}",
|
||||
Format::Warning(arg),
|
||||
Format::Warning(opt),
|
||||
format!("\n\t[valid values:{}]\n",
|
||||
p_vals.iter()
|
||||
.fold(String::new(), |acc, name| {
|
||||
acc + &format!(" {}",name)[..]
|
||||
})),
|
||||
format!("\n\t[valid values:{}]\n", valid_values),
|
||||
suffix.0),
|
||||
true,
|
||||
Some(matches.args.keys().map(|k| *k).collect()));
|
||||
|
@ -1905,7 +1911,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
if let Some(ref opt) = self.opts.get(nvo) {
|
||||
// Check the possible values
|
||||
if let Some(ref p_vals) = opt.possible_vals {
|
||||
if !p_vals.contains(arg_slice) {
|
||||
if !p_vals.contains(&arg_slice) {
|
||||
self.possible_values_error(arg_slice, &opt.to_string(),
|
||||
p_vals, matches);
|
||||
}
|
||||
|
@ -2089,7 +2095,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
|
||||
|
||||
if let Some(ref p_vals) = p.possible_vals {
|
||||
if !p_vals.contains(arg_slice) {
|
||||
if !p_vals.contains(&arg_slice) {
|
||||
self.possible_values_error(arg_slice, &p.to_string(),
|
||||
p_vals, matches);
|
||||
}
|
||||
|
@ -2687,7 +2693,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
|
||||
fn validate_value(&self, v: &OptBuilder, av: &str, matches: &ArgMatches) {
|
||||
if let Some(ref p_vals) = v.possible_vals {
|
||||
if !p_vals.contains(av) {
|
||||
if !p_vals.contains(&av) {
|
||||
self.possible_values_error(av, &v.to_string(), p_vals, matches);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::str::FromStr;
|
|||
use std::ascii::AsciiExt;
|
||||
|
||||
/// Application level settings, which affect how `App` operates
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum AppSettings {
|
||||
/// Allows subcommands to override all requirements of the parent (this command). For example
|
||||
/// if you had a subcommand or even top level application which had a required arguments that
|
||||
|
|
|
@ -38,4 +38,17 @@ pub enum DidYouMeanMessageStyle {
|
|||
LongFlag,
|
||||
/// Suggested value is one of various possible values
|
||||
EnumValue,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn did_you_mean_possible_values() {
|
||||
let p_vals = ["test", "possible", "values"];
|
||||
assert_eq!(did_you_mean("tst", p_vals.iter()), Some("test"));
|
||||
assert!(did_you_mean("hahaahahah", p_vals.iter()).is_none());
|
||||
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use std::iter::IntoIterator;
|
||||
use std::collections::HashSet;
|
||||
#[cfg(feature = "yaml")]
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::BTreeSet;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
|
@ -86,7 +86,7 @@ pub struct Arg<'n, 'l, 'h, 'g, 'p, 'r> {
|
|||
#[doc(hidden)]
|
||||
pub group: Option<&'g str>,
|
||||
#[doc(hidden)]
|
||||
pub val_names: Option<Vec<&'n str>>,
|
||||
pub val_names: Option<BTreeSet<&'n str>>,
|
||||
#[doc(hidden)]
|
||||
pub num_vals: Option<u8>,
|
||||
#[doc(hidden)]
|
||||
|
@ -294,7 +294,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
|
|||
let mut num_names = 1;
|
||||
let mut name_first = false;
|
||||
let mut consec_names = false;
|
||||
let mut val_names = HashSet::new();
|
||||
let mut val_names = BTreeSet::new();
|
||||
|
||||
let parser = UsageParser::with_usage(u);
|
||||
for_match!{ parser,
|
||||
|
@ -377,7 +377,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
|
|||
blacklist: None,
|
||||
requires: None,
|
||||
num_vals: if num_names > 1 { Some(num_names) } else { None },
|
||||
val_names: if val_names.len() > 1 {Some(val_names.iter().map(|s| *s).collect::<Vec<_>>())}else{None},
|
||||
val_names: if val_names.len() > 1 {Some(val_names)}else{None},
|
||||
max_vals: None,
|
||||
min_vals: None,
|
||||
group: None,
|
||||
|
@ -945,9 +945,9 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
|
|||
where T: AsRef<str> + 'n,
|
||||
I: IntoIterator<Item=&'n T> {
|
||||
if let Some(ref mut vec) = self.val_names {
|
||||
names.into_iter().map(|s| vec.push(s.as_ref())).collect::<Vec<_>>();
|
||||
names.into_iter().map(|s| vec.insert(s.as_ref())).collect::<Vec<_>>();
|
||||
} else {
|
||||
self.val_names = Some(names.into_iter().map(|s| s.as_ref()).collect::<Vec<_>>());
|
||||
self.val_names = Some(names.into_iter().map(|s| s.as_ref()).collect::<BTreeSet<_>>());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -968,9 +968,11 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
|
|||
pub fn value_name(mut self, name: &'n str)
|
||||
-> Self {
|
||||
if let Some(ref mut vec) = self.val_names {
|
||||
vec.push(name);
|
||||
vec.insert(name);
|
||||
} else {
|
||||
self.val_names = Some(vec![name]);
|
||||
let mut bts = BTreeSet::new();
|
||||
bts.insert(name);
|
||||
self.val_names = Some(bts);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
|
|
@ -38,3 +38,38 @@ impl<'n> Display for FlagBuilder<'n> {
|
|||
}
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::FlagBuilder;
|
||||
|
||||
#[test]
|
||||
fn flagbuilder_display() {
|
||||
let f = FlagBuilder {
|
||||
name: "flg",
|
||||
short: None,
|
||||
long: Some("flag"),
|
||||
help: None,
|
||||
multiple: true,
|
||||
blacklist: None,
|
||||
requires: None,
|
||||
global: false,
|
||||
overrides: None
|
||||
};
|
||||
|
||||
assert_eq!(&*format!("{}", f), "--flag");
|
||||
|
||||
let f2 = FlagBuilder {
|
||||
name: "flg",
|
||||
short: Some('f'),
|
||||
long: None,
|
||||
help: None,
|
||||
multiple: false,
|
||||
blacklist: None,
|
||||
requires: None,
|
||||
global: false,
|
||||
overrides: None
|
||||
};
|
||||
|
||||
assert_eq!(&*format!("{}", f2), "-f");
|
||||
}
|
||||
}
|
|
@ -22,14 +22,14 @@ pub struct OptBuilder<'n> {
|
|||
/// exclusive arguments are evaluated.
|
||||
pub required: bool,
|
||||
/// A list of possible values for this argument
|
||||
pub possible_vals: Option<BTreeSet<&'n str>>,
|
||||
pub possible_vals: Option<Vec<&'n str>>,
|
||||
/// A list of names of other arguments that are *required* to be used when
|
||||
/// this flag is used
|
||||
pub requires: Option<Vec<&'n str>>,
|
||||
pub num_vals: Option<u8>,
|
||||
pub min_vals: Option<u8>,
|
||||
pub max_vals: Option<u8>,
|
||||
pub val_names: Option<Vec<&'n str>>,
|
||||
pub val_names: Option<BTreeSet<&'n str>>,
|
||||
pub empty_vals: bool,
|
||||
pub global: bool,
|
||||
pub validator: Option<Rc<Fn(String) -> StdResult<(), String>>>,
|
||||
|
@ -64,3 +64,60 @@ impl<'n> Display for OptBuilder<'n> {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::OptBuilder;
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
#[test]
|
||||
fn optbuilder_display() {
|
||||
let o = OptBuilder {
|
||||
name: "opt",
|
||||
short: None,
|
||||
long: Some("option"),
|
||||
help: None,
|
||||
multiple: true,
|
||||
blacklist: None,
|
||||
required: false,
|
||||
possible_vals: None,
|
||||
requires: None,
|
||||
num_vals: None,
|
||||
min_vals: None,
|
||||
max_vals: None,
|
||||
val_names: None,
|
||||
empty_vals: true,
|
||||
global: false,
|
||||
validator: None,
|
||||
overrides: None
|
||||
};
|
||||
|
||||
assert_eq!(&*format!("{}", o), "--option <opt>...");
|
||||
|
||||
let mut v_names = BTreeSet::new();
|
||||
v_names.insert("file");
|
||||
v_names.insert("name");
|
||||
|
||||
let o2 = OptBuilder {
|
||||
name: "opt",
|
||||
short: Some('o'),
|
||||
long: None,
|
||||
help: None,
|
||||
multiple: false,
|
||||
blacklist: None,
|
||||
required: false,
|
||||
possible_vals: None,
|
||||
requires: None,
|
||||
num_vals: None,
|
||||
min_vals: None,
|
||||
max_vals: None,
|
||||
val_names: Some(v_names),
|
||||
empty_vals: true,
|
||||
global: false,
|
||||
validator: None,
|
||||
overrides: None
|
||||
};
|
||||
|
||||
assert_eq!(&*format!("{}", o2), "-o <file> <name>");
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
use std::collections::BTreeSet;
|
||||
use std::fmt::{ Display, Formatter, Result };
|
||||
use std::result::Result as StdResult;
|
||||
use std::rc::Rc;
|
||||
|
@ -21,7 +20,7 @@ pub struct PosBuilder<'n> {
|
|||
/// A list of names for other arguments that *may not* be used with this flag
|
||||
pub blacklist: Option<Vec<&'n str>>,
|
||||
/// A list of possible values for this argument
|
||||
pub possible_vals: Option<BTreeSet<&'n str>>,
|
||||
pub possible_vals: Option<Vec<&'n str>>,
|
||||
/// The index of the argument
|
||||
pub index: u8,
|
||||
pub num_vals: Option<u8>,
|
||||
|
@ -48,3 +47,50 @@ impl<'n> Display for PosBuilder<'n> {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::PosBuilder;
|
||||
|
||||
#[test]
|
||||
fn posbuilder_display() {
|
||||
let p = PosBuilder {
|
||||
name: "pos",
|
||||
help: None,
|
||||
multiple: true,
|
||||
blacklist: None,
|
||||
required: false,
|
||||
possible_vals: None,
|
||||
requires: None,
|
||||
num_vals: None,
|
||||
min_vals: None,
|
||||
max_vals: None,
|
||||
index: 1,
|
||||
empty_vals: true,
|
||||
global: false,
|
||||
validator: None,
|
||||
overrides: None
|
||||
};
|
||||
|
||||
assert_eq!(&*format!("{}", p), "[pos]...");
|
||||
|
||||
let p2 = PosBuilder {
|
||||
name: "pos",
|
||||
help: None,
|
||||
multiple: false,
|
||||
blacklist: None,
|
||||
required: true,
|
||||
possible_vals: None,
|
||||
requires: None,
|
||||
num_vals: None,
|
||||
min_vals: None,
|
||||
max_vals: None,
|
||||
index: 1,
|
||||
empty_vals: true,
|
||||
global: false,
|
||||
validator: None,
|
||||
overrides: None
|
||||
};
|
||||
|
||||
assert_eq!(&*format!("{}", p2), "<pos>");
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
#[cfg(feature = "yaml")]
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Debug, Formatter, Result};
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
|
@ -46,13 +45,13 @@ pub struct ArgGroup<'n, 'ar> {
|
|||
#[doc(hidden)]
|
||||
pub name: &'n str,
|
||||
#[doc(hidden)]
|
||||
pub args: HashSet<&'ar str>,
|
||||
pub args: Vec<&'ar str>,
|
||||
#[doc(hidden)]
|
||||
pub required: bool,
|
||||
#[doc(hidden)]
|
||||
pub requires: Option<HashSet<&'ar str>>,
|
||||
pub requires: Option<Vec<&'ar str>>,
|
||||
#[doc(hidden)]
|
||||
pub conflicts: Option<HashSet<&'ar str>>
|
||||
pub conflicts: Option<Vec<&'ar str>>
|
||||
}
|
||||
|
||||
impl<'n, 'ar> ArgGroup<'n, 'ar> {
|
||||
|
@ -71,7 +70,7 @@ impl<'n, 'ar> ArgGroup<'n, 'ar> {
|
|||
ArgGroup {
|
||||
name: n,
|
||||
required: false,
|
||||
args: HashSet::new(),
|
||||
args: vec![],
|
||||
requires: None,
|
||||
conflicts: None
|
||||
}
|
||||
|
@ -141,7 +140,7 @@ impl<'n, 'ar> ArgGroup<'n, 'ar> {
|
|||
/// .add("config")
|
||||
/// # ).get_matches();
|
||||
pub fn add(mut self, n: &'ar str) -> Self {
|
||||
self.args.insert(n);
|
||||
self.args.push(n);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -202,11 +201,9 @@ impl<'n, 'ar> ArgGroup<'n, 'ar> {
|
|||
/// # ).get_matches();
|
||||
pub fn requires(mut self, n: &'ar str) -> Self {
|
||||
if let Some(ref mut reqs) = self.requires {
|
||||
reqs.insert(n);
|
||||
reqs.push(n);
|
||||
} else {
|
||||
let mut hs = HashSet::new();
|
||||
hs.insert(n);
|
||||
self.requires = Some(hs);
|
||||
self.requires = Some(vec![n]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -252,11 +249,9 @@ impl<'n, 'ar> ArgGroup<'n, 'ar> {
|
|||
/// # ).get_matches();
|
||||
pub fn conflicts_with(mut self, n: &'ar str) -> Self {
|
||||
if let Some(ref mut confs) = self.conflicts {
|
||||
confs.insert(n);
|
||||
confs.push(n);
|
||||
} else {
|
||||
let mut hs = HashSet::new();
|
||||
hs.insert(n);
|
||||
self.conflicts = Some(hs);
|
||||
self.conflicts = Some(vec![n]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -296,3 +291,32 @@ impl<'n, 'ar> Debug for ArgGroup<'n, 'ar> {
|
|||
}}", self.name, self.args, self.required, self.requires, self.conflicts)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::ArgGroup;
|
||||
|
||||
#[test]
|
||||
fn groups() {
|
||||
let g = ArgGroup::with_name("test")
|
||||
.add("a1")
|
||||
.add_all(&["a2", "a3"])
|
||||
.add("a4")
|
||||
.required(true)
|
||||
.conflicts_with("c1")
|
||||
.conflicts_with_all(&["c2", "c3"])
|
||||
.conflicts_with("c4")
|
||||
.requires("r1")
|
||||
.requires_all(&["r2", "r3"])
|
||||
.requires("r4");
|
||||
|
||||
let args = vec!["a1", "a2", "a3", "a4"];
|
||||
let reqs = vec!["r1", "r2", "r3", "r4"];
|
||||
let confs = vec!["c1", "c2", "c3", "c4"];
|
||||
|
||||
assert_eq!(g.args, args);
|
||||
assert_eq!(g.requires.unwrap(), reqs);
|
||||
assert_eq!(g.conflicts.unwrap(), confs);
|
||||
|
||||
}
|
||||
}
|
16
src/fmt.rs
16
src/fmt.rs
|
@ -48,3 +48,19 @@ impl<T: fmt::Display> fmt::Display for Format<T> {
|
|||
write!(f, "{}", &self.format())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::Format;
|
||||
use ansi_term::Colour::{Red, Green, Yellow};
|
||||
|
||||
#[test]
|
||||
fn colored_output() {
|
||||
let err = Format::Error("error");
|
||||
assert_eq!(&*format!("{}", err), &*format!("{}", Red.bold().paint("error")));
|
||||
let good = Format::Good("good");
|
||||
assert_eq!(&*format!("{}", good), &*format!("{}", Green.paint("good")));
|
||||
let warn = Format::Warning("warn");
|
||||
assert_eq!(&*format!("{}", warn), &*format!("{}", Yellow.paint("warn")));
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
use super::{App, Arg, SubCommand};
|
||||
use std::collections::HashSet;
|
||||
|
||||
use super::{App, Arg, SubCommand};
|
||||
use std::vec::Vec;
|
||||
|
||||
arg_enum!{
|
||||
|
@ -906,4 +907,6 @@ fn create_multiple_subcommands() {
|
|||
.arg(Arg::with_name("roster").short("r"))])
|
||||
.arg(Arg::with_name("other").long("other"))
|
||||
.get_matches();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -69,6 +69,15 @@ args:
|
|||
multiple: true
|
||||
help: Tests 3 max vals
|
||||
max_values: 3
|
||||
groups:
|
||||
- test:
|
||||
args:
|
||||
- maxvals3
|
||||
- minmals2
|
||||
conflicts_with:
|
||||
- option3
|
||||
requires:
|
||||
- multvals
|
||||
subcommands:
|
||||
- subcmd:
|
||||
about: tests subcommands
|
||||
|
|
|
@ -12,4 +12,17 @@ fn sub_command_negate_requred() {
|
|||
.subcommand(SubCommand::with_name("sub1"))
|
||||
.subcommand(SubCommand::with_name("sub1"))
|
||||
.get_matches_from(vec!["", "sub1"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn app_settings_fromstr() {
|
||||
assert_eq!("subcommandsnegatereqs".parse::<AppSettings>().ok().unwrap(), AppSettings::SubcommandsNegateReqs);
|
||||
assert_eq!("subcommandsrequired".parse::<AppSettings>().ok().unwrap(), AppSettings::SubcommandRequired);
|
||||
assert_eq!("argrequiredelsehelp".parse::<AppSettings>().ok().unwrap(), AppSettings::ArgRequiredElseHelp);
|
||||
assert_eq!("globalversion".parse::<AppSettings>().ok().unwrap(), AppSettings::GlobalVersion);
|
||||
assert_eq!("versionlesssubcommands".parse::<AppSettings>().ok().unwrap(), AppSettings::VersionlessSubcommands);
|
||||
assert_eq!("unifiedhelpmessage".parse::<AppSettings>().ok().unwrap(), AppSettings::UnifiedHelpMessage);
|
||||
assert_eq!("waitonerror".parse::<AppSettings>().ok().unwrap(), AppSettings::WaitOnError);
|
||||
assert_eq!("subcommandrequiredelsehelp".parse::<AppSettings>().ok().unwrap(), AppSettings::SubcommandRequiredElseHelp);
|
||||
assert!("hahahaha".parse::<AppSettings>().is_err());
|
||||
}
|
Loading…
Reference in a new issue