tests/viz_bloodstream.rs
//! Headless robot-UI drive of the 🩸 **Bloodstream** tab (feature `viz`).
//!
//! Proves the DONE contract without a window or GPU: switch to the tab, assert the
//! organic body renders REAL workspace crates (organs) + arteries (vessels), then
//! **drill into an organ** through the control channel (`bloodstream.expand:<crate>`)
//! and assert the **recursive external-dependency layer appears** — a non-empty
//! crates.io deps-of-deps closure reaching ≥2 rings deep — read back from
//! `state_json` (LAW #6). Same pattern as `tests/viz_demo.rs`: one `ctx.run` per
//! frame drives `draw_ui`, which polls the control channel.
#![cfg(feature = "viz")]
use std::path::PathBuf;
use nornir::viz::UrdrThreadsApp;
use nornir::viz::control::VizCommand;
fn build_app() -> UrdrThreadsApp {
let warehouse_root =
std::env::temp_dir().join(format!("nornir-viz-bloodstream-{}", std::process::id()));
let _ = std::fs::create_dir_all(&warehouse_root);
// No live warehouse ⇒ the tab falls back to nornir's OWN body (embedded lock),
// so the render + the recursive drill-down are real, deterministic data.
UrdrThreadsApp::with_repos(
warehouse_root,
"nornir".to_string(),
PathBuf::new(),
vec!["nornir".to_string()],
)
}
/// One headless frame so `draw_ui` (and the pane's `draw`) runs.
fn tick(app: &mut UrdrThreadsApp) {
let ctx = egui::Context::default();
// egui 0.36 debug-asserts on a FullOutput dropped with unapplied texture
// deltas; nothing is uploaded headless, so they are cleared (2026-10-03).
ctx.run_ui(egui::RawInput::default(), |ui| app.draw_ui(ui)).textures_delta.clear();
}
#[test]
fn bloodstream_renders_body_then_drills_into_recursive_external_deps() {
let mut app = build_app();
// 1) Switch to the Bloodstream tab and pump a few frames so the body builds.
app.apply_command(&VizCommand {
tab: Some("Bloodstream".into()),
..Default::default()
});
for _ in 0..4 {
tick(&mut app);
}
let state = app.state_json();
assert_eq!(state["tab"], "Bloodstream", "the tab switched");
let blood = &state["bloodstream"];
let organs = blood["organs"].as_array().expect("organs is an array");
assert!(
!organs.is_empty(),
"the circulatory body rendered REAL workspace crates as organs (got 0)"
);
assert_eq!(
blood["from_data"], true,
"built from real data, not a demo/blank"
);
// Every organ carries an anatomical slot + a body position (the render coords).
assert!(
organs
.iter()
.all(|o| o["organ"].is_string() && o["x"].is_number() && o["y"].is_number())
);
// Vessels (arteries) wire the organs together.
assert!(
blood["vessel_count"].as_u64().unwrap_or(0) >= 1,
"at least one artery between organs"
);
// Nothing drilled yet (lazy).
assert_eq!(
blood["external_count"].as_u64().unwrap(),
0,
"no capillaries before drill-down"
);
// 2) Pick an organ to drill into — prefer `nornir` (a big closure), else the
// first organ the body seated.
let target = organs
.iter()
.find_map(|o| o["crate"].as_str().filter(|c| *c == "nornir"))
.or_else(|| organs[0]["crate"].as_str())
.expect("an organ crate name")
.to_string();
// 3) Drill in through the control channel (the robot-UI `viz.click` path).
app.apply_command(&VizCommand {
click_id: Some(format!("bloodstream.expand:{target}")),
..Default::default()
});
for _ in 0..4 {
tick(&mut app);
}
// 4) Assert the RECURSIVE external-dependency layer appeared (non-empty), and
// that it is genuinely deps-of-deps (reaches ≥2 rings deep).
let state2 = app.state_json();
let blood2 = &state2["bloodstream"];
let total_ext = blood2["external_count"].as_u64().unwrap();
assert!(
total_ext > 0,
"drilling `{target}` surfaced its non-workspace transitive deps (got 0)"
);
let drilled = blood2["organs"]
.as_array()
.unwrap()
.iter()
.find(|o| o["crate"] == serde_json::json!(target))
.expect("the drilled organ is present");
assert_eq!(drilled["expanded"], true, "`{target}` is now expanded");
let ext_here = drilled["external_count"].as_u64().unwrap();
assert!(ext_here > 0, "`{target}` has a non-empty external closure");
assert!(
drilled["external_max_depth"].as_u64().unwrap() >= 2,
"the closure is genuinely RECURSIVE (deps-of-deps, depth ≥2): {:?}",
drilled["external_max_depth"]
);
// The external entries carry real name/version/depth (crates.io resolver data).
let ext = drilled["external"].as_array().unwrap();
assert!(
ext.iter()
.all(|e| e["name"].is_string() && e["version"].is_string() && e["depth"].is_number())
);
assert!(
ext.iter().any(|e| e["depth"].as_u64() == Some(1)),
"a direct external dep (depth 1) is present"
);
assert!(
ext.iter().any(|e| e["depth"].as_u64().unwrap_or(0) >= 2),
"a transitive deps-of-deps entry (depth ≥2) is present"
);
// 5) Collapse clears the capillaries (drill-down is toggleable).
app.apply_command(&VizCommand {
click_id: Some(format!("bloodstream.expand:{target}")),
..Default::default()
});
for _ in 0..2 {
tick(&mut app);
}
let state3 = app.state_json();
assert_eq!(
state3["bloodstream"]["external_count"].as_u64().unwrap(),
0,
"collapsing the organ dropped its capillaries"
);
}