Permalink
Browse files

Introduce a glorious new cli arg splitter

Allow &str and &[&str] as input for `command`

Fixes #25
  • Loading branch information...
killercup committed Mar 23, 2017
1 parent b386d23 commit a04a0e1a57ee83c7634e6ff1fa8494a8a73b54cd
Showing with 110 additions and 2 deletions.
  1. +12 −2 src/lib.rs
  2. +98 −0 src/parse_cmd.rs
View
@@ -119,6 +119,9 @@ pub use macros::flatten_escaped_string;
mod output;
use output::{OutputAssertion, StdErr, StdOut};
mod parse_cmd;
use parse_cmd::ToCmd;
mod diff;
/// Assertions for a specific command.
@@ -178,9 +181,16 @@ impl Assert {
/// assert_cli::Assert::command(&["echo", "1337"])
/// .unwrap();
/// ```
pub fn command(cmd: &[&str]) -> Self {
///
/// ```rust
/// extern crate assert_cli;
///
/// assert_cli::Assert::command("echo 1337")
/// .unwrap();
/// ```
pub fn command<'a, T: ToCmd<'a> + ?Sized>(cmd: &'a T) -> Self {
Assert {
cmd: cmd.into_iter().cloned().map(String::from).collect(),
cmd: cmd.to_cmd(),
..Self::default()
}
}
View
@@ -0,0 +1,98 @@
pub trait ToCmd<'a> {
fn to_cmd(&'a self) -> Vec<String>;
}
impl<'a> ToCmd<'a> for str {
fn to_cmd(&'a self) -> Vec<String> {
let mut args = Vec::new();
let mut current_arg = String::new();
let mut in_quote = Vec::new();
for c in self.chars() {
if in_quote.is_empty() && c.is_whitespace() {
args.push(current_arg);
current_arg = String::new();
continue;
}
current_arg.push(c);
if c == '"' || c == '\'' {
if in_quote.last() == Some(&c) {
in_quote.pop();
} else {
in_quote.push(c);
}
}
}
if !current_arg.is_empty() {
args.push(current_arg);
}
args
}
}
impl<'a, 'b, T> ToCmd<'a> for T where
&'a T: AsRef<[&'b str]>,
T: 'a,
{
fn to_cmd(&'a self) -> Vec<String> {
self.as_ref().into_iter().map(|x| x.to_string()).collect()
}
}
#[cfg(test)]
mod test {
use super::ToCmd;
#[test]
fn slices() {
assert_eq!(
ToCmd::to_cmd(&["echo", "42"]),
vec!["echo", "42"]
);
}
#[test]
fn simple() {
assert_eq!(
"echo 42".to_cmd(),
vec!["echo", "42"]
);
assert_eq!(
r#"echo "42""#.to_cmd(),
vec!["echo", "\"42\""]
);
assert_eq!(
r#"echo '42'"#.to_cmd(),
vec!["echo", "\'42\'"]
);
assert_eq!(
r#"echo '42 is the answer'"#.to_cmd(),
vec!["echo", "\'42 is the answer\'"]
);
}
#[test]
fn real_world() {
assert_eq!(
r#"cargo run --bin whatever -- --input="Lorem ipsum" -f"#.to_cmd(),
vec!["cargo", "run", "--bin", "whatever", "--", "--input=\"Lorem ipsum\"", "-f"]
);
}
#[test]
fn nested_quotes() {
assert_eq!(
r#"echo "lorem ipsum 'dolor' sit amet""#.to_cmd(),
vec!["echo", "\"lorem ipsum 'dolor' sit amet\""]
);
assert_eq!(
r#"echo "lorem ipsum ('dolor "doloris" septetur') sit amet""#.to_cmd(),
vec!["echo", "\"lorem ipsum ('dolor \"doloris\" septetur') sit amet\""]
);
}
}

0 comments on commit a04a0e1

Please sign in to comment.