diff options
Diffstat (limited to 'vendor/xflags-macros/tests/it')
-rw-r--r-- | vendor/xflags-macros/tests/it/help.rs | 144 | ||||
-rw-r--r-- | vendor/xflags-macros/tests/it/main.rs | 198 | ||||
-rw-r--r-- | vendor/xflags-macros/tests/it/repeated_pos.rs | 94 | ||||
-rw-r--r-- | vendor/xflags-macros/tests/it/smoke.rs | 112 | ||||
-rw-r--r-- | vendor/xflags-macros/tests/it/src/help.rs | 25 | ||||
-rw-r--r-- | vendor/xflags-macros/tests/it/src/repeated_pos.rs | 9 | ||||
-rw-r--r-- | vendor/xflags-macros/tests/it/src/smoke.rs | 15 | ||||
-rw-r--r-- | vendor/xflags-macros/tests/it/src/subcommands.rs | 20 | ||||
-rw-r--r-- | vendor/xflags-macros/tests/it/subcommands.rs | 225 |
9 files changed, 842 insertions, 0 deletions
diff --git a/vendor/xflags-macros/tests/it/help.rs b/vendor/xflags-macros/tests/it/help.rs new file mode 100644 index 000000000..36a966485 --- /dev/null +++ b/vendor/xflags-macros/tests/it/help.rs @@ -0,0 +1,144 @@ +#![allow(unused)] +use std::{ffi::OsString, path::PathBuf}; + +#[derive(Debug)] +pub struct Helpful { + pub src: Option<PathBuf>, + pub extra: Option<String>, + + pub switch: (), + pub subcommand: HelpfulCmd, +} + +#[derive(Debug)] +pub enum HelpfulCmd { + Sub(Sub), +} + +#[derive(Debug)] +pub struct Sub { + pub flag: bool, +} + +impl Helpful { + pub const HELP: &'static str = Self::HELP_; + + #[allow(dead_code)] + pub fn from_env() -> xflags::Result<Self> { + Self::from_env_() + } + + #[allow(dead_code)] + pub fn from_vec(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> { + Self::from_vec_(args) + } +} + +impl Helpful { + fn from_env_() -> xflags::Result<Self> { + let mut p = xflags::rt::Parser::new_from_env(); + Self::parse_(&mut p) + } + fn from_vec_(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> { + let mut p = xflags::rt::Parser::new(args); + Self::parse_(&mut p) + } +} + +impl Helpful { + fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> { + let mut switch = Vec::new(); + + let mut src = (false, Vec::new()); + let mut extra = (false, Vec::new()); + + let mut sub_ = None; + while let Some(arg_) = p_.pop_flag() { + match arg_ { + Ok(flag_) => match flag_.as_str() { + "--switch" | "-s" => switch.push(()), + _ => return Err(p_.unexpected_flag(&flag_)), + }, + Err(arg_) => { + match arg_.to_str().unwrap_or("") { + "sub" => { + sub_ = Some(HelpfulCmd::Sub(Sub::parse_(p_)?)); + break; + } + _ => (), + } + if let (done_ @ false, buf_) = &mut src { + buf_.push(arg_.into()); + *done_ = true; + continue; + } + if let (done_ @ false, buf_) = &mut extra { + buf_.push(p_.value_from_str::<String>("extra", arg_)?); + *done_ = true; + continue; + } + return Err(p_.unexpected_arg(arg_)); + } + } + } + Ok(Self { + src: p_.optional("src", src.1)?, + extra: p_.optional("extra", extra.1)?, + + switch: p_.required("--switch", switch)?, + subcommand: p_.subcommand(sub_)?, + }) + } +} + +impl Sub { + fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> { + let mut flag = Vec::new(); + + while let Some(arg_) = p_.pop_flag() { + match arg_ { + Ok(flag_) => match flag_.as_str() { + "--flag" | "-f" => flag.push(()), + _ => return Err(p_.unexpected_flag(&flag_)), + }, + Err(arg_) => { + return Err(p_.unexpected_arg(arg_)); + } + } + } + Ok(Self { flag: p_.optional("--flag", flag)?.is_some() }) + } +} +impl Helpful { + const HELP_: &'static str = "\ +helpful + Does stuff + + Helpful stuff. + +ARGS: + [src] + With an arg. + + [extra] + Another arg. + + This time, we provide some extra info about the + arg. Maybe some caveats, or what kinds of + values are accepted. + +OPTIONS: + -s, --switch + And a switch. + +SUBCOMMANDS: + +helpful sub + And even a subcommand! + + OPTIONS: + -f, --flag + With an optional flag. This has a really long + description which spans multiple lines. +"; +} diff --git a/vendor/xflags-macros/tests/it/main.rs b/vendor/xflags-macros/tests/it/main.rs new file mode 100644 index 000000000..1ce058814 --- /dev/null +++ b/vendor/xflags-macros/tests/it/main.rs @@ -0,0 +1,198 @@ +mod repeated_pos; +mod smoke; +mod subcommands; +mod help; + +use std::{ffi::OsString, fmt}; + +use expect_test::{expect, Expect}; + +fn check<F, A>(f: F, args: &str, expect: Expect) +where + F: FnOnce(Vec<OsString>) -> xflags::Result<A>, + A: fmt::Debug, +{ + let args = args.split_ascii_whitespace().map(OsString::from).collect::<Vec<_>>(); + let res = f(args); + match res { + Ok(args) => { + expect.assert_debug_eq(&args); + } + Err(err) => { + expect.assert_eq(&err.to_string()); + } + } +} + +#[test] +fn smoke() { + check( + smoke::RustAnalyzer::from_vec, + "-n 92 .", + expect![[r#" + RustAnalyzer { + workspace: ".", + jobs: None, + log_file: None, + verbose: 0, + number: 92, + data: [], + emoji: false, + } + "#]], + ); + check( + smoke::RustAnalyzer::from_vec, + "-n 92 -v --verbose -v --data 0xDEAD --log-file /tmp/log.txt --data 0xBEEF .", + expect![[r#" + RustAnalyzer { + workspace: ".", + jobs: None, + log_file: Some( + "/tmp/log.txt", + ), + verbose: 3, + number: 92, + data: [ + "0xDEAD", + "0xBEEF", + ], + emoji: false, + } + "#]], + ); + + check( + smoke::RustAnalyzer::from_vec, + "-n 92 --werbose", + expect![[r#"unexpected flag: `--werbose`"#]], + ); + check(smoke::RustAnalyzer::from_vec, "", expect![[r#"flag is required: `workspace`"#]]); + check(smoke::RustAnalyzer::from_vec, ".", expect![[r#"flag is required: `--number`"#]]); + check(smoke::RustAnalyzer::from_vec, "-n", expect![[r#"expected a value for `-n`"#]]); + check( + smoke::RustAnalyzer::from_vec, + "-n lol", + expect![[r#"can't parse `-n`, invalid digit found in string"#]], + ); + check( + smoke::RustAnalyzer::from_vec, + "-n 1 -n 2 .", + expect![[r#"flag specified more than once: `--number`"#]], + ); + check( + smoke::RustAnalyzer::from_vec, + "-n 1 . 92 lol", + expect![[r#"unexpected argument: "lol""#]], + ); + check( + smoke::RustAnalyzer::from_vec, + "-n 1 . --emoji --emoji", + expect![[r#"flag specified more than once: `--emoji`"#]], + ); +} + +#[test] +fn repeated_argument() { + check( + repeated_pos::RepeatedPos::from_vec, + "a 11 c d e f", + expect![[r#" + RepeatedPos { + a: "a", + b: Some( + 11, + ), + c: Some( + "c", + ), + rest: [ + "d", + "e", + "f", + ], + } + "#]], + ); +} + +#[test] +fn subcommands() { + check( + subcommands::RustAnalyzer::from_vec, + "server", + expect![[r#" + RustAnalyzer { + verbose: 0, + subcommand: Server( + Server { + dir: None, + subcommand: Launch( + Launch { + log: false, + }, + ), + }, + ), + } + "#]], + ); + + check( + subcommands::RustAnalyzer::from_vec, + "server --dir . --log", + expect![[r#" + RustAnalyzer { + verbose: 0, + subcommand: Server( + Server { + dir: Some( + ".", + ), + subcommand: Launch( + Launch { + log: true, + }, + ), + }, + ), + } + "#]], + ); + + check( + subcommands::RustAnalyzer::from_vec, + "server watch", + expect![[r#" + RustAnalyzer { + verbose: 0, + subcommand: Server( + Server { + dir: None, + subcommand: Watch( + Watch, + ), + }, + ), + } + "#]], + ); + + check( + subcommands::RustAnalyzer::from_vec, + "-v analysis-stats . --parallel", + expect![[r#" + RustAnalyzer { + verbose: 1, + subcommand: AnalysisStats( + AnalysisStats { + path: ".", + parallel: true, + }, + ), + } + "#]], + ); + + check(subcommands::RustAnalyzer::from_vec, "", expect![[r#"subcommand is required"#]]); +} diff --git a/vendor/xflags-macros/tests/it/repeated_pos.rs b/vendor/xflags-macros/tests/it/repeated_pos.rs new file mode 100644 index 000000000..334af371d --- /dev/null +++ b/vendor/xflags-macros/tests/it/repeated_pos.rs @@ -0,0 +1,94 @@ +#![allow(unused)] +use std::{ffi::OsString, path::PathBuf}; + +#[derive(Debug)] +pub struct RepeatedPos { + pub a: PathBuf, + pub b: Option<u32>, + pub c: Option<OsString>, + pub rest: Vec<OsString>, +} + +impl RepeatedPos { + pub const HELP: &'static str = Self::HELP_; + + #[allow(dead_code)] + pub fn from_env() -> xflags::Result<Self> { + Self::from_env_() + } + + #[allow(dead_code)] + pub fn from_vec(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> { + Self::from_vec_(args) + } +} + +impl RepeatedPos { + fn from_env_() -> xflags::Result<Self> { + let mut p = xflags::rt::Parser::new_from_env(); + Self::parse_(&mut p) + } + fn from_vec_(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> { + let mut p = xflags::rt::Parser::new(args); + Self::parse_(&mut p) + } +} + +impl RepeatedPos { + fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> { + let mut a = (false, Vec::new()); + let mut b = (false, Vec::new()); + let mut c = (false, Vec::new()); + let mut rest = (false, Vec::new()); + + while let Some(arg_) = p_.pop_flag() { + match arg_ { + Ok(flag_) => match flag_.as_str() { + _ => return Err(p_.unexpected_flag(&flag_)), + }, + Err(arg_) => { + if let (done_ @ false, buf_) = &mut a { + buf_.push(arg_.into()); + *done_ = true; + continue; + } + if let (done_ @ false, buf_) = &mut b { + buf_.push(p_.value_from_str::<u32>("b", arg_)?); + *done_ = true; + continue; + } + if let (done_ @ false, buf_) = &mut c { + buf_.push(arg_.into()); + *done_ = true; + continue; + } + if let (false, buf_) = &mut rest { + buf_.push(arg_.into()); + continue; + } + return Err(p_.unexpected_arg(arg_)); + } + } + } + Ok(Self { + a: p_.required("a", a.1)?, + b: p_.optional("b", b.1)?, + c: p_.optional("c", c.1)?, + rest: rest.1, + }) + } +} +impl RepeatedPos { + const HELP_: &'static str = "\ +RepeatedPos + +ARGS: + <a> + + [b] + + [c] + + <rest>... +"; +} diff --git a/vendor/xflags-macros/tests/it/smoke.rs b/vendor/xflags-macros/tests/it/smoke.rs new file mode 100644 index 000000000..e22c4f1f6 --- /dev/null +++ b/vendor/xflags-macros/tests/it/smoke.rs @@ -0,0 +1,112 @@ +#![allow(unused)] +use std::{ffi::OsString, path::PathBuf}; + +#[derive(Debug)] +pub struct RustAnalyzer { + pub workspace: PathBuf, + pub jobs: Option<u32>, + + pub log_file: Option<PathBuf>, + pub verbose: u32, + pub number: u32, + pub data: Vec<OsString>, + pub emoji: bool, +} + +impl RustAnalyzer { + pub const HELP: &'static str = Self::HELP_; + + #[allow(dead_code)] + pub fn from_env() -> xflags::Result<Self> { + Self::from_env_() + } + + #[allow(dead_code)] + pub fn from_vec(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> { + Self::from_vec_(args) + } +} + +impl RustAnalyzer { + fn from_env_() -> xflags::Result<Self> { + let mut p = xflags::rt::Parser::new_from_env(); + Self::parse_(&mut p) + } + fn from_vec_(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> { + let mut p = xflags::rt::Parser::new(args); + Self::parse_(&mut p) + } +} + +impl RustAnalyzer { + fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> { + let mut log_file = Vec::new(); + let mut verbose = Vec::new(); + let mut number = Vec::new(); + let mut data = Vec::new(); + let mut emoji = Vec::new(); + + let mut workspace = (false, Vec::new()); + let mut jobs = (false, Vec::new()); + + while let Some(arg_) = p_.pop_flag() { + match arg_ { + Ok(flag_) => match flag_.as_str() { + "--log-file" => log_file.push(p_.next_value(&flag_)?.into()), + "--verbose" | "-v" => verbose.push(()), + "--number" | "-n" => number.push(p_.next_value_from_str::<u32>(&flag_)?), + "--data" => data.push(p_.next_value(&flag_)?.into()), + "--emoji" => emoji.push(()), + _ => return Err(p_.unexpected_flag(&flag_)), + }, + Err(arg_) => { + if let (done_ @ false, buf_) = &mut workspace { + buf_.push(arg_.into()); + *done_ = true; + continue; + } + if let (done_ @ false, buf_) = &mut jobs { + buf_.push(p_.value_from_str::<u32>("jobs", arg_)?); + *done_ = true; + continue; + } + return Err(p_.unexpected_arg(arg_)); + } + } + } + Ok(Self { + workspace: p_.required("workspace", workspace.1)?, + jobs: p_.optional("jobs", jobs.1)?, + + log_file: p_.optional("--log-file", log_file)?, + verbose: verbose.len() as u32, + number: p_.required("--number", number)?, + data: data, + emoji: p_.optional("--emoji", emoji)?.is_some(), + }) + } +} +impl RustAnalyzer { + const HELP_: &'static str = "\ +rust-analyzer + LSP server for rust. + +ARGS: + <workspace> + + [jobs] + Number of concurrent jobs. + +OPTIONS: + --log-file <path> + Path to log file. By default, logs go to stderr. + + -v, --verbose + + -n, --number <n> + + --data <value> + + --emoji +"; +} diff --git a/vendor/xflags-macros/tests/it/src/help.rs b/vendor/xflags-macros/tests/it/src/help.rs new file mode 100644 index 000000000..d552c1e63 --- /dev/null +++ b/vendor/xflags-macros/tests/it/src/help.rs @@ -0,0 +1,25 @@ +xflags! { + /// Does stuff + /// + /// Helpful stuff. + cmd helpful + /// With an arg. + optional src: PathBuf + /// Another arg. + /// + /// This time, we provide some extra info about the + /// arg. Maybe some caveats, or what kinds of + /// values are accepted. + optional extra: String + { + /// And a switch. + required -s, --switch + + /// And even a subcommand! + cmd sub { + /// With an optional flag. This has a really long + /// description which spans multiple lines. + optional -f, --flag + } + } +} diff --git a/vendor/xflags-macros/tests/it/src/repeated_pos.rs b/vendor/xflags-macros/tests/it/src/repeated_pos.rs new file mode 100644 index 000000000..4106c65eb --- /dev/null +++ b/vendor/xflags-macros/tests/it/src/repeated_pos.rs @@ -0,0 +1,9 @@ +xflags! { + cmd RepeatedPos + required a: PathBuf + optional b: u32 + optional c: OsString + repeated rest: OsString + { + } +} diff --git a/vendor/xflags-macros/tests/it/src/smoke.rs b/vendor/xflags-macros/tests/it/src/smoke.rs new file mode 100644 index 000000000..ae303779e --- /dev/null +++ b/vendor/xflags-macros/tests/it/src/smoke.rs @@ -0,0 +1,15 @@ +xflags! { + /// LSP server for rust. + cmd rust-analyzer + required workspace: PathBuf + /// Number of concurrent jobs. + optional jobs: u32 + { + /// Path to log file. By default, logs go to stderr. + optional --log-file path: PathBuf + repeated -v, --verbose + required -n, --number n: u32 + repeated --data value: OsString + optional --emoji + } +} diff --git a/vendor/xflags-macros/tests/it/src/subcommands.rs b/vendor/xflags-macros/tests/it/src/subcommands.rs new file mode 100644 index 000000000..70a0a5049 --- /dev/null +++ b/vendor/xflags-macros/tests/it/src/subcommands.rs @@ -0,0 +1,20 @@ +xflags! { + cmd rust-analyzer { + repeated -v, --verbose + + cmd server { + optional --dir path:PathBuf + default cmd launch { + optional --log + } + cmd watch { + } + } + + cmd analysis-stats + required path: PathBuf + { + optional --parallel + } + } +} diff --git a/vendor/xflags-macros/tests/it/subcommands.rs b/vendor/xflags-macros/tests/it/subcommands.rs new file mode 100644 index 000000000..7941a395d --- /dev/null +++ b/vendor/xflags-macros/tests/it/subcommands.rs @@ -0,0 +1,225 @@ +#![allow(unused)] +use std::{ffi::OsString, path::PathBuf}; + +#[derive(Debug)] +pub struct RustAnalyzer { + pub verbose: u32, + pub subcommand: RustAnalyzerCmd, +} + +#[derive(Debug)] +pub enum RustAnalyzerCmd { + Server(Server), + AnalysisStats(AnalysisStats), +} + +#[derive(Debug)] +pub struct Server { + pub dir: Option<PathBuf>, + pub subcommand: ServerCmd, +} + +#[derive(Debug)] +pub enum ServerCmd { + Launch(Launch), + Watch(Watch), +} + +#[derive(Debug)] +pub struct Launch { + pub log: bool, +} + +#[derive(Debug)] +pub struct Watch; + +#[derive(Debug)] +pub struct AnalysisStats { + pub path: PathBuf, + + pub parallel: bool, +} + +impl RustAnalyzer { + pub const HELP: &'static str = Self::HELP_; + + #[allow(dead_code)] + pub fn from_env() -> xflags::Result<Self> { + Self::from_env_() + } + + #[allow(dead_code)] + pub fn from_vec(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> { + Self::from_vec_(args) + } +} + +impl RustAnalyzer { + fn from_env_() -> xflags::Result<Self> { + let mut p = xflags::rt::Parser::new_from_env(); + Self::parse_(&mut p) + } + fn from_vec_(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> { + let mut p = xflags::rt::Parser::new(args); + Self::parse_(&mut p) + } +} + +impl RustAnalyzer { + fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> { + let mut verbose = Vec::new(); + + let mut sub_ = None; + while let Some(arg_) = p_.pop_flag() { + match arg_ { + Ok(flag_) => match flag_.as_str() { + "--verbose" | "-v" => verbose.push(()), + _ => return Err(p_.unexpected_flag(&flag_)), + }, + Err(arg_) => { + match arg_.to_str().unwrap_or("") { + "server" => { + sub_ = Some(RustAnalyzerCmd::Server(Server::parse_(p_)?)); + break; + } + "analysis-stats" => { + sub_ = Some(RustAnalyzerCmd::AnalysisStats(AnalysisStats::parse_(p_)?)); + break; + } + _ => (), + } + return Err(p_.unexpected_arg(arg_)); + } + } + } + Ok(Self { verbose: verbose.len() as u32, subcommand: p_.subcommand(sub_)? }) + } +} + +impl Server { + fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> { + let mut dir = Vec::new(); + + let mut sub_ = None; + while let Some(arg_) = p_.pop_flag() { + match arg_ { + Ok(flag_) => match flag_.as_str() { + "--dir" => dir.push(p_.next_value(&flag_)?.into()), + _ => { + p_.push_back(Ok(flag_)); + break; + } + }, + Err(arg_) => { + match arg_.to_str().unwrap_or("") { + "watch" => { + sub_ = Some(ServerCmd::Watch(Watch::parse_(p_)?)); + break; + } + _ => (), + } + p_.push_back(Err(arg_)); + break; + } + } + } + if sub_.is_none() { + sub_ = Some(ServerCmd::Launch(Launch::parse_(p_)?)); + } + Ok(Self { dir: p_.optional("--dir", dir)?, subcommand: p_.subcommand(sub_)? }) + } +} + +impl Launch { + fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> { + let mut log = Vec::new(); + + while let Some(arg_) = p_.pop_flag() { + match arg_ { + Ok(flag_) => match flag_.as_str() { + "--log" => log.push(()), + _ => return Err(p_.unexpected_flag(&flag_)), + }, + Err(arg_) => { + return Err(p_.unexpected_arg(arg_)); + } + } + } + Ok(Self { log: p_.optional("--log", log)?.is_some() }) + } +} + +impl Watch { + fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> { + while let Some(arg_) = p_.pop_flag() { + match arg_ { + Ok(flag_) => match flag_.as_str() { + _ => return Err(p_.unexpected_flag(&flag_)), + }, + Err(arg_) => { + return Err(p_.unexpected_arg(arg_)); + } + } + } + Ok(Self {}) + } +} + +impl AnalysisStats { + fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> { + let mut parallel = Vec::new(); + + let mut path = (false, Vec::new()); + + while let Some(arg_) = p_.pop_flag() { + match arg_ { + Ok(flag_) => match flag_.as_str() { + "--parallel" => parallel.push(()), + _ => return Err(p_.unexpected_flag(&flag_)), + }, + Err(arg_) => { + if let (done_ @ false, buf_) = &mut path { + buf_.push(arg_.into()); + *done_ = true; + continue; + } + return Err(p_.unexpected_arg(arg_)); + } + } + } + Ok(Self { + path: p_.required("path", path.1)?, + + parallel: p_.optional("--parallel", parallel)?.is_some(), + }) + } +} +impl RustAnalyzer { + const HELP_: &'static str = "\ +rust-analyzer + +OPTIONS: + -v, --verbose + +SUBCOMMANDS: + +rust-analyzer server + + OPTIONS: + --dir <path> + + --log + + +rust-analyzer server watch + + +rust-analyzer analysis-stats + + ARGS: + <path> + + OPTIONS: + --parallel +"; +} |