use std::fs; use archlens_cargo_workspace::CargoWorkspaceAnalyzer; use archlens_domain::{CodeElementKind, RelationshipKind, ports::ProjectAnalyzer}; fn create_workspace(dir: &std::path::Path) { fs::write( dir.join("Cargo.toml"), r#" [workspace] members = ["crates/domain", "crates/application", "crates/adapters/sqlite"] "#, ) .unwrap(); fs::create_dir_all(dir.join("crates/domain/src")).unwrap(); fs::write( dir.join("crates/domain/Cargo.toml"), r#" [package] name = "myapp-domain" version = "0.1.0" edition = "2024" [dependencies] "#, ) .unwrap(); fs::write(dir.join("crates/domain/src/lib.rs"), "").unwrap(); fs::create_dir_all(dir.join("crates/application/src")).unwrap(); fs::write( dir.join("crates/application/Cargo.toml"), r#" [package] name = "myapp-application" version = "0.1.0" edition = "2024" [dependencies] myapp-domain = { path = "../domain" } "#, ) .unwrap(); fs::write(dir.join("crates/application/src/lib.rs"), "").unwrap(); fs::create_dir_all(dir.join("crates/adapters/sqlite/src")).unwrap(); fs::write( dir.join("crates/adapters/sqlite/Cargo.toml"), r#" [package] name = "myapp-sqlite" version = "0.1.0" edition = "2024" [dependencies] myapp-domain = { path = "../../domain" } "#, ) .unwrap(); fs::write(dir.join("crates/adapters/sqlite/src/lib.rs"), "").unwrap(); } #[test] fn discovers_workspace_members_as_project_elements() { let dir = tempfile::tempdir().unwrap(); create_workspace(dir.path()); let analyzer = CargoWorkspaceAnalyzer::new(); let graph = analyzer.analyze(dir.path()).unwrap(); assert_eq!(graph.elements().len(), 3); assert!( graph .elements() .iter() .all(|e| e.kind() == CodeElementKind::Project) ); let names: Vec<&str> = graph.elements().iter().map(|e| e.name()).collect(); assert!(names.contains(&"myapp-domain")); assert!(names.contains(&"myapp-application")); assert!(names.contains(&"myapp-sqlite")); } #[test] fn extracts_dependencies_between_workspace_members() { let dir = tempfile::tempdir().unwrap(); create_workspace(dir.path()); let analyzer = CargoWorkspaceAnalyzer::new(); let graph = analyzer.analyze(dir.path()).unwrap(); assert_eq!(graph.relationships().len(), 2); assert!( graph .relationships() .iter() .all(|r| r.kind() == RelationshipKind::Composition) ); let deps: Vec<(&str, &str)> = graph .relationships() .iter() .map(|r| (r.source(), r.target())) .collect(); assert!(deps.contains(&("myapp-application", "myapp-domain"))); assert!(deps.contains(&("myapp-sqlite", "myapp-domain"))); } #[test] fn assigns_module_from_directory_grouping() { let dir = tempfile::tempdir().unwrap(); create_workspace(dir.path()); let analyzer = CargoWorkspaceAnalyzer::new(); let graph = analyzer.analyze(dir.path()).unwrap(); let sqlite = graph .elements() .iter() .find(|e| e.name() == "myapp-sqlite") .unwrap(); assert_eq!(sqlite.module().unwrap().as_str(), "Adapters"); let domain = graph .elements() .iter() .find(|e| e.name() == "myapp-domain") .unwrap(); assert!(domain.module().is_none() || domain.module().unwrap().as_str() != "Adapters"); }