Skip to main content

sparrow/
project_test.rs

1use serde::Serialize;
2use std::path::Path;
3
4#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
5pub struct TestRunner {
6    pub name: String,
7    pub command: String,
8    pub args: Vec<String>,
9}
10
11impl TestRunner {
12    pub fn display_command(&self) -> String {
13        std::iter::once(self.command.as_str())
14            .chain(self.args.iter().map(String::as_str))
15            .collect::<Vec<_>>()
16            .join(" ")
17    }
18}
19
20pub fn detect_test_runner(root: &Path) -> Option<TestRunner> {
21    if root.join("Cargo.toml").exists() {
22        return Some(TestRunner {
23            name: "cargo".into(),
24            command: "cargo".into(),
25            args: vec!["test".into(), "--all-targets".into()],
26        });
27    }
28    if root.join("package.json").exists() {
29        return Some(TestRunner {
30            name: "npm".into(),
31            command: "npm".into(),
32            args: vec!["test".into()],
33        });
34    }
35    if root.join("pyproject.toml").exists()
36        || root.join("pytest.ini").exists()
37        || root.join("setup.cfg").exists()
38    {
39        return Some(TestRunner {
40            name: "pytest".into(),
41            command: "python".into(),
42            args: vec!["-m".into(), "pytest".into()],
43        });
44    }
45    None
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn detects_cargo_runner_first() {
54        let temp = tempfile::tempdir().unwrap();
55        std::fs::write(temp.path().join("Cargo.toml"), "[package]\nname='x'\n").unwrap();
56        let runner = detect_test_runner(temp.path()).unwrap();
57        assert_eq!(runner.name, "cargo");
58        assert_eq!(runner.display_command(), "cargo test --all-targets");
59    }
60
61    #[test]
62    fn detects_node_and_python_runners() {
63        let node = tempfile::tempdir().unwrap();
64        std::fs::write(node.path().join("package.json"), "{}").unwrap();
65        assert_eq!(detect_test_runner(node.path()).unwrap().name, "npm");
66
67        let py = tempfile::tempdir().unwrap();
68        std::fs::write(py.path().join("pyproject.toml"), "[project]\nname='x'\n").unwrap();
69        assert_eq!(detect_test_runner(py.path()).unwrap().name, "pytest");
70    }
71}