1336d762aSopenharmony_ciuse std::collections::BTreeSet;
2336d762aSopenharmony_ciuse std::process::{Command, Stdio};
3336d762aSopenharmony_ci
4336d762aSopenharmony_cipub type Feature = &'static str;
5336d762aSopenharmony_ci
6336d762aSopenharmony_cipub struct TestArgs {
7336d762aSopenharmony_ci    pub features: BTreeSet<Feature>,
8336d762aSopenharmony_ci    pub default_features: bool,
9336d762aSopenharmony_ci    pub lib_only: bool,
10336d762aSopenharmony_ci}
11336d762aSopenharmony_ci
12336d762aSopenharmony_ciimpl Default for TestArgs {
13336d762aSopenharmony_ci    fn default() -> Self {
14336d762aSopenharmony_ci        TestArgs {
15336d762aSopenharmony_ci            features: BTreeSet::new(),
16336d762aSopenharmony_ci            default_features: true,
17336d762aSopenharmony_ci            lib_only: false,
18336d762aSopenharmony_ci        }
19336d762aSopenharmony_ci    }
20336d762aSopenharmony_ci}
21336d762aSopenharmony_ci
22336d762aSopenharmony_ciimpl TestArgs {
23336d762aSopenharmony_ci    fn features_string(&self) -> Option<String> {
24336d762aSopenharmony_ci        if self.features.is_empty() {
25336d762aSopenharmony_ci            return None;
26336d762aSopenharmony_ci        }
27336d762aSopenharmony_ci
28336d762aSopenharmony_ci        let s = self.features.iter().fold(String::new(), |mut s, f| {
29336d762aSopenharmony_ci            if !s.is_empty() {
30336d762aSopenharmony_ci                s.push(' ');
31336d762aSopenharmony_ci            }
32336d762aSopenharmony_ci            s.push_str(f);
33336d762aSopenharmony_ci
34336d762aSopenharmony_ci            s
35336d762aSopenharmony_ci        });
36336d762aSopenharmony_ci
37336d762aSopenharmony_ci        Some(s)
38336d762aSopenharmony_ci    }
39336d762aSopenharmony_ci}
40336d762aSopenharmony_ci
41336d762aSopenharmony_cipub fn test(args: TestArgs) -> bool {
42336d762aSopenharmony_ci    let features = args.features_string();
43336d762aSopenharmony_ci
44336d762aSopenharmony_ci    let mut command = Command::new("cargo");
45336d762aSopenharmony_ci
46336d762aSopenharmony_ci    command
47336d762aSopenharmony_ci        .stdout(Stdio::inherit())
48336d762aSopenharmony_ci        .stderr(Stdio::inherit())
49336d762aSopenharmony_ci        .arg("test")
50336d762aSopenharmony_ci        .arg("--verbose");
51336d762aSopenharmony_ci
52336d762aSopenharmony_ci    if !args.default_features {
53336d762aSopenharmony_ci        command.arg("--no-default-features");
54336d762aSopenharmony_ci    }
55336d762aSopenharmony_ci
56336d762aSopenharmony_ci    if args.lib_only {
57336d762aSopenharmony_ci        command.arg("--lib");
58336d762aSopenharmony_ci    }
59336d762aSopenharmony_ci
60336d762aSopenharmony_ci    if let Some(features) = &features {
61336d762aSopenharmony_ci        command.args(&["--features", features]);
62336d762aSopenharmony_ci    }
63336d762aSopenharmony_ci
64336d762aSopenharmony_ci    println!("running {:?}", command);
65336d762aSopenharmony_ci
66336d762aSopenharmony_ci    let status = command.status().expect("Failed to execute command");
67336d762aSopenharmony_ci
68336d762aSopenharmony_ci    if !status.success() {
69336d762aSopenharmony_ci        eprintln!(
70336d762aSopenharmony_ci            "test execution failed for features: {}",
71336d762aSopenharmony_ci            features.as_ref().map(AsRef::as_ref).unwrap_or("")
72336d762aSopenharmony_ci        );
73336d762aSopenharmony_ci        false
74336d762aSopenharmony_ci    } else {
75336d762aSopenharmony_ci        true
76336d762aSopenharmony_ci    }
77336d762aSopenharmony_ci}
78