168 lines
5.5 KiB
Rust
168 lines
5.5 KiB
Rust
use std::path::Path;
|
|
|
|
use archlens_domain::{
|
|
CodeElement, CodeElementKind, CodeGraph, FilePath, Language, ModuleName, Relationship,
|
|
RelationshipKind, normalize_cargo_package, normalize_python_package,
|
|
};
|
|
|
|
fn make_element(name: &str, module: Option<&str>) -> CodeElement {
|
|
let mut el = CodeElement::new(
|
|
name,
|
|
CodeElementKind::Class,
|
|
FilePath::new(&format!("src/{name}.rs")).unwrap(),
|
|
1,
|
|
)
|
|
.unwrap();
|
|
if let Some(m) = module {
|
|
el = el.with_module(ModuleName::new(m).unwrap());
|
|
}
|
|
el
|
|
}
|
|
|
|
// ── merge_project_edges ───────────────────────────────────────────────────────
|
|
|
|
#[test]
|
|
fn merge_project_edges_adds_module_level_edges_from_project_deps() {
|
|
let mut graph = CodeGraph::new();
|
|
graph.add_element(make_element("Service", Some("Application")));
|
|
graph.add_element(make_element("Order", Some("Domain")));
|
|
|
|
let mut project_graph = CodeGraph::new();
|
|
project_graph.add_element(
|
|
CodeElement::new(
|
|
"myapp-application",
|
|
CodeElementKind::Project,
|
|
FilePath::new("crates/application/Cargo.toml").unwrap(),
|
|
1,
|
|
)
|
|
.unwrap(),
|
|
);
|
|
project_graph.add_element(
|
|
CodeElement::new(
|
|
"myapp-domain",
|
|
CodeElementKind::Project,
|
|
FilePath::new("crates/domain/Cargo.toml").unwrap(),
|
|
1,
|
|
)
|
|
.unwrap(),
|
|
);
|
|
project_graph.add_relationship(
|
|
Relationship::new(
|
|
"myapp-application",
|
|
"myapp-domain",
|
|
RelationshipKind::Composition,
|
|
)
|
|
.unwrap(),
|
|
);
|
|
|
|
graph.merge_project_edges(&project_graph);
|
|
|
|
let module_edges = graph.module_edges();
|
|
assert!(
|
|
module_edges.contains_key(&("Application".to_string(), "Domain".to_string())),
|
|
"expected Application -> Domain edge, got: {module_edges:?}"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn merge_project_edges_ignores_crates_with_no_matching_module() {
|
|
let mut graph = CodeGraph::new();
|
|
graph.add_element(make_element("Order", Some("Domain")));
|
|
|
|
let mut project_graph = CodeGraph::new();
|
|
project_graph.add_element(
|
|
CodeElement::new(
|
|
"external-lib",
|
|
CodeElementKind::Project,
|
|
FilePath::new("external/Cargo.toml").unwrap(),
|
|
1,
|
|
)
|
|
.unwrap(),
|
|
);
|
|
project_graph.add_element(
|
|
CodeElement::new(
|
|
"myapp-domain",
|
|
CodeElementKind::Project,
|
|
FilePath::new("crates/domain/Cargo.toml").unwrap(),
|
|
1,
|
|
)
|
|
.unwrap(),
|
|
);
|
|
project_graph.add_relationship(
|
|
Relationship::new(
|
|
"external-lib",
|
|
"myapp-domain",
|
|
RelationshipKind::Composition,
|
|
)
|
|
.unwrap(),
|
|
);
|
|
|
|
graph.merge_project_edges(&project_graph);
|
|
|
|
// "External" (from external-lib) isn't a known module in graph → no edge
|
|
assert!(graph.module_edges().is_empty());
|
|
}
|
|
|
|
// ── Language::is_test_file ────────────────────────────────────────────────────
|
|
|
|
#[test]
|
|
fn language_detects_python_test_prefix_files() {
|
|
assert!(Language::Python.is_test_file(Path::new("src/test_orders.py")));
|
|
}
|
|
|
|
#[test]
|
|
fn language_detects_python_test_suffix_files() {
|
|
assert!(Language::Python.is_test_file(Path::new("src/orders_test.py")));
|
|
}
|
|
|
|
#[test]
|
|
fn language_detects_rust_test_files() {
|
|
assert!(Language::Rust.is_test_file(Path::new("src/orders_tests.rs")));
|
|
}
|
|
|
|
#[test]
|
|
fn language_detects_files_in_tests_dir() {
|
|
assert!(Language::Rust.is_test_file(Path::new("tests/integration.rs")));
|
|
assert!(Language::Python.is_test_file(Path::new("tests/helpers.py")));
|
|
}
|
|
|
|
#[test]
|
|
fn language_does_not_flag_regular_files_as_tests() {
|
|
assert!(!Language::Rust.is_test_file(Path::new("src/orders.rs")));
|
|
assert!(!Language::Python.is_test_file(Path::new("src/orders.py")));
|
|
}
|
|
|
|
// ── AnalysisConfig::is_standard_excluded ─────────────────────────────────────
|
|
|
|
#[test]
|
|
fn analysis_config_identifies_standard_excluded_dirs() {
|
|
use archlens_domain::AnalysisConfig;
|
|
assert!(AnalysisConfig::is_standard_excluded(".venv"));
|
|
assert!(AnalysisConfig::is_standard_excluded("node_modules"));
|
|
assert!(AnalysisConfig::is_standard_excluded("target"));
|
|
assert!(AnalysisConfig::is_standard_excluded("__pycache__"));
|
|
}
|
|
|
|
#[test]
|
|
fn analysis_config_does_not_exclude_source_dirs() {
|
|
use archlens_domain::AnalysisConfig;
|
|
assert!(!AnalysisConfig::is_standard_excluded("src"));
|
|
assert!(!AnalysisConfig::is_standard_excluded("domain"));
|
|
assert!(!AnalysisConfig::is_standard_excluded("application"));
|
|
}
|
|
|
|
// ── Name normalization ────────────────────────────────────────────────────────
|
|
|
|
#[test]
|
|
fn normalize_cargo_package_converts_underscores_to_hyphens() {
|
|
assert_eq!(normalize_cargo_package("myapp_domain"), "myapp-domain");
|
|
assert_eq!(normalize_cargo_package("myapp-domain"), "myapp-domain");
|
|
}
|
|
|
|
#[test]
|
|
fn normalize_python_package_lowercases_and_unifies_separators() {
|
|
assert_eq!(normalize_python_package("My-Package"), "my_package");
|
|
assert_eq!(normalize_python_package("my.package"), "my_package");
|
|
assert_eq!(normalize_python_package("my_package"), "my_package");
|
|
}
|