Skip to content

Commit

Permalink
Merge pull request #511 from ouch-org/cli-add-tests
Browse files Browse the repository at this point in the history
add tests for CLI usage
  • Loading branch information
figsoda authored Sep 16, 2023
2 parents 6d4e8be + c7d4829 commit 4703f1b
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 4 deletions.
156 changes: 154 additions & 2 deletions src/cli/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use clap::{Parser, ValueHint};
/// Supported formats: tar, zip, gz, xz/lzma, bz/bz2, lz4, sz, zst.
///
/// Repository: https://github.com/ouch-org/ouch
#[derive(Parser, Debug)]
#[derive(Parser, Debug, PartialEq)]
#[command(about, version)]
// Disable rustdoc::bare_urls because rustdoc parses URLs differently than Clap
#[allow(rustdoc::bare_urls)]
Expand Down Expand Up @@ -41,7 +41,7 @@ pub struct CliArgs {
#[arg(short, long, global = true)]
pub format: Option<OsString>,

/// Ouch and claps subcommands
// Ouch and claps subcommands
#[command(subcommand)]
pub cmd: Subcommand,
}
Expand Down Expand Up @@ -97,3 +97,155 @@ pub enum Subcommand {
tree: bool,
},
}

#[cfg(test)]
mod tests {
use super::*;

fn args_splitter(input: &str) -> impl Iterator<Item = &str> {
input.split_whitespace()
}

fn to_paths(iter: impl IntoIterator<Item = &'static str>) -> Vec<PathBuf> {
iter.into_iter().map(PathBuf::from).collect()
}

macro_rules! test {
($args:expr, $expected:expr) => {
let result = match CliArgs::try_parse_from(args_splitter($args)) {
Ok(result) => result,
Err(err) => panic!(
"CLI result is Err, expected Ok, input: '{}'.\nResult: '{err}'",
$args
),
};
assert_eq!(result, $expected, "CLI result mismatched, input: '{}'.", $args);
};
}

fn mock_cli_args() -> CliArgs {
CliArgs {
yes: false,
no: false,
accessible: false,
hidden: false,
quiet: false,
gitignore: false,
format: None,
// This is usually replaced in assertion tests
cmd: Subcommand::Decompress {
// Put a crazy value here so no test can assert it unintentionally
files: vec!["\x00\x11\x22".into()],
output_dir: None,
},
}
}

#[test]
fn test_clap_cli_ok() {
test!(
"ouch decompress file.tar.gz",
CliArgs {
cmd: Subcommand::Decompress {
files: to_paths(["file.tar.gz"]),
output_dir: None,
},
..mock_cli_args()
}
);
test!(
"ouch d file.tar.gz",
CliArgs {
cmd: Subcommand::Decompress {
files: to_paths(["file.tar.gz"]),
output_dir: None,
},
..mock_cli_args()
}
);
test!(
"ouch d a b c",
CliArgs {
cmd: Subcommand::Decompress {
files: to_paths(["a", "b", "c"]),
output_dir: None,
},
..mock_cli_args()
}
);

test!(
"ouch compress file file.tar.gz",
CliArgs {
cmd: Subcommand::Compress {
files: to_paths(["file"]),
output: PathBuf::from("file.tar.gz"),
level: None,
fast: false,
slow: false,
},
..mock_cli_args()
}
);
test!(
"ouch compress a b c archive.tar.gz",
CliArgs {
cmd: Subcommand::Compress {
files: to_paths(["a", "b", "c"]),
output: PathBuf::from("archive.tar.gz"),
level: None,
fast: false,
slow: false,
},
..mock_cli_args()
}
);
test!(
"ouch compress a b c archive.tar.gz",
CliArgs {
cmd: Subcommand::Compress {
files: to_paths(["a", "b", "c"]),
output: PathBuf::from("archive.tar.gz"),
level: None,
fast: false,
slow: false,
},
..mock_cli_args()
}
);

let inputs = [
"ouch compress a b c output --format tar.gz",
// https://github.com/clap-rs/clap/issues/5115
// "ouch compress a b c --format tar.gz output",
// "ouch compress a b --format tar.gz c output",
// "ouch compress a --format tar.gz b c output",
"ouch compress --format tar.gz a b c output",
"ouch --format tar.gz compress a b c output",
];
for input in inputs {
test!(
input,
CliArgs {
cmd: Subcommand::Compress {
files: to_paths(["a", "b", "c"]),
output: PathBuf::from("output"),
level: None,
fast: false,
slow: false,
},
format: Some("tar.gz".into()),
..mock_cli_args()
}
);
}
}

#[test]
fn test_clap_cli_err() {
assert!(CliArgs::try_parse_from(args_splitter("ouch c")).is_err());
assert!(CliArgs::try_parse_from(args_splitter("ouch c input")).is_err());
assert!(CliArgs::try_parse_from(args_splitter("ouch d")).is_err());
assert!(CliArgs::try_parse_from(args_splitter("ouch l")).is_err());
}
}
2 changes: 1 addition & 1 deletion src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl CliArgs {
/// And:
/// 1. Make paths absolute.
/// 2. Checks the QuestionPolicy.
pub fn parse_args() -> crate::Result<(Self, QuestionPolicy, FileVisibilityPolicy)> {
pub fn parse_and_validate_args() -> crate::Result<(Self, QuestionPolicy, FileVisibilityPolicy)> {
let mut args = Self::parse();

set_accessible(args.accessible);
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ fn main() {
}

fn run() -> Result<()> {
let (args, skip_questions_positively, file_visibility_policy) = CliArgs::parse_args()?;
let (args, skip_questions_positively, file_visibility_policy) = CliArgs::parse_and_validate_args()?;
commands::run(args, skip_questions_positively, file_visibility_policy)
}

0 comments on commit 4703f1b

Please sign in to comment.