use facett_core::{Facet, harness};
use facett_graphview::{MetroBranch, MetroLine, MetroMap, MetroStation, MetroView, StationKind};
fn two_lines() -> MetroMap {
let line_a = MetroLine::new(
"A",
"Bench Run",
vec![
MetroStation::new("ui::run", "Run", StationKind::Start, true),
MetroStation::new("bench::collect", "collect", StationKind::Emitter, true),
MetroStation::new("bench::normalize", "normalize", StationKind::PassThrough, true),
MetroStation::with_branches(
"grpc::Submit",
"Bench.Submit",
StationKind::Grpc,
true,
vec![
MetroBranch::new("caller::ui::Submit", "viz", StationKind::UiClient, true),
MetroBranch::new("caller::cli::Submit", "nornir", StationKind::CliClient, true),
],
),
MetroStation::new("wh::bench_runs", "bench_runs", StationKind::Terminus, true),
],
);
let line_b = MetroLine::new(
"B",
"Docs Export",
vec![
MetroStation::new("ui::export", "Export", StationKind::Start, true),
MetroStation::new("docs::gather", "gather", StationKind::Emitter, true),
MetroStation::new("docs::render_svg", "render_svg", StationKind::Emitter, false), MetroStation::new("grpc::Render", "Docs.Render", StationKind::Grpc, true),
MetroStation::new("wh::doc_exports", "doc_exports", StationKind::Terminus, true),
],
);
MetroMap::new(vec![line_a, line_b])
}
#[test]
fn headless_render_reports_green_and_red_lines() {
let mut view = MetroView::new("Metro");
view.set_map(two_lines());
let report = harness::headless_render(&mut view);
assert_eq!(report.title, "Metro");
assert!(report.drew(), "the metro lines tessellated to vertices");
let s = &report.state;
assert_eq!(s["lines"], 2, "two lines drawn");
assert_eq!(s["green_lines"], 1, "exactly one green line");
assert_eq!(s["green"], false, "the map is not fully green");
let lines = s["line"].as_array().expect("line array");
assert_eq!(lines.len(), 2);
let a = &lines[0];
assert_eq!(a["id"], "A");
assert_eq!(a["green"], true, "line A is green (every gating stop lit)");
assert!(a["unlit"].as_array().unwrap().is_empty(), "line A has no unlit stops");
assert_eq!(a["station_count"], 4, "4 gating stops; the pass-through isn't one");
let b = &lines[1];
assert_eq!(b["id"], "B");
assert_eq!(b["green"], false, "line B is red (an emitter never fired)");
let unlit: Vec<&str> = b["unlit"].as_array().unwrap().iter().map(|v| v.as_str().unwrap()).collect();
assert_eq!(unlit, ["render_svg"], "the unlit station is named");
let render_svg = b["stations"]
.as_array()
.unwrap()
.iter()
.find(|st| st["label"] == "render_svg")
.expect("render_svg station present");
assert_eq!(render_svg["kind"], "emitter");
assert_eq!(render_svg["lit"], false);
let grpc_a = a["stations"].as_array().unwrap().iter().find(|st| st["kind"] == "grpc").unwrap();
let arms = grpc_a["branches"].as_array().expect("the gRPC stop carries caller arms");
assert_eq!(arms.len(), 2, "called by BOTH ui+cli → two arms");
let markers: Vec<&str> = arms.iter().map(|x| x["marker"].as_str().unwrap()).collect();
assert!(markers.contains(&"UI") && markers.contains(&"CLI"), "both markers present: {markers:?}");
assert!(arms.iter().all(|x| x["lit"].as_bool().unwrap()), "both arms exercised (lit)");
}
#[test]
fn discovery_local_ctor_renders_two_lines() {
let mut view = MetroView::local();
let report = harness::headless_render(&mut view);
assert!(report.drew());
assert_eq!(report.state["lines"], 2);
assert_eq!(report.state["green_lines"], 1);
let caps = view.caps();
assert!(caps.themeable && caps.resizable && caps.selectable);
}