diff --git a/README.md b/README.md index 66e0b1b..0dfed25 100644 --- a/README.md +++ b/README.md @@ -78,3 +78,7 @@ Once you have that installed, just run cargo build --release ``` and you will find an executable in `target/release`. + +### Unit tests + +In order for the unit tests to pass, you will need `python3` diff --git a/src/command.rs b/src/command.rs index 3e3f5f1..be7431f 100644 --- a/src/command.rs +++ b/src/command.rs @@ -3,6 +3,7 @@ use crate::logger::{LogLevel, Logger}; use std::error::Error; use std::fmt::{Display, Formatter}; use std::io; +use std::iter::once; use std::process::{Command, ExitStatus, Stdio}; pub trait LogRunnable { @@ -47,12 +48,20 @@ impl Display for SpecificExecutionError<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!( f, - "Failed to execute command {:?}: {}", - self.command, self.error + "Failed to execute command '{}': {}", + command_to_string(self.command), + self.error ) } } +fn command_to_string(command: &Command) -> String { + once(command.get_program().to_string_lossy()) + .chain(command.get_args().map(|arg| arg.to_string_lossy())) + .collect::>() + .join(" ") +} + impl Error for SpecificExecutionError<'_> {} #[derive(Debug)] @@ -76,9 +85,9 @@ impl From for ExecutionError { impl Display for ExecutionError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - ExecutionError::StartError(e) => write!(f, "failed to start command: {}", e), + ExecutionError::StartError(e) => write!(f, "Failed to start command: {}", e), ExecutionError::BadExitStatus(status) => { - write!(f, "command failed with exit status: {}", status) + write!(f, "Command failed with {}", status) } } } @@ -90,23 +99,40 @@ impl Error for ExecutionError {} mod test { use crate::command::{ExecutionError, LogRunnable, SpecificExecutionError}; use crate::logger::Logger; + use std::path::PathBuf; use std::process::Command; #[test] fn test_unknown_command() { - let mut command = Command::new("a_command_which_def_doesnt_exist"); + let mut command = Command::new("python7"); let Err( e @ SpecificExecutionError { error: ExecutionError::StartError(_), .. }, - ) = command.args(["foo", "bar"]).run(&Logger::default()) + ) = command + .args([PathBuf::from("test-ressources/python/exit_1.py")]) + .run(&Logger::default()) else { panic!("command shouldn't exist"); }; - println!("{e}"); + assert_eq!(e.to_string(), "Failed to execute command 'python7': Failed to start command: No such file or directory (os error 2)"); } #[test] - fn test_error() {} + fn test_error() { + let mut command = Command::new("python3"); + let Err( + e @ SpecificExecutionError { + error: ExecutionError::BadExitStatus(_), + .. + }, + ) = command + .arg("test-ressources/python/exit_1.py") + .run(&Logger::default()) + else { + panic!("command should return exit-code 1") + }; + assert_eq!(e.to_string(), "Failed to execute command 'python3 test-ressources/python/exit_1.py': Command failed with exit status: 1"); + } } diff --git a/src/logger.rs b/src/logger.rs index 89226b6..57ddae5 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -39,7 +39,7 @@ macro_rules! log { $logger.$level(format!($($args)*)); }; ($logger:expr, $($args:tt)*) => { - log!($logger, info, $($args)*); + log!($logger, info, $($args)*); //TODO better use default level with log function instead of assuming info as default } } diff --git a/test-ressources/python/exit_1.py b/test-ressources/python/exit_1.py new file mode 100644 index 0000000..b11a11b --- /dev/null +++ b/test-ressources/python/exit_1.py @@ -0,0 +1 @@ +exit(1) \ No newline at end of file