code_analyze_mcp/
test_detection.rs1use std::path::Path;
8
9pub fn is_test_file(path: &Path) -> bool {
22 for component in path.components() {
24 if let Some("tests" | "test" | "__tests__" | "spec") = component.as_os_str().to_str() {
25 return true;
26 }
27 }
28
29 let file_name = match path.file_name().and_then(|n| n.to_str()) {
31 Some(name) => name,
32 None => return false,
33 };
34
35 if file_name.starts_with("test_") && file_name.ends_with(".rs") {
37 return true;
38 }
39 if file_name.ends_with("_test.rs") {
40 return true;
41 }
42
43 if file_name.starts_with("test_") && file_name.ends_with(".py") {
45 return true;
46 }
47 if file_name.ends_with("_test.py") {
48 return true;
49 }
50
51 if file_name.ends_with("_test.go") {
53 return true;
54 }
55
56 if file_name.starts_with("Test") && file_name.ends_with(".java") {
58 return true;
59 }
60 if file_name.ends_with("Test.java") {
61 return true;
62 }
63
64 if file_name.ends_with(".test.ts") || file_name.ends_with(".test.js") {
66 return true;
67 }
68 if file_name.ends_with(".spec.ts") || file_name.ends_with(".spec.js") {
69 return true;
70 }
71
72 false
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn filename_pattern_detects_test_file() {
81 assert!(is_test_file(Path::new("test_utils.rs")));
82 assert!(is_test_file(Path::new("utils_test.rs")));
83 }
84
85 #[test]
86 fn filename_pattern_rejects_production_file() {
87 assert!(!is_test_file(Path::new("utils.rs")));
88 assert!(!is_test_file(Path::new("main.rs")));
89 }
90
91 #[test]
92 fn directory_pattern_detects_test_file() {
93 assert!(is_test_file(Path::new("tests/utils.rs")));
94 }
95
96 #[test]
97 fn directory_pattern_detects_nested_test_file() {
98 assert!(is_test_file(Path::new("src/tests/utils.rs")));
99 assert!(!is_test_file(Path::new("src/utils.rs")));
100 }
101}