use super::*; use oa_core::{Kind, Layer, Position, RelationKind}; #[test] fn saved_membership_respects_filters_and_does_not_change_project() { let mut p = Project::empty(); let first = p.add(Kind::Activity, "Same name", 20., 20.); let second = p.add(Kind::Activity, "Same name", 340., 20.); let relation = p.relate(RelationKind::Interaction, "Handoff", first, second); let shown = p.ensure_diagram(Layer::Oa); let mut hidden = p.diagrams[&shown].clone(); hidden.id = Id::new_v4(); hidden.alias = "filtered_copy".into(); hidden.nodes = hidden .nodes .into_values() .map(|mut node| { node.id = Id::new_v4(); node.alias = format!("filtered_{}", node.alias); (node.id, node) }) .collect(); hidden.view_options.hidden_edges.push(relation); let hidden_id = hidden.id; p.diagrams.insert(hidden_id, hidden); let before = p.clone(); let hits = saved_usages(&p, relation); assert_eq!(hits.len(), 1); assert_eq!(hits[0].surface, Surface::Saved(shown)); assert_eq!(hits[0].target, Target::Edge(relation)); let hits = saved_usages(&p, first); assert_eq!(hits.len(), 2); assert!(hits.iter().all(|hit| match hit.target { Target::Placement(node) => p.diagrams[&hit.surface.id()].nodes[&node].element == first, _ => false, })); assert_eq!(p, before); } #[test] fn folded_child_is_not_a_visible_node_and_placement_identity_stays_exact() { let mut p = Project::empty(); let parent = p.add(Kind::Activity, "Container", 20., 20.); let child = p .add_element(Kind::Activity, Layer::Oa, "Nested", Some(parent)) .unwrap(); let diagram = p.ensure_diagram(Layer::Oa); let child_node = p.place(diagram, child, Position { x: 50., y: 100. }); let parent_node = p.diagrams[&diagram] .nodes .values() .find(|n| n.element == parent) .unwrap() .id; let hits = saved_usages(&p, child_node); assert_eq!(hits.len(), 1); assert_eq!(hits[0].target, Target::Placement(child_node)); p.diagrams .get_mut(&diagram) .unwrap() .nodes .get_mut(&parent_node) .unwrap() .collapsed = true; let before = p.clone(); assert!(saved_usages(&p, child).is_empty()); assert!(saved_usages(&p, child_node).is_empty()); assert_eq!(saved_usages(&p, parent).len(), 1); assert_eq!(p, before); } #[test] fn ports_are_found_at_the_visible_owner_and_unplaced_elements_do_not_match_names() { let mut p = Project::empty(); let owner = p.add(Kind::Function, "Compute", 20., 20.); let port = Id::new_v4(); let element = oa_core::ports::make_port( &p, port, owner, "Input", oa_core::PortContract::FunctionInput { incoming_items: vec![], }, ) .unwrap(); p = oa_core::execute_batch(&p, &[oa_core::Command::CreateElement(element)]).unwrap(); let unrelated = p .add_element(Kind::Function, Layer::Sa, "Compute", None) .unwrap(); let hits = saved_usages(&p, port); assert_eq!(hits.len(), 1); let view = projection::project_view(&p, hits[0].surface.id()); let painted = view .ports .iter() .find(|shown| shown.element == port) .unwrap(); assert_eq!( hits[0].target, Target::Port { port, placement: painted.owner } ); assert_eq!( hits[0].bounds.center(), iced::Point::new(painted.position.x, painted.position.y) ); assert!(saved_usages(&p, unrelated).is_empty()); assert!(saved_usages(&p, Id::new_v4()).is_empty()); } #[test] fn reveal_camera_centers_target_without_whole_view_shrink() { let bounds = Rectangle { x: 100_000., y: -50_000., width: 224., height: 94., }; let viewport = iced::Size::new(700., 500.); let (zoom, pan) = camera(bounds, viewport); assert_eq!(zoom, 1.25); assert!((bounds.center_x() * zoom + pan.x - 350.).abs() < 0.01); assert!((bounds.center_y() * zoom + pan.y - 250.).abs() < 0.01); } #[test] fn oversized_container_reveal_targets_its_labelled_header() { let mut p = Project::empty(); let container = p.add(Kind::Activity, "Large enclosing activity", 40., 70.); let diagram = p.ensure_diagram(Layer::Oa); let node = p .diagrams .get_mut(&diagram) .unwrap() .nodes .values_mut() .next() .unwrap(); node.size = oa_core::Size { width: 4000., height: 4000., }; let before = p.clone(); let hits = saved_usages(&p, container); assert_eq!(hits.len(), 1); assert_eq!(hits[0].bounds.x, 40.); assert_eq!(hits[0].bounds.y, 70.); assert!(hits[0].bounds.width <= 420.); assert!(hits[0].bounds.height <= 64.); let (zoom, pan) = camera(hits[0].bounds, iced::Size::new(500., 300.)); assert!((hits[0].bounds.center_x() * zoom + pan.x - 250.).abs() < 0.01); assert!(70. * zoom + pan.y >= 0.); assert_eq!(p, before); } #[test] fn state_machine_owner_finds_its_view_without_a_machine_placement() { let mut p = Project::empty(); let machine = p .add_element(Kind::StateMachine, Layer::Sa, "Monitor", None) .unwrap(); let unrelated = p .add_element(Kind::StateMachine, Layer::Sa, "Other", None) .unwrap(); let diagram = p.ensure_diagram(Layer::Sa); p.diagrams.get_mut(&diagram).unwrap().projection = oa_core::ProjectionKind::StateMachine { machine }; let before = p.clone(); let hits = saved_usages(&p, machine); assert_eq!(hits.len(), 1); assert_eq!(hits[0].surface, Surface::Saved(diagram)); assert_eq!(hits[0].target, Target::Whole); assert_eq!(hits[0].role, "state machine view"); assert!(saved_usages(&p, unrelated).is_empty()); assert_eq!(p, before); } #[test] fn whole_diagram_camera_fits_large_bounds_instead_of_individual_object_scale() { let bounds = Rectangle { x: 2000., y: -4000., width: 100_000., height: 80_000., }; let (zoom, pan) = camera_for(&Target::Whole, bounds, iced::Size::new(500., 300.)); assert!(zoom < 0.01); assert!(bounds.x * zoom + pan.x >= 0.); assert!(bounds.y * zoom + pan.y >= 0.); assert!((bounds.x + bounds.width) * zoom + pan.x <= 500.); assert!((bounds.y + bounds.height) * zoom + pan.y <= 300.); }