// Integration tests for the trait-based render graph use nigig_map::render_graph::{ PassType, RenderGraph, RenderPass, BackgroundPass, FillPass, StrokePass, PoiPass, LabelPass, }; #[test] fn test_render_graph_default_passes() { let graph = RenderGraph::new(); let passes = graph.passes(); assert_eq!(passes.len(), 5, "Should have 5 default passes"); // Verify passes are in z_order let z_orders: Vec = passes.iter().map(|p| p.z_order()).collect(); for i in 1..z_orders.len() { assert!(z_orders[i] > z_orders[i-1], "Passes should be sorted by z_order"); } } #[test] fn test_pass_types() { let bg = BackgroundPass::default(); assert_eq!(bg.pass_type(), PassType::Background); assert_eq!(bg.z_order(), 0); assert!(bg.is_enabled()); let fill = FillPass::default(); assert_eq!(fill.pass_type(), PassType::Fill); assert_eq!(fill.z_order(), 100); let stroke = StrokePass::default(); assert_eq!(stroke.pass_type(), PassType::Stroke); assert_eq!(stroke.z_order(), 200); let poi = PoiPass::default(); assert_eq!(poi.pass_type(), PassType::Poi); assert_eq!(poi.z_order(), 300); assert_eq!(poi.min_zoom(), 13.0); let label = LabelPass::default(); assert_eq!(label.pass_type(), PassType::Label); assert_eq!(label.z_order(), 400); assert_eq!(label.min_zoom(), 13.0); } #[test] fn test_zoom_gating() { let poi = PoiPass::default(); // POI should not execute below min_zoom assert!(!poi.should_execute(12.0)); assert!(!poi.should_execute(12.9)); // POI should execute at and above min_zoom assert!(poi.should_execute(13.0)); assert!(poi.should_execute(14.0)); assert!(poi.should_execute(20.0)); } #[test] fn test_pass_enable_disable() { let mut poi = PoiPass::default(); assert!(poi.is_enabled()); poi.enabled = false; assert!(!poi.is_enabled()); assert!(!poi.should_execute(15.0)); // Should not execute even at valid zoom poi.enabled = true; assert!(poi.is_enabled()); assert!(poi.should_execute(15.0)); // Should execute again } #[test] fn test_render_graph_get_pass() { let graph = RenderGraph::new(); let bg = graph.get_pass(PassType::Background); assert!(bg.is_some()); assert_eq!(bg.unwrap().pass_type(), PassType::Background); let fill = graph.get_pass(PassType::Fill); assert!(fill.is_some()); // Try to get a pass that doesn't exist let debug = graph.get_pass(PassType::Debug); assert!(debug.is_none()); } #[test] fn test_render_graph_remove_pass() { let mut graph = RenderGraph::new(); assert_eq!(graph.passes().len(), 5); graph.remove_pass(PassType::Background); assert_eq!(graph.passes().len(), 4); let bg = graph.get_pass(PassType::Background); assert!(bg.is_none()); } #[test] fn test_custom_pass_ordering() { let mut graph = RenderGraph::new(); // Create a custom pass with z_order between Fill and Stroke struct CustomPass; impl RenderPass for CustomPass { fn pass_type(&self) -> PassType { PassType::Debug } fn z_order(&self) -> i32 { 150 } fn is_enabled(&self) -> bool { true } fn min_zoom(&self) -> f64 { 0.0 } fn max_zoom(&self) -> f64 { 30.0 } fn execute(&self, _ctx: &mut nigig_map::render_graph::RenderContext) -> nigig_map::render_graph::PassStats { nigig_map::render_graph::PassStats::default() } } graph.add_pass(Box::new(CustomPass)); let passes = graph.passes(); assert_eq!(passes.len(), 6); // Verify ordering: Background(0), Fill(100), Custom(150), Stroke(200), ... let z_orders: Vec = passes.iter().map(|p| p.z_order()).collect(); assert_eq!(z_orders, vec![0, 100, 150, 200, 300, 400]); } #[test] fn test_pass_stats_collection() { let mut graph = RenderGraph::new(); // Initially no stats assert_eq!(graph.total_tiles_drawn(), 0); assert_eq!(graph.total_features_drawn(), 0); // Note: We can't test execute() without a full RenderContext, // which requires makepad widgets. This would be tested in // integration tests with the full UI. } #[test] fn test_pass_zoom_range_customization() { let mut poi = PoiPass::default(); // Default zoom range assert_eq!(poi.min_zoom(), 13.0); assert_eq!(poi.max_zoom(), 30.0); // Customize zoom range poi.min_zoom = 10.0; poi.max_zoom = 20.0; assert!(poi.should_execute(10.0)); assert!(poi.should_execute(15.0)); assert!(poi.should_execute(20.0)); assert!(!poi.should_execute(9.0)); assert!(!poi.should_execute(21.0)); } #[test] fn test_all_pass_types_have_names() { let types = vec![ PassType::Background, PassType::Fill, PassType::Stroke, PassType::Poi, PassType::Label, PassType::Selection, PassType::Debug, ]; for pass_type in types { let name = pass_type.name(); assert!(!name.is_empty(), "Pass type {:?} should have a name", pass_type); } } #[test] fn test_all_pass_types_have_default_z_order() { let types = vec![ PassType::Background, PassType::Fill, PassType::Stroke, PassType::Poi, PassType::Label, PassType::Selection, PassType::Debug, ]; let z_orders: Vec = types.iter().map(|t| t.default_z_order()).collect(); // Verify z_orders are unique let mut sorted = z_orders.clone(); sorted.sort(); sorted.dedup(); assert_eq!(z_orders.len(), sorted.len(), "All pass types should have unique z_orders"); // Verify z_orders are in expected order assert!(z_orders[0] < z_orders[1]); // Background < Fill assert!(z_orders[1] < z_orders[2]); // Fill < Stroke assert!(z_orders[2] < z_orders[3]); // Stroke < Poi assert!(z_orders[3] < z_orders[4]); // Poi < Label }