use egui_kittest::Harness;
use facett_core::{Facet, Layout, Scene, hash_color};
use facett_graph::GraphView;
fn populated_graph() -> Scene {
let mut s = Scene::new();
let people: Vec<usize> = (0..6).map(|i| s.node(format!("Person{i}"), hash_color("Person"))).collect();
let co = s.node("Acme", hash_color("Company"));
let addr = s.node("HQ", hash_color("Address"));
for &p in &people {
s.edge(p, co);
}
s.edge(co, addr);
for w in people.windows(2) {
s.edge(w[0], w[1]);
}
s
}
#[test]
fn graph_renders_non_blank_and_confined() {
let mut harness = Harness::builder().with_size(egui::vec2(640.0, 480.0)).build_ui(move |ui| {
facett_core::set_theme(ui.ctx(), facett_core::Theme::sci_fi());
let full = ui.available_rect_before_wrap();
let g_rect = egui::Rect::from_min_size(full.min, egui::vec2(full.width(), full.height() * 0.5));
let mut view = GraphView::new(populated_graph());
view.set_layout(Layout::Force);
ui.scope_builder(egui::UiBuilder::new().max_rect(g_rect), |ui| view.ui(ui));
});
harness.run_steps(3);
let img = match harness.render() {
Ok(img) => img,
Err(e) => {
eprintln!("[robot] no wgpu backend ({e}) — graph confinement pixel leg skipped");
return;
}
};
let (w, h) = (img.width(), img.height());
let win_bg = *img.get_pixel(w / 2, h - 3);
let (wr, wg, wb) = (win_bg.0[0] as i32, win_bg.0[1] as i32, win_bg.0[2] as i32);
let far_from =
|p: &image::Rgba<u8>| (p.0[0] as i32 - wr).abs() + (p.0[1] as i32 - wg).abs() + (p.0[2] as i32 - wb).abs() > 24;
let graph_h = (h as f32 * 0.5) as u32;
let margin_y0 = (h as f32 * 0.6) as u32; let (mut body, mut body_tot, mut leak, mut leak_tot) = (0usize, 0usize, 0usize, 0usize);
for (_x, y, p) in img.enumerate_pixels() {
if y < graph_h {
body_tot += 1;
if far_from(p) {
body += 1;
}
} else if y >= margin_y0 {
leak_tot += 1;
if far_from(p) {
leak += 1;
}
}
}
let body_ratio = body as f64 / body_tot.max(1) as f64;
let margin_leak = leak as f64 / leak_tot.max(1) as f64;
eprintln!("[robot] graph body content {body_ratio:.4}, outside-widget leak {margin_leak:.4}");
assert!(body_ratio > 0.01, "the graph rect drew content (ratio {body_ratio:.4})");
assert!(margin_leak < 0.02, "graph content confined to its rect (leak {margin_leak:.4})");
#[cfg(feature = "testmatrix")]
facett_core::testmatrix::emit(
"facett-graph.robot_confined",
"non_blank_and_confined",
body_ratio > 0.01 && margin_leak < 0.02,
&format!("graph_rect_ratio={body_ratio:.4} outside_leak={margin_leak:.4}"),
);
}
#[test]
fn graph_final_picture_png_blob() {
let mut harness = Harness::builder().with_size(egui::vec2(900.0, 640.0)).build_ui(move |ui| {
facett_core::set_theme(ui.ctx(), facett_core::Theme::cyberpunk_neon());
let mut view = GraphView::new(populated_graph()).with_title("graph-final");
view.set_layout(Layout::Force);
view.ui(ui);
});
harness.run_steps(3);
let img = match harness.render() {
Ok(img) => img,
Err(e) => {
eprintln!("[robot] no wgpu backend ({e}) — graph PNG blob skipped");
return;
}
};
let dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/snapshots");
std::fs::create_dir_all(&dir).unwrap();
let path = dir.join("graph_final.png");
img.save(&path).expect("save graph_final.png");
let bytes = std::fs::metadata(&path).unwrap().len();
assert!(bytes > 1000, "graph_final.png is a real frame ({bytes} bytes)");
eprintln!("[robot] wrote {} ({bytes} bytes)", path.display());
#[cfg(feature = "testmatrix")]
facett_core::testmatrix::emit(
"facett-graph.robot_png",
"final_picture_blob_written",
bytes > 1000,
&format!("graph_final.png {bytes} bytes"),
);
}