use std::path::Path;
use sdivi_config::{Config, PatternsConfig};
use sdivi_lang_rust::RustAdapter;
use sdivi_parsing::parse::parse_repository;
use sdivi_patterns::{build_catalog, compute_entropy};
fn fixture_path(name: &str) -> std::path::PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../../tests/fixtures")
.join(name)
}
fn total_entropy(fixture: &str, config: &Config, patterns_config: &PatternsConfig) -> f64 {
let root = fixture_path(fixture);
let adapters: Vec<Box<dyn sdivi_parsing::adapter::LanguageAdapter>> =
vec![Box::new(RustAdapter)];
let records = parse_repository(config, &root, &adapters);
let catalog = build_catalog(&records, patterns_config);
catalog.entries.values().map(compute_entropy).sum::<f64>()
}
#[test]
fn high_entropy_greater_than_simple_rust() {
let config = Config::default();
let mut patterns_config = config.patterns.clone();
patterns_config.min_pattern_nodes = 1;
let simple_entropy = total_entropy("simple-rust", &config, &patterns_config);
let high_entropy = total_entropy("high-entropy", &config, &patterns_config);
assert!(
high_entropy > simple_entropy,
"high-entropy fixture ({high_entropy:.4}) must exceed simple-rust ({simple_entropy:.4})"
);
}
#[test]
fn simple_rust_error_handling_entropy_is_zero() {
let config = Config::default();
let mut patterns_config = config.patterns.clone();
patterns_config.min_pattern_nodes = 1;
let root = fixture_path("simple-rust");
let adapters: Vec<Box<dyn sdivi_parsing::adapter::LanguageAdapter>> =
vec![Box::new(RustAdapter)];
let records = parse_repository(&config, &root, &adapters);
let catalog = build_catalog(&records, &patterns_config);
let h = catalog
.entries
.get("error_handling")
.map(compute_entropy)
.unwrap_or(0.0);
assert!(
h < 1e-10,
"simple-rust error_handling entropy must be 0 (only one distinct shape), got {h}"
);
}
#[test]
fn high_entropy_error_handling_entropy_is_positive() {
let config = Config::default();
let mut patterns_config = config.patterns.clone();
patterns_config.min_pattern_nodes = 1;
let root = fixture_path("high-entropy");
let adapters: Vec<Box<dyn sdivi_parsing::adapter::LanguageAdapter>> =
vec![Box::new(RustAdapter)];
let records = parse_repository(&config, &root, &adapters);
let catalog = build_catalog(&records, &patterns_config);
let h = catalog
.entries
.get("error_handling")
.map(compute_entropy)
.unwrap_or(0.0);
assert!(
h > 0.0,
"high-entropy fixture must have positive error_handling entropy (try + match), got {h}"
);
}