facett-plandag/tests/flow_lane.rs
use egui::{Rect, pos2, vec2};
use facett_core::Facet;
use facett_plandag::{CostMetric, Msg, PlanDagView};
#[test]
fn producers_are_left_and_metrics_do_not_rebuild_geometry() {
let mut view = PlanDagView::local();
let scene = view.flow_scene();
for edge in &scene.graph().edges {
let a = scene
.graph()
.nodes
.iter()
.find(|n| n.id == edge.from)
.unwrap();
let b = scene
.graph()
.nodes
.iter()
.find(|n| n.id == edge.to)
.unwrap();
assert!(a.position[0] < b.position[0]);
}
let generation = scene.generation();
view.update(Msg::SetMetric(CostMetric::Rows));
assert_eq!(view.flow_scene().generation(), generation);
view.update(Msg::ToggleGroup("1".into()));
assert_ne!(view.flow_scene().generation(), generation);
view.update(Msg::ToggleGroup("1".into()));
assert_eq!(view.flow_scene().generation(), generation);
}
#[test]
fn navigation_is_observable_and_zoom_keeps_cursor_anchor() {
let mut view = PlanDagView::local();
view.update(Msg::Fit(Rect::from_min_size(
pos2(10.0, 20.0),
vec2(900.0, 500.0),
)));
assert!(view.state().fitted);
let anchor = pos2(240.0, 140.0);
let world = view.nav().transform().inverse().mul_pos(anchor);
view.update(Msg::Zoom {
factor: 2.0,
anchor,
});
assert!(view.nav().to_screen(world).distance(anchor) < 0.001);
let old = view.nav().offset;
view.update(Msg::Pan(vec2(17.0, -4.0)));
assert_eq!(view.nav().offset, [old[0] + 17.0, old[1] - 4.0]);
assert_eq!(view.state_json()["nav"]["scale"], view.nav().scale);
}
#[test]
fn zoom_culls_labels_but_keeps_the_same_scene() {
let mut view = PlanDagView::local();
let rect = Rect::from_min_size(pos2(0.0, 0.0), vec2(900.0, 500.0));
view.update(Msg::Fit(rect));
let generation = view.flow_scene().generation();
let ctx = egui::Context::default();
let visible = |view: &PlanDagView| {
let mut count = 0;
let mut output = ctx.run_ui(egui::RawInput::default(), |ui| {
count = facett_flow::paint(
ui,
egui::Id::new("cull"),
rect,
view.flow_scene(),
&facett_flow::View::from_navigable(view.nav(), rect),
&facett_flow::PaintOpts {
animation: facett_flow::Animation::None,
..Default::default()
},
)
.on_screen
.len();
});
output.textures_delta.clear();
count
};
assert_eq!(visible(&view), view.flow_scene().graph().nodes.len());
view.update(Msg::Zoom {
factor: 8.0,
anchor: rect.center(),
});
assert!(visible(&view) < view.flow_scene().graph().nodes.len());
assert_eq!(generation, view.flow_scene().generation());
}
#[test]
fn restoring_an_invalid_zoom_clamp_keeps_the_usable_camera() {
let mut view = PlanDagView::local();
let before = *view.nav();
assert!(!view.load_state(&serde_json::json!({
"nav": { "scale": 1.0, "offset": [0.0, 0.0], "min_scale": 2.0, "max_scale": 1.0 }
})));
assert_eq!(*view.nav(), before);
view.update(Msg::Zoom {
factor: 2.0,
anchor: pos2(100.0, 100.0),
});
assert_eq!(view.nav().scale, 2.0);
}