#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_detection_registry_creation() {
let registry = DetectionRegistry::new();
let detectors = registry.list_detectors();
assert!(detectors.contains(&"duplicates"));
assert!(detectors.contains(&"satd"));
assert!(detectors.contains(&"polyglot"));
assert_eq!(detectors.len(), 3);
}
#[tokio::test]
async fn test_unified_processor() {
let processor = UnifiedDetectionProcessor::new();
let available = processor.available_detectors();
assert!(available.contains(&"duplicates"));
assert!(available.contains(&"satd"));
assert!(available.contains(&"polyglot"));
assert_eq!(available.len(), 3);
}
#[test]
fn test_detection_config_default() {
let config = DetectionConfig::default();
assert!(config.parallel_processing);
assert!(config.max_files.is_none());
assert_eq!(config.output_format, OutputFormat::Json);
assert!(matches!(
config.detector_specific,
DetectorSpecificConfig::Duplicates(_)
));
}
#[test]
fn test_detector_capabilities() {
let caps = DetectorCapabilities {
supports_batch: true,
supports_streaming: false,
language_agnostic: true,
requires_ast: false,
};
assert!(caps.supports_batch);
assert!(!caps.supports_streaming);
assert!(caps.language_agnostic);
assert!(!caps.requires_ast);
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod additional_tests {
use super::*;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_detector_capabilities() {
let caps = DetectorCapabilities {
supports_batch: true,
supports_streaming: false,
language_agnostic: true,
requires_ast: false,
};
assert!(caps.supports_batch);
assert!(!caps.supports_streaming);
assert!(caps.language_agnostic);
assert!(!caps.requires_ast);
}
#[test]
fn test_detection_config_custom() {
let config = DetectionConfig {
max_files: Some(100),
parallel_processing: false,
output_format: OutputFormat::Yaml,
detector_specific: DetectorSpecificConfig::SATD(satd::SATDConfig::default()),
};
assert_eq!(config.max_files, Some(100));
assert!(!config.parallel_processing);
assert_eq!(config.output_format, OutputFormat::Yaml);
assert!(matches!(
config.detector_specific,
DetectorSpecificConfig::SATD(_)
));
}
#[test]
fn test_output_format_enum() {
let json_format = OutputFormat::Json;
let yaml_format = OutputFormat::Yaml;
let summary_format = OutputFormat::Summary;
assert_eq!(json_format, OutputFormat::Json);
assert_eq!(yaml_format, OutputFormat::Yaml);
assert_eq!(summary_format, OutputFormat::Summary);
assert_ne!(json_format, yaml_format);
}
#[test]
fn test_detection_input_variants() {
let single = DetectionInput::SingleFile(std::path::PathBuf::from("/test.rs"));
let multiple = DetectionInput::MultipleFiles(vec![
std::path::PathBuf::from("/file1.rs"),
std::path::PathBuf::from("/file2.rs"),
]);
let project = DetectionInput::ProjectDirectory(std::path::PathBuf::from("/project"));
let content = DetectionInput::Content("test content".to_string());
assert!(matches!(single, DetectionInput::SingleFile(_)));
assert!(matches!(multiple, DetectionInput::MultipleFiles(_)));
assert!(matches!(project, DetectionInput::ProjectDirectory(_)));
assert!(matches!(content, DetectionInput::Content(_)));
}
#[tokio::test]
async fn test_unified_detection_processor_creation() {
let processor = UnifiedDetectionProcessor::new();
let detectors = processor.available_detectors();
assert_eq!(detectors.len(), 3);
assert!(detectors.contains(&"duplicates"));
assert!(detectors.contains(&"satd"));
assert!(detectors.contains(&"polyglot"));
}
#[tokio::test]
async fn test_detect_duplicates_empty_list() {
let processor = UnifiedDetectionProcessor::new();
let result = processor.detect_duplicates(vec![]).await;
match result {
Ok(_duplicates) => {
}
Err(_) => {
}
}
}
#[tokio::test]
async fn test_detect_satd_with_temp_project() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("test.rs");
fs::write(
&test_file,
r#"
// TODO: Fix this later
fn bad_function() {
// FIXME: This is broken
panic!("Not implemented");
}
"#,
)
.unwrap();
let processor = UnifiedDetectionProcessor::new();
let result = processor.detect_satd(temp_dir.path()).await;
match result {
Ok(_satd_result) => {
}
Err(_) => {
}
}
}
#[tokio::test]
async fn test_analyze_polyglot_project() {
let temp_dir = TempDir::new().unwrap();
fs::write(temp_dir.path().join("main.rs"), "fn main() {}").unwrap();
fs::write(temp_dir.path().join("script.py"), "def main(): pass").unwrap();
fs::write(temp_dir.path().join("app.js"), "function main() {}").unwrap();
let processor = UnifiedDetectionProcessor::new();
let result = processor.analyze_polyglot(temp_dir.path()).await;
match result {
Ok(polyglot_analysis) => {
assert!(!polyglot_analysis.languages.is_empty());
}
Err(_) => {
}
}
}
#[test]
fn test_registry_list_detectors() {
let registry = DetectionRegistry::new();
let detectors = registry.list_detectors();
assert_eq!(detectors.len(), 3);
let detector_set: std::collections::HashSet<_> = detectors.into_iter().collect();
assert!(detector_set.contains("duplicates"));
assert!(detector_set.contains("satd"));
assert!(detector_set.contains("polyglot"));
}
#[tokio::test]
async fn test_registry_detect_with_unknown_detector() {
let registry = DetectionRegistry::new();
let input = DetectionInput::Content("test".to_string());
let config = DetectionConfig::default();
let result = registry.detect("unknown_detector", input, config).await;
assert!(result.is_err());
if let Err(e) = result {
assert!(e.to_string().contains("Unknown detector"));
}
}
}
#[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);
}
}
}