P1 correctness: - filter test files by default (--include-tests to opt in) - per-module diagrams show cross-module dependency arrows - qualified type names (Module::TypeName) fix false edges from duplicate names P2 output richness: - method parameter types and return types in class diagrams (Rust + Python) - Python pyproject.toml project analyzer (--level project for monorepos) P3 unique value: - boundary rules in archlens.toml ([rules] allow/deny, --strict enforcement) P4 nice to have: - dependency weight labels on module arrows (--no-weights to disable) - --watch mode with 500ms debounce - D2 renderer adapter (--format d2) - interactive self-contained HTML viewer (--format html) - git-aware incremental analysis (--since <ref>)
93 lines
2.4 KiB
Rust
93 lines
2.4 KiB
Rust
use std::fs;
|
|
|
|
use archlens_domain::{DiagramLevel, ports::ConfigLoader};
|
|
use archlens_toml_config::TomlConfigLoader;
|
|
|
|
#[test]
|
|
fn loads_analysis_config_from_toml_file() {
|
|
let dir = tempfile::tempdir().unwrap();
|
|
let config_path = dir.path().join("archlens.toml");
|
|
fs::write(
|
|
&config_path,
|
|
r#"
|
|
[analysis]
|
|
exclude = ["tests/", "vendor/"]
|
|
level = "type"
|
|
|
|
[modules]
|
|
"src/orders" = "Orders"
|
|
"src/billing" = "Billing"
|
|
"#,
|
|
)
|
|
.unwrap();
|
|
|
|
let loader = TomlConfigLoader::from_path(&config_path).unwrap();
|
|
let config = loader.load_analysis_config().unwrap();
|
|
|
|
assert_eq!(config.excludes(), &["tests/", "vendor/"]);
|
|
assert_eq!(config.level(), DiagramLevel::Type);
|
|
assert_eq!(
|
|
config.module_mappings().get("src/orders").unwrap(),
|
|
"Orders"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn loads_output_config_from_toml_file() {
|
|
let dir = tempfile::tempdir().unwrap();
|
|
let config_path = dir.path().join("archlens.toml");
|
|
fs::write(
|
|
&config_path,
|
|
r#"
|
|
[output]
|
|
format = "mermaid"
|
|
path = "docs/arch.mmd"
|
|
split_by_module = true
|
|
"#,
|
|
)
|
|
.unwrap();
|
|
|
|
let loader = TomlConfigLoader::from_path(&config_path).unwrap();
|
|
let config = loader.load_output_config().unwrap();
|
|
|
|
assert!(config.split_by_module());
|
|
assert_eq!(config.output_path(), Some("docs/arch.mmd"));
|
|
}
|
|
|
|
#[test]
|
|
fn missing_file_returns_defaults() {
|
|
let loader = TomlConfigLoader::default();
|
|
|
|
let analysis = loader.load_analysis_config().unwrap();
|
|
assert!(analysis.excludes().is_empty());
|
|
assert_eq!(analysis.level(), DiagramLevel::Module);
|
|
|
|
let output = loader.load_output_config().unwrap();
|
|
assert!(!output.split_by_module());
|
|
assert!(output.output_path().is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn loads_boundary_rules_from_toml_file() {
|
|
let dir = tempfile::tempdir().unwrap();
|
|
let config_path = dir.path().join("archlens.toml");
|
|
fs::write(
|
|
&config_path,
|
|
r#"
|
|
[rules]
|
|
allow = ["Application --> Domain", "Adapters --> Domain"]
|
|
deny = ["Domain --> Adapters"]
|
|
"#,
|
|
)
|
|
.unwrap();
|
|
|
|
let loader = TomlConfigLoader::from_path(&config_path).unwrap();
|
|
let (allow, deny) = loader.load_rules();
|
|
|
|
assert_eq!(allow.len(), 2);
|
|
assert_eq!(deny.len(), 1);
|
|
assert!(allow.iter().any(|r| r == "Application --> Domain"));
|
|
assert!(allow.iter().any(|r| r == "Adapters --> Domain"));
|
|
assert!(deny.iter().any(|r| r == "Domain --> Adapters"));
|
|
}
|