use std::process::{Child, Command};
struct CommandRunner {
command: Vec<String>,
restart: bool,
clear: bool,
current_process: Option<Child>,
}
impl CommandRunner {
fn new(command: Vec<String>, restart: bool, clear: bool) -> Self {
Self {
command,
restart,
clear,
current_process: None,
}
}
fn dry_run(&mut self) -> Result<(), String> {
if self.restart {
if self.current_process.is_some() {
self.current_process = None;
}
}
if self.command.is_empty() {
return Err("Empty command".to_string());
}
if self.restart {
self.current_process = Some(mock_child_process());
}
Ok(())
}
}
fn mock_child_process() -> Child {
Command::new("echo").arg("test").spawn().unwrap()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_command_runner_new() {
let cmd = vec!["cargo".to_string(), "test".to_string()];
let runner = CommandRunner::new(cmd.clone(), true, false);
assert_eq!(runner.command, cmd);
assert_eq!(runner.restart, true);
assert_eq!(runner.clear, false);
assert!(runner.current_process.is_none());
}
#[test]
fn test_command_runner_dry_run_empty_command() {
let mut runner = CommandRunner::new(vec![], false, false);
let result = runner.dry_run();
assert!(result.is_err());
assert_eq!(result.unwrap_err(), "Empty command");
}
#[test]
fn test_command_runner_dry_run_success() {
let mut runner =
CommandRunner::new(vec!["echo".to_string(), "test".to_string()], false, false);
let result = runner.dry_run();
assert!(result.is_ok());
assert!(runner.current_process.is_none()); }
#[test]
fn test_command_runner_restart_mode() {
let mut runner =
CommandRunner::new(vec!["echo".to_string(), "test".to_string()], true, false);
let result = runner.dry_run();
assert!(result.is_ok());
assert!(runner.current_process.is_some());
let _first_proc_id = runner.current_process.as_ref().unwrap().id();
let result = runner.dry_run();
assert!(result.is_ok());
assert!(runner.current_process.is_some());
assert!(runner.current_process.is_some());
if let Some(mut child) = runner.current_process.take() {
let _ = child.kill();
}
}
}