use crate::adapters::analyzers::structural::collect_metadata;
use crate::adapters::analyzers::structural::oi::*;
use crate::adapters::analyzers::structural::{StructuralWarning, StructuralWarningKind};
use crate::config::StructuralConfig;
fn detect_multi(sources: &[(&str, &str)]) -> Vec<StructuralWarning> {
let parsed = super::parse_multi(sources);
let meta = collect_metadata(&parsed);
let config = StructuralConfig::default();
let mut warnings = Vec::new();
detect_oi(&mut warnings, &meta, &config);
warnings
}
#[test]
fn test_same_file_not_flagged() {
let w = detect_multi(&[("lib.rs", "struct Foo {} impl Foo { fn bar() {} }")]);
assert!(w.is_empty());
}
#[test]
fn test_different_module_flagged() {
let w = detect_multi(&[
("types.rs", "pub struct Foo {}"),
("other.rs", "impl Foo { fn bar() {} }"),
]);
assert_eq!(w.len(), 1);
assert!(matches!(
w[0].kind,
StructuralWarningKind::OrphanedImpl { .. }
));
}
#[test]
fn test_same_module_tree_not_flagged() {
let w = detect_multi(&[
("analyzer/mod.rs", "pub struct Analyzer {}"),
("analyzer/helpers.rs", "impl Analyzer { fn helper() {} }"),
]);
assert!(w.is_empty(), "same top-level module should not be flagged");
}
#[test]
fn test_trait_impl_not_flagged() {
let w = detect_multi(&[
(
"types.rs",
"pub struct Foo {} pub trait Bar { fn baz(&self); }",
),
("other.rs", "impl Bar for Foo { fn baz(&self) {} }"),
]);
assert!(w.is_empty());
}
#[test]
fn test_external_type_not_flagged() {
let w = detect_multi(&[("other.rs", "impl ExternalType { fn bar() {} }")]);
assert!(w.is_empty(), "external type should not be flagged");
}
#[test]
fn test_same_module_backslash_paths_not_flagged() {
let w = detect_multi(&[
("db\\connection.rs", "pub struct Database {}"),
(
"db\\queries\\chunks.rs",
"impl Database { fn get_chunks() {} }",
),
]);
assert!(
w.is_empty(),
"Same top-level module with backslash paths should not be flagged, got {:?}",
w.iter().map(|w| &w.file).collect::<Vec<_>>()
);
}
#[test]
fn test_disabled_check() {
let parsed: Vec<(String, String, syn::File)> = vec![
(
"a.rs".to_string(),
"pub struct Foo {}".to_string(),
syn::parse_file("pub struct Foo {}").expect("test"),
),
(
"b.rs".to_string(),
"impl Foo { fn bar() {} }".to_string(),
syn::parse_file("impl Foo { fn bar() {} }").expect("test"),
),
];
let meta = collect_metadata(&parsed);
let config = StructuralConfig {
check_oi: false,
..StructuralConfig::default()
};
let mut warnings = Vec::new();
detect_oi(&mut warnings, &meta, &config);
assert!(warnings.is_empty());
}