md_cli_test/
lib.rs

1use std::ffi::OsString;
2use std::path::PathBuf;
3
4use temp_testdir::TempDir;
5
6pub mod case;
7pub mod cmd;
8pub mod error;
9
10#[derive(Debug, Clone)]
11pub struct Tester {
12    pub md_file_path: PathBuf,
13    pub cargo_bin_alias: Option<String>,
14    pub cargo_bin_name: Option<String>,
15    pub envs: Vec<(OsString, OsString)>,
16}
17
18impl Tester {
19    pub fn new(md_file_path: impl Into<PathBuf>) -> Self {
20        Self {
21            md_file_path: md_file_path.into(),
22            cargo_bin_alias: None,
23            cargo_bin_name: None,
24            envs: Vec::new(),
25        }
26    }
27
28    pub fn with_cargo_bin_alias(mut self, alias: impl Into<String>) -> Self {
29        self.cargo_bin_alias = Some(alias.into());
30        self
31    }
32
33    pub fn with_cargo_bin_name(mut self, cargo_bin_name: impl Into<String>) -> Self {
34        self.cargo_bin_name = Some(cargo_bin_name.into());
35        self
36    }
37
38    pub fn with_env(mut self, key: impl Into<OsString>, val: impl Into<OsString>) -> Self {
39        self.envs.push((key.into(), val.into()));
40        self
41    }
42
43    pub fn with_envs(mut self, vars: impl IntoIterator<Item = (impl Into<OsString>, impl Into<OsString>)>) -> Self {
44        for (key, val) in vars {
45            self.envs.push((key.into(), val.into()));
46        }
47        self
48    }
49
50    pub fn run(self) -> error::Result<()> {
51        let sections = case::parse_markdown_tests(
52            self.md_file_path,
53            self.cargo_bin_alias,
54            self.cargo_bin_name,
55            Some(self.envs),
56        )?;
57
58        for section in sections {
59            let test_dir = TempDir::default();
60            let mut completed_tests = Vec::new();
61
62            log::debug!("\n# {}", section.title);
63
64            for test_case in section.cases {
65                let test_case = test_case.with_test_dir(test_dir.as_os_str());
66
67                log::debug!("Testing: {:?}", test_case.commands);
68                test_case.run()?;
69                completed_tests.push(test_case);
70            }
71
72            // Destroy completed test cases
73            drop(completed_tests);
74        }
75        Ok(())
76    }
77}