cargo_all_features/
test_runner.rs1use crate::types::FeatureList;
2use std::{error, path, process};
3use termcolor::WriteColor;
4
5pub struct TestRunner {
6 command: process::Command,
7 crate_name: String,
8 features: String,
10 working_dir: path::PathBuf,
11 cargo_command: String,
12}
13
14fn split_slice<'a>(slice: &'a [String], item: &'a str) -> (&'a [String], &'a [String]) {
15 if let Some(pos) = slice.iter().position(|s| s == item) {
16 (&slice[..pos], &slice[pos..])
17 } else {
18 (slice, &[])
19 }
20}
21
22impl TestRunner {
23 pub fn new(
24 cargo_command: String,
25 crate_name: String,
26 feature_set: FeatureList,
27 cargo_args: &[String],
28 working_dir: path::PathBuf,
29 ) -> Self {
30 let mut command = process::Command::new(crate::cargo_cmd());
31
32 command.arg(cargo_command.clone());
33
34 let (cargo_args_b, cargo_args_a) = split_slice(cargo_args, "--");
35
36 command.args(cargo_args_b.iter());
40
41 command.arg("--no-default-features");
43
44 let mut features = feature_set
46 .iter()
47 .fold(String::new(), |s, feature| s + feature + ",");
48
49 if !features.is_empty() {
50 features.remove(features.len() - 1);
51
52 command.arg("--features");
53 command.arg(&features);
54 }
55
56 command.args(cargo_args_a.iter());
58
59 TestRunner {
61 crate_name,
62 command,
63 features,
64 working_dir,
65 cargo_command,
66 }
67 }
68
69 pub fn run(&mut self) -> Result<crate::TestOutcome, Box<dyn error::Error>> {
70 let mut stdout = termcolor::StandardStream::stdout(termcolor::ColorChoice::Auto);
71 stdout
72 .set_color(
73 termcolor::ColorSpec::new()
74 .set_fg(Some(termcolor::Color::Cyan))
75 .set_bold(true),
76 )
77 .unwrap();
78 print!(" Running {} ", self.cargo_command);
79 stdout.reset().unwrap();
80 println!("crate={} features=[{}]", self.crate_name, self.features);
81
82 let output = self
83 .command
84 .stdout(process::Stdio::inherit())
85 .stderr(process::Stdio::inherit())
86 .current_dir(&self.working_dir)
87 .output()?;
88
89 Ok(if output.status.success() {
90 crate::TestOutcome::Pass
91 } else {
92 crate::TestOutcome::Fail(output.status)
93 })
94 }
95}