mirror of
https://github.com/clap-rs/clap
synced 2024-12-14 14:52:33 +00:00
Merge #2855
2855: fix(gen)!: Simplify `Generator` trait r=pksunkara a=epage Co-authored-by: Ed Page <eopage@gmail.com>
This commit is contained in:
commit
36e172672c
8 changed files with 261 additions and 269 deletions
|
@ -4,7 +4,7 @@ mod shells;
|
|||
use std::io::Write;
|
||||
|
||||
// Internal
|
||||
use clap::{App, Arg};
|
||||
use clap::App;
|
||||
pub use shells::*;
|
||||
|
||||
/// Generator trait which can be used to write generators
|
||||
|
@ -53,255 +53,4 @@ pub trait Generator {
|
|||
/// }
|
||||
/// ```
|
||||
fn generate(&self, app: &App, buf: &mut dyn Write);
|
||||
|
||||
/// Gets all subcommands including child subcommands in the form of `("name", "bin_name")`.
|
||||
///
|
||||
/// Subcommand `rustup toolchain install` would be converted to
|
||||
/// `("install", "rustup toolchain install")`.
|
||||
fn all_subcommands(&self, app: &App) -> Vec<(String, String)> {
|
||||
let mut subcmds: Vec<_> = self.subcommands(app);
|
||||
|
||||
for sc_v in app.get_subcommands().map(|s| self.all_subcommands(s)) {
|
||||
subcmds.extend(sc_v);
|
||||
}
|
||||
|
||||
subcmds
|
||||
}
|
||||
|
||||
/// Finds the subcommand [`clap::App`] from the given [`clap::App`] with the given path.
|
||||
///
|
||||
/// **NOTE:** `path` should not contain the root `bin_name`.
|
||||
fn find_subcommand_with_path<'help, 'app>(
|
||||
&self,
|
||||
p: &'app App<'help>,
|
||||
path: Vec<&str>,
|
||||
) -> &'app App<'help> {
|
||||
let mut app = p;
|
||||
|
||||
for sc in path {
|
||||
app = app.find_subcommand(sc).unwrap();
|
||||
}
|
||||
|
||||
app
|
||||
}
|
||||
|
||||
/// Gets subcommands of [`clap::App`] in the form of `("name", "bin_name")`.
|
||||
///
|
||||
/// Subcommand `rustup toolchain install` would be converted to
|
||||
/// `("install", "rustup toolchain install")`.
|
||||
fn subcommands(&self, p: &App) -> Vec<(String, String)> {
|
||||
debug!("subcommands: name={}", p.get_name());
|
||||
debug!("subcommands: Has subcommands...{:?}", p.has_subcommands());
|
||||
|
||||
let mut subcmds = vec![];
|
||||
|
||||
if !p.has_subcommands() {
|
||||
return subcmds;
|
||||
}
|
||||
|
||||
for sc in p.get_subcommands() {
|
||||
let sc_bin_name = sc.get_bin_name().unwrap();
|
||||
|
||||
debug!(
|
||||
"subcommands:iter: name={}, bin_name={}",
|
||||
sc.get_name(),
|
||||
sc_bin_name
|
||||
);
|
||||
|
||||
subcmds.push((sc.get_name().to_string(), sc_bin_name.to_string()));
|
||||
}
|
||||
|
||||
subcmds
|
||||
}
|
||||
|
||||
/// Gets all the short options, their visible aliases and flags of a [`clap::App`].
|
||||
/// Includes `h` and `V` depending on the [`clap::AppSettings`].
|
||||
fn shorts_and_visible_aliases(&self, p: &App) -> Vec<char> {
|
||||
debug!("shorts: name={}", p.get_name());
|
||||
|
||||
p.get_arguments()
|
||||
.filter_map(|a| {
|
||||
if a.get_index().is_none() {
|
||||
if a.get_visible_short_aliases().is_some() && a.get_short().is_some() {
|
||||
let mut shorts_and_visible_aliases = a.get_visible_short_aliases().unwrap();
|
||||
shorts_and_visible_aliases.push(a.get_short().unwrap());
|
||||
Some(shorts_and_visible_aliases)
|
||||
} else if a.get_visible_short_aliases().is_none() && a.get_short().is_some() {
|
||||
Some(vec![a.get_short().unwrap()])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Gets all the long options, their visible aliases and flags of a [`clap::App`].
|
||||
/// Includes `help` and `version` depending on the [`clap::AppSettings`].
|
||||
fn longs_and_visible_aliases(&self, p: &App) -> Vec<String> {
|
||||
debug!("longs: name={}", p.get_name());
|
||||
|
||||
p.get_arguments()
|
||||
.filter_map(|a| {
|
||||
if a.get_index().is_none() {
|
||||
if a.get_visible_aliases().is_some() && a.get_long().is_some() {
|
||||
let mut visible_aliases: Vec<_> = a
|
||||
.get_visible_aliases()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect();
|
||||
visible_aliases.push(a.get_long().unwrap().to_string());
|
||||
Some(visible_aliases)
|
||||
} else if a.get_visible_aliases().is_none() && a.get_long().is_some() {
|
||||
Some(vec![a.get_long().unwrap().to_string()])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Gets all the flags of a [`clap::App`](App).
|
||||
/// Includes `help` and `version` depending on the [`clap::AppSettings`].
|
||||
fn flags<'help>(&self, p: &App<'help>) -> Vec<Arg<'help>> {
|
||||
debug!("flags: name={}", p.get_name());
|
||||
p.get_flags().cloned().collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Generator for Foo {
|
||||
fn generate(&self, _: &App, _: &mut dyn Write) {}
|
||||
|
||||
fn file_name(&self, name: &str) -> String {
|
||||
name.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
fn common() -> App<'static> {
|
||||
let mut app = App::new("myapp")
|
||||
.version("3.0")
|
||||
.subcommand(
|
||||
App::new("test").subcommand(App::new("config")).arg(
|
||||
Arg::new("file")
|
||||
.short('f')
|
||||
.short_alias('c')
|
||||
.visible_short_alias('p')
|
||||
.long("file")
|
||||
.visible_alias("path"),
|
||||
),
|
||||
)
|
||||
.subcommand(App::new("hello"))
|
||||
.bin_name("my-app");
|
||||
|
||||
app._build();
|
||||
app._build_bin_names();
|
||||
app
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subcommands() {
|
||||
let app = common();
|
||||
|
||||
assert_eq!(
|
||||
Foo.subcommands(&app),
|
||||
vec![
|
||||
("test".to_string(), "my-app test".to_string()),
|
||||
("hello".to_string(), "my-app hello".to_string()),
|
||||
("help".to_string(), "my-app help".to_string()),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_subcommands() {
|
||||
let app = common();
|
||||
|
||||
assert_eq!(
|
||||
Foo.all_subcommands(&app),
|
||||
vec![
|
||||
("test".to_string(), "my-app test".to_string()),
|
||||
("hello".to_string(), "my-app hello".to_string()),
|
||||
("help".to_string(), "my-app help".to_string()),
|
||||
("config".to_string(), "my-app test config".to_string()),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_subcommand_with_path() {
|
||||
let app = common();
|
||||
let sc_app = Foo.find_subcommand_with_path(&app, "test config".split(' ').collect());
|
||||
|
||||
assert_eq!(sc_app.get_name(), "config");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flags() {
|
||||
let app = common();
|
||||
let flags = Foo.flags(&app);
|
||||
|
||||
assert_eq!(flags.len(), 2);
|
||||
assert_eq!(flags[0].get_long(), Some("help"));
|
||||
assert_eq!(flags[1].get_long(), Some("version"));
|
||||
|
||||
let sc_flags = Foo.flags(Foo.find_subcommand_with_path(&app, vec!["test"]));
|
||||
|
||||
assert_eq!(sc_flags.len(), 3);
|
||||
assert_eq!(sc_flags[0].get_long(), Some("file"));
|
||||
assert_eq!(sc_flags[1].get_long(), Some("help"));
|
||||
assert_eq!(sc_flags[2].get_long(), Some("version"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shorts() {
|
||||
let app = common();
|
||||
let shorts = Foo.shorts_and_visible_aliases(&app);
|
||||
|
||||
assert_eq!(shorts.len(), 2);
|
||||
assert_eq!(shorts[0], 'h');
|
||||
assert_eq!(shorts[1], 'V');
|
||||
|
||||
let sc_shorts =
|
||||
Foo.shorts_and_visible_aliases(Foo.find_subcommand_with_path(&app, vec!["test"]));
|
||||
|
||||
assert_eq!(sc_shorts.len(), 4);
|
||||
assert_eq!(sc_shorts[0], 'p');
|
||||
assert_eq!(sc_shorts[1], 'f');
|
||||
assert_eq!(sc_shorts[2], 'h');
|
||||
assert_eq!(sc_shorts[3], 'V');
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_longs() {
|
||||
let app = common();
|
||||
let longs = Foo.longs_and_visible_aliases(&app);
|
||||
|
||||
assert_eq!(longs.len(), 2);
|
||||
assert_eq!(longs[0], "help");
|
||||
assert_eq!(longs[1], "version");
|
||||
|
||||
let sc_longs =
|
||||
Foo.longs_and_visible_aliases(Foo.find_subcommand_with_path(&app, vec!["test"]));
|
||||
|
||||
assert_eq!(sc_longs.len(), 4);
|
||||
assert_eq!(sc_longs[0], "path");
|
||||
assert_eq!(sc_longs[1], "file");
|
||||
assert_eq!(sc_longs[2], "help");
|
||||
assert_eq!(sc_longs[3], "version");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
use std::io::Write;
|
||||
|
||||
// Internal
|
||||
use crate::utils;
|
||||
use crate::Generator;
|
||||
use clap::*;
|
||||
|
||||
|
@ -75,8 +76,7 @@ fn all_subcommands(app: &App) -> String {
|
|||
debug!("all_subcommands");
|
||||
|
||||
let mut subcmds = vec![String::new()];
|
||||
let mut scs = Bash
|
||||
.all_subcommands(app)
|
||||
let mut scs = utils::all_subcommands(app)
|
||||
.iter()
|
||||
.map(|x| x.0.clone())
|
||||
.collect::<Vec<_>>();
|
||||
|
@ -101,8 +101,7 @@ fn subcommand_details(app: &App) -> String {
|
|||
debug!("subcommand_details");
|
||||
|
||||
let mut subcmd_dets = vec![String::new()];
|
||||
let mut scs = Bash
|
||||
.all_subcommands(app)
|
||||
let mut scs = utils::all_subcommands(app)
|
||||
.iter()
|
||||
.map(|x| x.1.replace(" ", "__"))
|
||||
.collect::<Vec<_>>();
|
||||
|
@ -138,7 +137,7 @@ fn subcommand_details(app: &App) -> String {
|
|||
fn option_details_for_path(app: &App, path: &str) -> String {
|
||||
debug!("option_details_for_path: path={}", path);
|
||||
|
||||
let p = Bash.find_subcommand_with_path(app, path.split("__").skip(1).collect());
|
||||
let p = utils::find_subcommand_with_path(app, path.split("__").skip(1).collect());
|
||||
let mut opts = vec![String::new()];
|
||||
|
||||
for o in p.get_opts() {
|
||||
|
@ -191,17 +190,15 @@ fn vals_for(o: &Arg) -> String {
|
|||
fn all_options_for_path(app: &App, path: &str) -> String {
|
||||
debug!("all_options_for_path: path={}", path);
|
||||
|
||||
let p = Bash.find_subcommand_with_path(app, path.split("__").skip(1).collect());
|
||||
let scs: Vec<_> = Bash.subcommands(p).iter().map(|x| x.0.clone()).collect();
|
||||
let p = utils::find_subcommand_with_path(app, path.split("__").skip(1).collect());
|
||||
let scs: Vec<_> = utils::subcommands(p).iter().map(|x| x.0.clone()).collect();
|
||||
|
||||
let opts = format!(
|
||||
"{shorts} {longs} {pos} {subcmds}",
|
||||
shorts = Bash
|
||||
.shorts_and_visible_aliases(p)
|
||||
shorts = utils::shorts_and_visible_aliases(p)
|
||||
.iter()
|
||||
.fold(String::new(), |acc, s| format!("{} -{}", acc, s)),
|
||||
longs = Bash
|
||||
.longs_and_visible_aliases(p)
|
||||
longs = utils::longs_and_visible_aliases(p)
|
||||
.iter()
|
||||
.fold(String::new(), |acc, l| format!("{} --{}", acc, l)),
|
||||
pos = p
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
use std::io::Write;
|
||||
|
||||
// Internal
|
||||
use crate::utils;
|
||||
use crate::Generator;
|
||||
use crate::INTERNAL_ERROR_MSG;
|
||||
use clap::*;
|
||||
|
@ -99,7 +100,7 @@ fn generate_inner<'help>(
|
|||
}
|
||||
}
|
||||
|
||||
for flag in Elvish.flags(p) {
|
||||
for flag in utils::flags(p) {
|
||||
if let Some(shorts) = flag.get_short_and_visible_aliases() {
|
||||
let tooltip = get_tooltip(flag.get_about(), shorts[0]);
|
||||
for short in shorts {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
use std::io::Write;
|
||||
|
||||
// Internal
|
||||
use crate::utils;
|
||||
use crate::Generator;
|
||||
use clap::*;
|
||||
|
||||
|
@ -96,7 +97,7 @@ fn gen_fish_inner(root_command: &str, parent_commands: &[&str], app: &App, buffe
|
|||
buffer.push('\n');
|
||||
}
|
||||
|
||||
for flag in Fish.flags(app) {
|
||||
for flag in utils::flags(app) {
|
||||
let mut template = basic_template.clone();
|
||||
|
||||
if let Some(shorts) = flag.get_short_and_visible_aliases() {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
use std::io::Write;
|
||||
|
||||
// Internal
|
||||
use crate::utils;
|
||||
use crate::Generator;
|
||||
use crate::INTERNAL_ERROR_MSG;
|
||||
use clap::*;
|
||||
|
@ -115,7 +116,7 @@ fn generate_inner<'help>(
|
|||
}
|
||||
}
|
||||
|
||||
for flag in PowerShell.flags(p) {
|
||||
for flag in utils::flags(p) {
|
||||
if let Some(shorts) = flag.get_short_and_visible_aliases() {
|
||||
let tooltip = get_tooltip(flag.get_about(), shorts[0]);
|
||||
for short in shorts {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
use std::io::Write;
|
||||
|
||||
// Internal
|
||||
use crate::utils;
|
||||
use crate::Generator;
|
||||
use crate::INTERNAL_ERROR_MSG;
|
||||
use clap::*;
|
||||
|
@ -100,7 +101,7 @@ _{bin_name_underscore}_commands() {{
|
|||
ret.push(parent_text);
|
||||
|
||||
// Next we start looping through all the children, grandchildren, etc.
|
||||
let mut all_subcommands = Zsh.all_subcommands(p);
|
||||
let mut all_subcommands = utils::all_subcommands(p);
|
||||
|
||||
all_subcommands.sort();
|
||||
all_subcommands.dedup();
|
||||
|
@ -216,7 +217,7 @@ fn get_subcommands_of(parent: &App) -> String {
|
|||
return String::new();
|
||||
}
|
||||
|
||||
let subcommand_names = Zsh.subcommands(parent);
|
||||
let subcommand_names = utils::subcommands(parent);
|
||||
let mut all_subcommands = vec![];
|
||||
|
||||
for &(ref name, ref bin_name) in &subcommand_names {
|
||||
|
@ -528,7 +529,7 @@ fn write_flags_of(p: &App, p_global: Option<&App>) -> String {
|
|||
|
||||
let mut ret = vec![];
|
||||
|
||||
for f in Zsh.flags(p) {
|
||||
for f in utils::flags(p) {
|
||||
debug!("write_flags_of:iter: f={}", f.get_name());
|
||||
|
||||
let help = f.get_about().map_or(String::new(), escape_help);
|
||||
|
|
|
@ -66,6 +66,8 @@ mod macros;
|
|||
pub mod generators;
|
||||
/// Contains supported shells for auto-completion scripts
|
||||
mod shell;
|
||||
/// Helpers for writing generators
|
||||
pub mod utils;
|
||||
|
||||
use std::ffi::OsString;
|
||||
use std::fs::File;
|
||||
|
|
240
clap_generate/src/utils.rs
Normal file
240
clap_generate/src/utils.rs
Normal file
|
@ -0,0 +1,240 @@
|
|||
use clap::{App, Arg};
|
||||
|
||||
/// Gets all subcommands including child subcommands in the form of `("name", "bin_name")`.
|
||||
///
|
||||
/// Subcommand `rustup toolchain install` would be converted to
|
||||
/// `("install", "rustup toolchain install")`.
|
||||
pub fn all_subcommands(app: &App) -> Vec<(String, String)> {
|
||||
let mut subcmds: Vec<_> = subcommands(app);
|
||||
|
||||
for sc_v in app.get_subcommands().map(|s| all_subcommands(s)) {
|
||||
subcmds.extend(sc_v);
|
||||
}
|
||||
|
||||
subcmds
|
||||
}
|
||||
|
||||
/// Finds the subcommand [`clap::App`] from the given [`clap::App`] with the given path.
|
||||
///
|
||||
/// **NOTE:** `path` should not contain the root `bin_name`.
|
||||
pub fn find_subcommand_with_path<'help, 'app>(
|
||||
p: &'app App<'help>,
|
||||
path: Vec<&str>,
|
||||
) -> &'app App<'help> {
|
||||
let mut app = p;
|
||||
|
||||
for sc in path {
|
||||
app = app.find_subcommand(sc).unwrap();
|
||||
}
|
||||
|
||||
app
|
||||
}
|
||||
|
||||
/// Gets subcommands of [`clap::App`] in the form of `("name", "bin_name")`.
|
||||
///
|
||||
/// Subcommand `rustup toolchain install` would be converted to
|
||||
/// `("install", "rustup toolchain install")`.
|
||||
pub fn subcommands(p: &App) -> Vec<(String, String)> {
|
||||
debug!("subcommands: name={}", p.get_name());
|
||||
debug!("subcommands: Has subcommands...{:?}", p.has_subcommands());
|
||||
|
||||
let mut subcmds = vec![];
|
||||
|
||||
if !p.has_subcommands() {
|
||||
return subcmds;
|
||||
}
|
||||
|
||||
for sc in p.get_subcommands() {
|
||||
let sc_bin_name = sc.get_bin_name().unwrap();
|
||||
|
||||
debug!(
|
||||
"subcommands:iter: name={}, bin_name={}",
|
||||
sc.get_name(),
|
||||
sc_bin_name
|
||||
);
|
||||
|
||||
subcmds.push((sc.get_name().to_string(), sc_bin_name.to_string()));
|
||||
}
|
||||
|
||||
subcmds
|
||||
}
|
||||
|
||||
/// Gets all the short options, their visible aliases and flags of a [`clap::App`].
|
||||
/// Includes `h` and `V` depending on the [`clap::AppSettings`].
|
||||
pub fn shorts_and_visible_aliases(p: &App) -> Vec<char> {
|
||||
debug!("shorts: name={}", p.get_name());
|
||||
|
||||
p.get_arguments()
|
||||
.filter_map(|a| {
|
||||
if a.get_index().is_none() {
|
||||
if a.get_visible_short_aliases().is_some() && a.get_short().is_some() {
|
||||
let mut shorts_and_visible_aliases = a.get_visible_short_aliases().unwrap();
|
||||
shorts_and_visible_aliases.push(a.get_short().unwrap());
|
||||
Some(shorts_and_visible_aliases)
|
||||
} else if a.get_visible_short_aliases().is_none() && a.get_short().is_some() {
|
||||
Some(vec![a.get_short().unwrap()])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Gets all the long options, their visible aliases and flags of a [`clap::App`].
|
||||
/// Includes `help` and `version` depending on the [`clap::AppSettings`].
|
||||
pub fn longs_and_visible_aliases(p: &App) -> Vec<String> {
|
||||
debug!("longs: name={}", p.get_name());
|
||||
|
||||
p.get_arguments()
|
||||
.filter_map(|a| {
|
||||
if a.get_index().is_none() {
|
||||
if a.get_visible_aliases().is_some() && a.get_long().is_some() {
|
||||
let mut visible_aliases: Vec<_> = a
|
||||
.get_visible_aliases()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect();
|
||||
visible_aliases.push(a.get_long().unwrap().to_string());
|
||||
Some(visible_aliases)
|
||||
} else if a.get_visible_aliases().is_none() && a.get_long().is_some() {
|
||||
Some(vec![a.get_long().unwrap().to_string()])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Gets all the flags of a [`clap::App`](App).
|
||||
/// Includes `help` and `version` depending on the [`clap::AppSettings`].
|
||||
pub fn flags<'help>(p: &App<'help>) -> Vec<Arg<'help>> {
|
||||
debug!("flags: name={}", p.get_name());
|
||||
p.get_flags().cloned().collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use clap::Arg;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
fn common() -> App<'static> {
|
||||
let mut app = App::new("myapp")
|
||||
.version("3.0")
|
||||
.subcommand(
|
||||
App::new("test").subcommand(App::new("config")).arg(
|
||||
Arg::new("file")
|
||||
.short('f')
|
||||
.short_alias('c')
|
||||
.visible_short_alias('p')
|
||||
.long("file")
|
||||
.visible_alias("path"),
|
||||
),
|
||||
)
|
||||
.subcommand(App::new("hello"))
|
||||
.bin_name("my-app");
|
||||
|
||||
app._build();
|
||||
app._build_bin_names();
|
||||
app
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subcommands() {
|
||||
let app = common();
|
||||
|
||||
assert_eq!(
|
||||
subcommands(&app),
|
||||
vec![
|
||||
("test".to_string(), "my-app test".to_string()),
|
||||
("hello".to_string(), "my-app hello".to_string()),
|
||||
("help".to_string(), "my-app help".to_string()),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_subcommands() {
|
||||
let app = common();
|
||||
|
||||
assert_eq!(
|
||||
all_subcommands(&app),
|
||||
vec![
|
||||
("test".to_string(), "my-app test".to_string()),
|
||||
("hello".to_string(), "my-app hello".to_string()),
|
||||
("help".to_string(), "my-app help".to_string()),
|
||||
("config".to_string(), "my-app test config".to_string()),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_subcommand_with_path() {
|
||||
let app = common();
|
||||
let sc_app = find_subcommand_with_path(&app, "test config".split(' ').collect());
|
||||
|
||||
assert_eq!(sc_app.get_name(), "config");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flags() {
|
||||
let app = common();
|
||||
let actual_flags = flags(&app);
|
||||
|
||||
assert_eq!(actual_flags.len(), 2);
|
||||
assert_eq!(actual_flags[0].get_long(), Some("help"));
|
||||
assert_eq!(actual_flags[1].get_long(), Some("version"));
|
||||
|
||||
let sc_flags = flags(find_subcommand_with_path(&app, vec!["test"]));
|
||||
|
||||
assert_eq!(sc_flags.len(), 3);
|
||||
assert_eq!(sc_flags[0].get_long(), Some("file"));
|
||||
assert_eq!(sc_flags[1].get_long(), Some("help"));
|
||||
assert_eq!(sc_flags[2].get_long(), Some("version"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shorts() {
|
||||
let app = common();
|
||||
let shorts = shorts_and_visible_aliases(&app);
|
||||
|
||||
assert_eq!(shorts.len(), 2);
|
||||
assert_eq!(shorts[0], 'h');
|
||||
assert_eq!(shorts[1], 'V');
|
||||
|
||||
let sc_shorts = shorts_and_visible_aliases(find_subcommand_with_path(&app, vec!["test"]));
|
||||
|
||||
assert_eq!(sc_shorts.len(), 4);
|
||||
assert_eq!(sc_shorts[0], 'p');
|
||||
assert_eq!(sc_shorts[1], 'f');
|
||||
assert_eq!(sc_shorts[2], 'h');
|
||||
assert_eq!(sc_shorts[3], 'V');
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_longs() {
|
||||
let app = common();
|
||||
let longs = longs_and_visible_aliases(&app);
|
||||
|
||||
assert_eq!(longs.len(), 2);
|
||||
assert_eq!(longs[0], "help");
|
||||
assert_eq!(longs[1], "version");
|
||||
|
||||
let sc_longs = longs_and_visible_aliases(find_subcommand_with_path(&app, vec!["test"]));
|
||||
|
||||
assert_eq!(sc_longs.len(), 4);
|
||||
assert_eq!(sc_longs[0], "path");
|
||||
assert_eq!(sc_longs[1], "file");
|
||||
assert_eq!(sc_longs[2], "help");
|
||||
assert_eq!(sc_longs[3], "version");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue