use crate::types::FeatureList;
use std::{error, path, process};
use termcolor::WriteColor;
pub struct TestRunner {
command: process::Command,
crate_name: String,
features: String,
working_dir: path::PathBuf,
cargo_command: String,
}
fn split_slice<'a>(slice: &'a [String], item: &'a str) -> (&'a [String], &'a [String]) {
if let Some(pos) = slice.iter().position(|s| s == item) {
(&slice[..pos], &slice[pos..])
} else {
(slice, &[])
}
}
impl TestRunner {
pub fn new(
cargo_command: String,
crate_name: String,
feature_set: FeatureList,
cargo_args: &[String],
working_dir: path::PathBuf,
) -> Self {
let mut command = process::Command::new(crate::cargo_cmd());
command.arg(cargo_command.clone());
let (cargo_args_b, cargo_args_a) = split_slice(cargo_args, "--");
command.args(cargo_args_b.iter());
command.arg("--no-default-features");
let mut features = feature_set
.iter()
.fold(String::new(), |s, feature| s + feature + ",");
if !features.is_empty() {
features.remove(features.len() - 1);
command.arg("--features");
command.arg(&features);
}
command.args(cargo_args_a.iter());
TestRunner {
crate_name,
command,
features,
working_dir,
cargo_command,
}
}
pub fn run(&mut self) -> Result<crate::TestOutcome, Box<dyn error::Error>> {
let mut stdout = termcolor::StandardStream::stdout(termcolor::ColorChoice::Auto);
stdout
.set_color(
termcolor::ColorSpec::new()
.set_fg(Some(termcolor::Color::Cyan))
.set_bold(true),
)
.unwrap();
print!(" Running {} ", self.cargo_command);
stdout.reset().unwrap();
println!("crate={} features=[{}]", self.crate_name, self.features);
let output = self
.command
.stdout(process::Stdio::inherit())
.stderr(process::Stdio::inherit())
.current_dir(&self.working_dir)
.output()?;
Ok(if output.status.success() {
crate::TestOutcome::Pass
} else {
crate::TestOutcome::Fail(output.status)
})
}
}