use archlens_domain::{ CodeElement, CodeElementKind, CodeGraph, FilePath, ModuleName, Relationship, RelationshipKind, }; fn make_element(name: &str, module: Option<&str>) -> CodeElement { let mut element = CodeElement::new( name, CodeElementKind::Class, FilePath::new(&format!("src/{name}.rs")).unwrap(), 1, ) .unwrap(); if let Some(m) = module { element = element.with_module(ModuleName::new(m).unwrap()); } element } #[test] fn empty_graph_has_no_elements() { let graph = CodeGraph::new(); assert!(graph.elements().is_empty()); assert!(graph.relationships().is_empty()); } #[test] fn graph_stores_added_elements() { let mut graph = CodeGraph::new(); graph.add_element(make_element("OrderService", None)); graph.add_element(make_element("Order", None)); assert_eq!(graph.elements().len(), 2); } #[test] fn graph_stores_relationships() { let mut graph = CodeGraph::new(); let service = make_element("OrderService", None); let repo = make_element("OrderRepository", None); graph.add_element(service); graph.add_element(repo); graph.add_relationship( Relationship::new( "OrderService", "OrderRepository", RelationshipKind::Composition, ) .unwrap(), ); assert_eq!(graph.relationships().len(), 1); let rel = &graph.relationships()[0]; assert_eq!(rel.source(), "OrderService"); assert_eq!(rel.target(), "OrderRepository"); assert_eq!(rel.kind(), RelationshipKind::Composition); } #[test] fn subgraph_by_module_filters_elements() { let mut graph = CodeGraph::new(); graph.add_element(make_element("OrderService", Some("Orders"))); graph.add_element(make_element("Order", Some("Orders"))); graph.add_element(make_element("BillingService", Some("Billing"))); let module = ModuleName::new("Orders").unwrap(); let subgraph = graph.subgraph_by_module(&module); assert_eq!(subgraph.elements().len(), 2); assert!( subgraph .elements() .iter() .all(|e| e.module().unwrap().as_str() == "Orders") ); } #[test] fn subgraph_includes_relationships_within_module() { let mut graph = CodeGraph::new(); graph.add_element(make_element("OrderService", Some("Orders"))); graph.add_element(make_element("Order", Some("Orders"))); graph.add_element(make_element("BillingService", Some("Billing"))); graph.add_relationship( Relationship::new("OrderService", "Order", RelationshipKind::Composition).unwrap(), ); graph.add_relationship( Relationship::new( "OrderService", "BillingService", RelationshipKind::Composition, ) .unwrap(), ); let module = ModuleName::new("Orders").unwrap(); let subgraph = graph.subgraph_by_module(&module); assert_eq!(subgraph.relationships().len(), 1); assert_eq!(subgraph.relationships()[0].target(), "Order"); } #[test] fn subgraph_of_nonexistent_module_is_empty() { let mut graph = CodeGraph::new(); graph.add_element(make_element("OrderService", Some("Orders"))); let module = ModuleName::new("Unknown").unwrap(); let subgraph = graph.subgraph_by_module(&module); assert!(subgraph.elements().is_empty()); assert!(subgraph.relationships().is_empty()); } #[test] fn graph_lists_unique_modules() { let mut graph = CodeGraph::new(); graph.add_element(make_element("OrderService", Some("Orders"))); graph.add_element(make_element("Order", Some("Orders"))); graph.add_element(make_element("BillingService", Some("Billing"))); graph.add_element(make_element("Orphan", None)); let modules = graph.modules(); assert_eq!(modules.len(), 2); assert!(modules.iter().any(|m| m.as_str() == "Orders")); assert!(modules.iter().any(|m| m.as_str() == "Billing")); }