use std::{
env::args,
ffi::OsStr,
io::Error as IoError,
};
use mockall::{Sequence, automock};
#[automock]
pub trait Command {
fn args(&self, args: Vec<String>);
fn exec(&self) -> IoError;
fn stdin(&self, cfg: MockStdio);
fn stdout(&self, cfg: MockStdio);
fn stderr(&self, cfg: MockStdio);
}
#[derive(Debug, Default)]
pub struct FakeCommand {
command: MockCommand,
}
impl FakeCommand {
#[must_use]
pub fn new<S: AsRef<OsStr>>(_program: S) -> Self {
let mut sequence = Sequence::new();
let mut mock_command = MockCommand::new();
_ = mock_command.expect_args()
.withf(|list| list == &args().skip(1).collect::<Vec<_>>())
.times(1)
.in_sequence(&mut sequence)
.returning(|_| ())
;
_ = mock_command.expect_stdin()
.times(1)
.in_sequence(&mut sequence)
.returning(|_| ())
;
_ = mock_command.expect_stdout()
.times(1)
.in_sequence(&mut sequence)
.returning(|_| ())
;
_ = mock_command.expect_stderr()
.times(1)
.in_sequence(&mut sequence)
.returning(|_| ())
;
_ = mock_command.expect_exec()
.times(1)
.in_sequence(&mut sequence)
.returning(|| IoError::from_raw_os_error(0))
;
Self {
command: mock_command,
}
}
pub fn args(&mut self, args: Vec<String>) -> &mut Self {
self.command.args(args);
self
}
pub fn exec(&mut self) -> IoError {
self.command.exec()
}
pub fn stdin(&mut self, cfg: MockStdio) -> &mut Self {
self.command.stdin(cfg);
self
}
pub fn stdout(&mut self, cfg: MockStdio) -> &mut Self {
self.command.stdout(cfg);
self
}
pub fn stderr(&mut self, cfg: MockStdio) -> &mut Self {
self.command.stderr(cfg);
self
}
}
#[derive(Debug)]
#[non_exhaustive]
pub struct MockStdio;
#[expect(clippy::missing_const_for_fn, reason = "Needed for mock")]
impl MockStdio {
#[must_use]
pub fn inherit() -> Self {
Self
}
}
#[expect(clippy::missing_const_for_fn, reason = "Needed for mock")]
pub fn mock_exit(_code: i32) {}