mirror of
https://github.com/ouch-org/ouch.git
synced 2025-06-07 03:55:28 +00:00
tests: Start adding test for the command-line interface
This commit is contained in:
parent
39abfdffde
commit
65bc13e8fa
162
src/cli.rs
162
src/cli.rs
@ -1,13 +1,13 @@
|
|||||||
use std::{convert::TryFrom, ffi::OsStr, path::PathBuf, vec::Vec};
|
use std::{convert::TryFrom, ffi::OsStr, path::PathBuf, vec::Vec};
|
||||||
|
|
||||||
use clap::{Arg};
|
use clap::{Arg, Values};
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
|
|
||||||
use crate::error;
|
use crate::error;
|
||||||
use crate::extensions::CompressionExtension;
|
use crate::extensions::CompressionExtension;
|
||||||
use crate::file::File;
|
use crate::file::File;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub enum CommandType {
|
pub enum CommandType {
|
||||||
Compression(
|
Compression(
|
||||||
// Files to be compressed
|
// Files to be compressed
|
||||||
@ -19,13 +19,13 @@ pub enum CommandType {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub struct Command {
|
pub struct Command {
|
||||||
pub command_type: CommandType,
|
pub command_type: CommandType,
|
||||||
pub output: Option<File>,
|
pub output: Option<File>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_matches() -> clap::ArgMatches<'static> {
|
pub fn clap_app<'a, 'b>() -> clap::App<'a, 'b> {
|
||||||
clap::App::new("ouch")
|
clap::App::new("ouch")
|
||||||
.version("0.1.0")
|
.version("0.1.0")
|
||||||
.about("ouch is a unified compression & decompression utility")
|
.about("ouch is a unified compression & decompression utility")
|
||||||
@ -53,7 +53,10 @@ pub fn get_matches() -> clap::ArgMatches<'static> {
|
|||||||
.help("Output file (TODO description)")
|
.help("Output file (TODO description)")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.get_matches()
|
}
|
||||||
|
|
||||||
|
pub fn get_matches() -> clap::ArgMatches<'static> {
|
||||||
|
clap_app().get_matches()
|
||||||
}
|
}
|
||||||
|
|
||||||
// holy spaghetti code
|
// holy spaghetti code
|
||||||
@ -62,24 +65,42 @@ impl TryFrom<clap::ArgMatches<'static>> for Command {
|
|||||||
type Error = error::Error;
|
type Error = error::Error;
|
||||||
|
|
||||||
fn try_from(matches: clap::ArgMatches<'static>) -> error::OuchResult<Command> {
|
fn try_from(matches: clap::ArgMatches<'static>) -> error::OuchResult<Command> {
|
||||||
|
|
||||||
|
let process_decompressible_input = |input_files: Values| {
|
||||||
|
let input_files = input_files
|
||||||
|
.map(|filename| (filename, CompressionExtension::try_from(filename)));
|
||||||
|
|
||||||
|
for file in input_files.clone() {
|
||||||
|
if let (file, Err(_)) = file {
|
||||||
|
// eprintln!("{}: file '{}' is not decompressible.", "error".red(), file);
|
||||||
|
return Err(error::Error::InputsMustHaveBeenDecompressible(file.into()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Ok(input_files
|
||||||
|
.map(|(filename, extension)|
|
||||||
|
(PathBuf::from(filename), extension.unwrap())
|
||||||
|
)
|
||||||
|
.collect::<Vec<_>>())
|
||||||
|
};
|
||||||
|
|
||||||
// Possibilities:
|
// Possibilities:
|
||||||
// * Case 1: output not supplied, therefore try to infer output by checking if all input files are decompressible
|
// * Case 1: output not supplied, therefore try to infer output by checking if all input files are decompressible
|
||||||
// * Case 2: output supplied
|
// * Case 2: output supplied
|
||||||
|
|
||||||
let output_was_supplied = matches.is_present("output");
|
let output_was_supplied = matches.is_present("output");
|
||||||
|
|
||||||
|
|
||||||
|
let input_files = matches
|
||||||
|
.values_of("input")
|
||||||
|
.unwrap(); // Safe to unwrap since input is an obligatory argument
|
||||||
|
|
||||||
if output_was_supplied {
|
if output_was_supplied {
|
||||||
let output_file = matches
|
let output_file = matches
|
||||||
.value_of("output")
|
.value_of("output")
|
||||||
.unwrap(); // Safe unwrap since we've established that output was supplied
|
.unwrap(); // Safe unwrap since we've established that output was supplied
|
||||||
|
|
||||||
let input_files = matches
|
|
||||||
.values_of("input")
|
|
||||||
.unwrap(); // Safe to unwrap since input is an obligatory argument
|
|
||||||
// .map(PathBuf::from)
|
|
||||||
// .collect();
|
|
||||||
|
|
||||||
|
|
||||||
let output_file_extension = CompressionExtension::try_from(output_file);
|
let output_file_extension = CompressionExtension::try_from(output_file);
|
||||||
let output_is_compressible = output_file_extension.is_ok();
|
let output_is_compressible = output_file_extension.is_ok();
|
||||||
if output_is_compressible {
|
if output_is_compressible {
|
||||||
@ -99,22 +120,8 @@ impl TryFrom<clap::ArgMatches<'static>> for Command {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Checking if input files are decompressible
|
// Checking if input files are decompressible
|
||||||
let input_files = input_files
|
|
||||||
.map(|filename| (filename, CompressionExtension::try_from(filename)));
|
|
||||||
|
|
||||||
for file in input_files.clone() {
|
let input_files = process_decompressible_input(input_files)?;
|
||||||
if let (file, Err(_)) = file {
|
|
||||||
// eprintln!("{}: file '{}' is not decompressible.", "error".red(), file);
|
|
||||||
return Err(error::Error::InputsMustHaveBeenDecompressible(file.into()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let input_files =
|
|
||||||
input_files
|
|
||||||
.map(|(filename, extension)|
|
|
||||||
(PathBuf::from(filename), extension.unwrap())
|
|
||||||
)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
println!("{}: attempting to decompress input files into {}", "info".yellow(), output_file);
|
println!("{}: attempting to decompress input files into {}", "info".yellow(), output_file);
|
||||||
return Ok(
|
return Ok(
|
||||||
@ -125,94 +132,17 @@ impl TryFrom<clap::ArgMatches<'static>> for Command {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// BIG TODO
|
// else: output file not supplied
|
||||||
Err(error::Error::MissingExtensionError("placeholder result".into()))
|
// Case 1: all input files are decompressible
|
||||||
|
// Case 2: error
|
||||||
|
let input_files = process_decompressible_input(input_files)?;
|
||||||
|
return Ok(
|
||||||
|
Command {
|
||||||
|
command_type: CommandType::Decompression(input_files),
|
||||||
|
output: None
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl TryFrom<clap::ArgMatches<'static>> for ArgValues {
|
|
||||||
// type Error = error::OuchError;
|
|
||||||
// fn try_from(matches: clap::ArgMatches<'static>) -> error::OuchResult<ArgValues> {
|
|
||||||
// // Case 1: -o was set
|
|
||||||
// // Case 1.1: -o was set and has a (supported) compression file extension
|
|
||||||
// // |--> Compress all input files into the supplied output file (no extension checks on inputs)
|
|
||||||
// // Case 1.2: -o was set and is not a supported expression
|
|
||||||
// // Case 2: -o was not set
|
|
||||||
// // Case 2.1: -o was not set and all input files are (supported) compression file extensions
|
|
||||||
// // |--> Decompress input files into inferred filenames or directories
|
|
||||||
// // Case 2.2: -o was not set and not all input files are (supported) compression file extensions
|
|
||||||
// // |--> Issue an error
|
|
||||||
|
|
||||||
// let inputs = matches
|
|
||||||
// .values_of("input")
|
|
||||||
// .unwrap() // Safe to unwrap since this is a required argument
|
|
||||||
// .map(|input: &str| {
|
|
||||||
// (
|
|
||||||
// PathBuf::from(input),
|
|
||||||
// CompressionExtension::try_from(input).ok(),
|
|
||||||
// )
|
|
||||||
// });
|
|
||||||
|
|
||||||
// let output_was_supplied = matches.is_present("output");
|
|
||||||
// let inputs_are_compressed_files = inputs.clone().all(|(_, ext)| ext.is_some());
|
|
||||||
|
|
||||||
// match (output_was_supplied, inputs_are_compressed_files) {
|
|
||||||
// (true, true) => {
|
|
||||||
// // -o was set and inputs are all valid compressed files
|
|
||||||
|
|
||||||
// let output = matches.value_of("output").unwrap();
|
|
||||||
// let output = PathBuf::from(output);
|
|
||||||
// match CompressionExtension::try_from(&output) {
|
|
||||||
// Ok(ext) => {
|
|
||||||
// // If the output file is a valid compressed file, then we compress the input files into it
|
|
||||||
// Ok(Self {
|
|
||||||
// command_type: CommandType::Compress(
|
|
||||||
// inputs.map(|(path, _)| path).collect(),
|
|
||||||
// ),
|
|
||||||
// output: Some((output, ext)),
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// Err(_) => {
|
|
||||||
// // If the output file is not a compressed file, then we decompress the input files into it
|
|
||||||
// Ok(Self {
|
|
||||||
// command_type: CommandType::Decompress(
|
|
||||||
// inputs.map(|(path, ext)| (path, ext.unwrap())).collect(),
|
|
||||||
// ),
|
|
||||||
// output: Some((output, CompressionExtension::NotCompressed)),
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// (true, false) => {
|
|
||||||
// // -o was set and inputs are not (all) valid compressed files
|
|
||||||
// let output_str = matches.value_of("output").unwrap();
|
|
||||||
// let output = PathBuf::from(output_str);
|
|
||||||
// let output_ext = match CompressionExtension::try_from(&output) {
|
|
||||||
// Ok(ext) => ext,
|
|
||||||
// Err(_) => {
|
|
||||||
// return Err(error::OuchError::MissingExtensionError(output_str.into()));
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Ok(Self {
|
|
||||||
// command_type: CommandType::Compress(inputs.map(|(path, _)| path).collect()),
|
|
||||||
// output: Some((output, output_ext)),
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// (false, true) => {
|
|
||||||
// // Case 2.1: -o was not set and all input files are (supported) compression file extensions
|
|
||||||
// Ok(Self {
|
|
||||||
// command_type: CommandType::Decompress(
|
|
||||||
// inputs.map(|(path, ext)| (path, ext.unwrap())).collect(),
|
|
||||||
// ),
|
|
||||||
// output: None,
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// (false, false) => {
|
|
||||||
// // Case 2.2: -o was not set and not all input files are not (supported) compression file extensions
|
|
||||||
// Err(error::OuchError::InvalidInput)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
@ -4,7 +4,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::error;
|
use crate::error;
|
||||||
#[derive(Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
/// Accepted extensions for input and output
|
/// Accepted extensions for input and output
|
||||||
pub enum CompressionExtension {
|
pub enum CompressionExtension {
|
||||||
// .gz
|
// .gz
|
||||||
|
@ -12,7 +12,7 @@ use crate::extensions::CompressionExtension;
|
|||||||
// pub filename: PathBuf,
|
// pub filename: PathBuf,
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub enum File {
|
pub enum File {
|
||||||
WithExtension((PathBuf, CompressionExtension)),
|
WithExtension((PathBuf, CompressionExtension)),
|
||||||
WithoutExtension(PathBuf)
|
WithoutExtension(PathBuf)
|
||||||
|
@ -6,6 +6,7 @@ mod cli;
|
|||||||
mod file;
|
mod file;
|
||||||
mod extensions;
|
mod extensions;
|
||||||
mod error;
|
mod error;
|
||||||
|
mod test;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
|
64
src/test.rs
64
src/test.rs
@ -0,0 +1,64 @@
|
|||||||
|
#[cfg(test)]
|
||||||
|
mod cli {
|
||||||
|
|
||||||
|
use std::{convert::TryFrom};
|
||||||
|
|
||||||
|
use crate::cli::clap_app;
|
||||||
|
use crate::cli::Command;
|
||||||
|
use crate::file::File;
|
||||||
|
use crate::cli::CommandType::*;
|
||||||
|
use crate::extensions::CompressionExtension::*;
|
||||||
|
use crate::error::OuchResult;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn decompress_files_into_folder() -> OuchResult<()> {
|
||||||
|
let matches = clap_app().
|
||||||
|
get_matches_from(
|
||||||
|
vec!["ouch", "-i", "file.zip", "-o", "folder/"]
|
||||||
|
);
|
||||||
|
let command_from_matches = Command::try_from(matches)?;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
command_from_matches,
|
||||||
|
Command {
|
||||||
|
command_type: Decompression(
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
"file.zip".into(),
|
||||||
|
Zip,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
output: Some(File::WithoutExtension("folder".into())),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn decompress_files() -> OuchResult<()> {
|
||||||
|
let matches = clap_app().
|
||||||
|
get_matches_from(
|
||||||
|
vec!["ouch", "-i", "file.zip"]
|
||||||
|
);
|
||||||
|
let command_from_matches = Command::try_from(matches)?;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
command_from_matches,
|
||||||
|
Command {
|
||||||
|
command_type: Decompression(
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
"file.zip".into(),
|
||||||
|
Zip,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
output: None,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user