crates/nornir-warehouse-nav/tests/robot_world.rs
//! **robot_world** — egui_kittest robot-UI suite for the Warehouse Navigator's WORLD GRAPH.
//!
//! Drives the SHIPPED `WarehouseNav` facet through a real `egui_kittest::Harness` render (kittest
//! injects at the egui event layer, so the XWayland synthetic-button trap does not apply). Covers:
//!
//! - the 🌐 world toggle switches the nav into world mode and renders the repos→crates→functions
//! LOD surface (all three tiers present);
//! - the function tier is exactly what was fed: nothing (and said so) when nothing was, the named
//! fns and their call edge when one crate's graph is injected (the funcgraph seam).
//!
//! The per-frame-relayout regression guard lives in `robot_world_frame_budget.rs` (its own binary,
//! so the process-wide `world_build_calls()` counter is isolated).
#![cfg(not(target_arch = "wasm32"))]
use std::cell::RefCell;
use std::rc::Rc;
use egui::vec2;
use egui_kittest::kittest::Queryable;
use egui_kittest::Harness;
use facett_core::Facet;
use nornir_warehouse_nav::WarehouseNav;
/// ROBOT SCENARIO — the 🌐 toggle switches the nav into world mode and the LOD surface descends
/// repos → crates → functions. Driven by CLICKING the toggle button (addressed by its label), the
/// way an operator does. RED-when-broken: break the toggle or drop a tier and this fails.
#[test]
fn robot_world_toggle_switches_to_lod_and_renders_all_tiers() {
// a world with a function tier to descend to (the tests' generated one: 300 fns)
let nav = Rc::new(RefCell::new(WarehouseNav::from_fixture_with_functions(300)));
let n = nav.clone();
let mut h = Harness::builder()
.with_size(vec2(1200.0, 800.0))
.build_ui(move |ui| {
n.borrow_mut().ui(ui);
});
h.run();
// Off by default → the constellation drill-down.
assert_eq!(Facet::state_json(&*nav.borrow())["level"], "constellation");
// The toggle renders, labelled for the OFF state.
assert!(
h.query_by_label("🌐 world: off").is_some(),
"the world toggle renders"
);
// Click it → world mode.
h.get_by_label("🌐 world: off").click();
h.run();
h.run();
let s = Facet::state_json(&*nav.borrow());
assert_eq!(
s["level"], "world",
"the 🌐 toggle switches the nav into world mode: {s}"
);
assert_eq!(s["lod"], "functions");
// The LOD surface descends repos → crates → functions — all three tiers present,
// the function tier exactly the 300 fns that were fed.
assert_eq!(s["preview_repo_nodes"], 12, "repos tier present: {s}");
assert!(
s["preview_crate_nodes"].as_u64().unwrap() >= 1,
"crates tier present: {s}"
);
assert_eq!(
s["preview_fn_nodes"], 300,
"functions tier = what was fed: {s}"
);
// The lowered render model carries exactly the previewed nodes.
assert_eq!(s["preview_model_nodes"], s["preview_nodes"]);
// The button now reflects the ON state and toggles back to the drill-down.
assert!(
h.query_by_label("🌐 world: ON").is_some(),
"toggle now shows ON: {s}"
);
h.get_by_label("🌐 world: ON").click();
h.run();
h.run();
assert_eq!(
Facet::state_json(&*nav.borrow())["level"],
"constellation",
"the toggle switches back off"
);
}
/// ROBOT SCENARIO — the function tier is exactly what the navigator was given: nothing when it was
/// given nothing (and the surface SAYS there is no tier), the two named fns and their one call edge
/// when one crate's graph is fed. RED-when-broken: let a filler node appear under a crate nobody
/// named a function of, and this fails.
#[test]
fn robot_world_function_tier_is_what_was_fed_and_nothing_else() {
// (a) Nothing fed → no function node at all, and the header says so.
{
let nav = Rc::new(RefCell::new(WarehouseNav::from_fixture()));
let n = nav.clone();
let mut h = Harness::builder()
.with_size(vec2(1000.0, 700.0))
.build_ui(move |ui| {
n.borrow_mut().ui(ui);
});
nav.borrow_mut().update_json(r#"{"world":true}"#);
h.run();
let s = Facet::state_json(&*nav.borrow());
assert_eq!(
(s["real_fn_nodes"].as_u64(), s["preview_fn_nodes"].as_u64()),
(Some(0), Some(0)),
"no fn fed ⇒ no fn drawn: {s}"
);
assert!(
s.get("synthetic_fn_nodes").is_none(),
"no synthetic tier exists to count: {s}"
);
assert!(
h.query_by_label_contains("no function tier").is_some(),
"the surface says there is no function tier"
);
}
// (b) One crate's function graph fed → exactly those fns and that call edge.
{
use nornir_depgraph::funcgraph::{CrateFuncGraph, FnEdge, FnNode};
let real = CrateFuncGraph {
crate_name: "nornir-depgraph".into(),
nodes: vec![
FnNode {
id: "edda::nornir-depgraph::crate::build".into(),
name: "build".into(),
crate_name: "nornir-depgraph".into(),
},
FnNode {
id: "edda::nornir-depgraph::crate::layout".into(),
name: "layout".into(),
crate_name: "nornir-depgraph".into(),
},
],
edges: vec![FnEdge {
from: "edda::nornir-depgraph::crate::build".into(),
to: "edda::nornir-depgraph::crate::layout".into(),
}],
};
// `edda` produces `nornir-depgraph` in the fixture.
let nav = Rc::new(RefCell::new(
WarehouseNav::from_fixture().with_real_functions("edda", vec![real]),
));
let n = nav.clone();
let mut h = Harness::builder()
.with_size(vec2(1000.0, 700.0))
.build_ui(move |ui| {
n.borrow_mut().ui(ui);
});
nav.borrow_mut().update_json(r#"{"world_target":100000}"#);
nav.borrow_mut().update_json(r#"{"world":true}"#);
h.run();
let s = Facet::state_json(&*nav.borrow());
assert_eq!(
(s["real_fn_nodes"].as_u64(), s["preview_fn_nodes"].as_u64()),
(Some(2), Some(2)),
"the two fns and no third: {s}"
);
assert_eq!(s["real_call_edges"], 1, "the call edge resolved: {s}");
assert_eq!(
s["real_fn_crates"], 1,
"exactly the one crate has a function tier: {s}"
);
}
}