use std::sync::Mutex;
use super::{CommandOutcome, CommandRunner, ServiceError};
#[derive(Debug)]
pub struct FakeProvider {
calls: Mutex<Vec<Vec<String>>>,
fail_run_at: Option<usize>,
run_count: Mutex<usize>,
}
impl FakeProvider {
#[must_use]
pub fn new() -> Self {
Self {
calls: Mutex::new(Vec::new()),
fail_run_at: None,
run_count: Mutex::new(0),
}
}
#[must_use]
pub fn failing() -> Self {
Self::failing_run_at(1)
}
#[must_use]
pub fn failing_run_at(number: usize) -> Self {
Self {
calls: Mutex::new(Vec::new()),
fail_run_at: Some(number),
run_count: Mutex::new(0),
}
}
#[must_use]
pub fn calls(&self) -> Vec<Vec<String>> {
self.calls.lock().expect("calls mutex poisoned").clone()
}
}
impl Default for FakeProvider {
fn default() -> Self {
Self::new()
}
}
impl CommandRunner for FakeProvider {
fn run(&self, program: &str, args: &[String]) -> Result<CommandOutcome, ServiceError> {
let mut call = Vec::with_capacity(args.len() + 1);
call.push(program.to_string());
call.extend(args.iter().cloned());
let success = if args.first().map(String::as_str) == Some("run") {
let mut count = self.run_count.lock().expect("run-count mutex poisoned");
*count += 1;
self.fail_run_at != Some(*count)
} else {
true
};
self.calls.lock().expect("calls mutex poisoned").push(call);
Ok(CommandOutcome {
success,
output: if success {
String::new()
} else {
"fake failure".to_string()
},
})
}
}