#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_file_discovery_basic() {
let temp_dir = TempDir::new().unwrap();
let root = temp_dir.path();
fs::create_dir_all(root.join("src")).unwrap();
fs::write(root.join("src/main.rs"), "fn main() {}").unwrap();
fs::write(root.join("src/lib.rs"), "pub fn hello() {}").unwrap();
fs::create_dir_all(root.join("tests")).unwrap();
fs::write(root.join("tests/test.rs"), "#[test] fn test() {}").unwrap();
fs::create_dir_all(root.join("target/debug")).unwrap();
fs::write(root.join("target/debug/main"), "binary").unwrap();
fs::create_dir_all(root.join("node_modules/pkg")).unwrap();
fs::write(
root.join("node_modules/pkg/index.js"),
"module.exports = {}",
)
.unwrap();
let discovery = ProjectFileDiscovery::new(root.to_path_buf());
let files = discovery.discover_files().unwrap();
assert_eq!(files.len(), 3);
assert!(files.iter().any(|p| p.ends_with("src/main.rs")));
assert!(files.iter().any(|p| p.ends_with("src/lib.rs")));
assert!(files.iter().any(|p| p.ends_with("tests/test.rs")));
}
#[test]
fn test_external_repo_filtering() {
let temp_dir = TempDir::new().unwrap();
let root = temp_dir.path();
fs::create_dir_all(root.join("https___github_com_example_repo")).unwrap();
fs::write(
root.join("https___github_com_example_repo/main.rs"),
"fn main() {}",
)
.unwrap();
fs::write(root.join("main.rs"), "fn main() {}").unwrap();
let discovery = ProjectFileDiscovery::new(root.to_path_buf());
let files = discovery.discover_files().unwrap();
assert_eq!(files.len(), 1);
assert!(files[0].ends_with("main.rs"));
assert!(!files[0].to_string_lossy().contains("https___"));
}
#[test]
fn test_max_depth_limit() {
let temp_dir = TempDir::new().unwrap();
let root = temp_dir.path();
let mut current = root.to_path_buf();
for i in 0..20 {
current = current.join(format!("level{i}"));
fs::create_dir_all(¤t).unwrap();
fs::write(current.join("file.rs"), "// content").unwrap();
}
let config = FileDiscoveryConfig {
max_depth: Some(5),
..Default::default()
};
let discovery = ProjectFileDiscovery::new(root.to_path_buf()).with_config(config);
let files = discovery.discover_files().unwrap();
assert!(files.len() <= 5);
}
#[test]
#[ignore] fn test_custom_ignore_patterns() {
let temp_dir = TempDir::new().unwrap();
let root = temp_dir.path();
fs::write(root.join("include.rs"), "// include").unwrap();
fs::write(root.join("exclude.rs"), "// exclude").unwrap();
fs::write(root.join("test.rs"), "// test").unwrap();
let config = FileDiscoveryConfig {
custom_ignore_patterns: vec!["*exclude*".to_string()],
..Default::default()
};
let discovery = ProjectFileDiscovery::new(root.to_path_buf()).with_config(config);
let files = discovery.discover_files().unwrap();
assert_eq!(files.len(), 2);
assert!(!files
.iter()
.any(|p| p.to_string_lossy().contains("exclude")));
}
#[test]
fn test_file_extension_filtering() {
let temp_dir = TempDir::new().unwrap();
let root = temp_dir.path();
fs::write(root.join("main.rs"), "fn main() {}").unwrap();
fs::write(root.join("script.py"), "print('hello')").unwrap();
fs::write(root.join("app.js"), "console.log('hi')").unwrap();
fs::write(root.join("doc.md"), "# Documentation").unwrap();
fs::write(root.join("config.toml"), "[package]").unwrap();
fs::write(root.join("data.json"), "{}").unwrap();
let discovery = ProjectFileDiscovery::new(root.to_path_buf());
let files = discovery.discover_files().unwrap();
assert_eq!(files.len(), 5);
assert!(files.iter().any(|p| p.to_string_lossy().ends_with(".rs")));
assert!(files.iter().any(|p| p.to_string_lossy().ends_with(".py")));
assert!(files.iter().any(|p| p.to_string_lossy().ends_with(".js")));
assert!(!files.iter().any(|p| p.to_string_lossy().ends_with(".md")));
assert!(files.iter().any(|p| p.to_string_lossy().ends_with(".toml")));
assert!(files.iter().any(|p| p.to_string_lossy().ends_with(".json")));
}
#[test]
fn test_cython_file_discovery() {
let temp_dir = TempDir::new().unwrap();
let root = temp_dir.path();
fs::write(
root.join("module.pyx"),
"def add(int a, int b): return a + b",
)
.unwrap();
fs::write(root.join("module.pxd"), "cdef int add(int a, int b)").unwrap();
fs::write(root.join("setup.py"), "from distutils.core import setup").unwrap();
let discovery = ProjectFileDiscovery::new(root.to_path_buf());
let files = discovery.discover_files().unwrap();
assert_eq!(files.len(), 3);
assert!(files.iter().any(|p| p.to_string_lossy().ends_with(".pyx")));
assert!(files.iter().any(|p| p.to_string_lossy().ends_with(".pxd")));
assert!(files.iter().any(|p| p.to_string_lossy().ends_with(".py")));
}
#[test]
fn test_file_categorization() {
use std::path::Path;
assert_eq!(
ProjectFileDiscovery::categorize_file(Path::new("deep_context.md")),
FileCategory::GeneratedOutput
);
assert_eq!(
ProjectFileDiscovery::categorize_file(Path::new("test-deep-context-2.md")),
FileCategory::GeneratedOutput
);
assert_eq!(
ProjectFileDiscovery::categorize_file(Path::new("kaizen-metrics.json")),
FileCategory::GeneratedOutput
);
assert_eq!(
ProjectFileDiscovery::categorize_file(Path::new("README.md")),
FileCategory::EssentialDoc
);
assert_eq!(
ProjectFileDiscovery::categorize_file(Path::new("readme.md")),
FileCategory::EssentialDoc
);
assert_eq!(
ProjectFileDiscovery::categorize_file(Path::new("Makefile")),
FileCategory::BuildConfig
);
assert_eq!(
ProjectFileDiscovery::categorize_file(Path::new("Cargo.toml")),
FileCategory::BuildConfig
);
assert_eq!(
ProjectFileDiscovery::categorize_file(Path::new("pyproject.toml")),
FileCategory::BuildConfig
);
assert_eq!(
ProjectFileDiscovery::categorize_file(Path::new("test_something.md")),
FileCategory::TestArtifact
);
assert_eq!(
ProjectFileDiscovery::categorize_file(Path::new("docs/api.md")),
FileCategory::DevelopmentDoc
);
assert_eq!(
ProjectFileDiscovery::categorize_file(Path::new("src/main.rs")),
FileCategory::SourceCode
);
assert_eq!(
ProjectFileDiscovery::categorize_file(Path::new("app.ts")),
FileCategory::SourceCode
);
assert_eq!(
ProjectFileDiscovery::categorize_file(Path::new("script.py")),
FileCategory::SourceCode
);
}
#[test]
fn test_discovery_stats() {
let temp_dir = TempDir::new().unwrap();
let root = temp_dir.path();
fs::create_dir_all(root.join("src")).unwrap();
fs::write(root.join("src/main.rs"), "fn main() {}").unwrap();
fs::write(root.join("src/lib.rs"), "pub fn lib() {}").unwrap();
fs::create_dir_all(root.join("tests")).unwrap();
fs::write(root.join("tests/test.rs"), "#[test] fn test() {}").unwrap();
fs::write(root.join("app.js"), "console.log('app')").unwrap();
let discovery = ProjectFileDiscovery::new(root.to_path_buf());
let stats = discovery.get_discovery_stats().unwrap();
assert_eq!(stats.total_files, 4);
assert_eq!(stats.files_by_extension.get("rs"), Some(&3));
assert_eq!(stats.files_by_extension.get("js"), Some(&1));
assert_eq!(stats.files_by_category.get("src"), Some(&2));
assert_eq!(stats.files_by_category.get("tests"), Some(&1));
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod property_tests {
use proptest::prelude::*;
proptest! {
#[test]
fn basic_property_stability(_input in ".*") {
prop_assert!(true);
}
#[test]
fn module_consistency_check(_x in 0u32..1000) {
prop_assert!(_x < 1001);
}
}
}