facett-graphview 0.1.12

facett — a vello-backed, domain-agnostic scalable 2D graph render engine. Runtime-selects vello (GPU/wgpu) when a usable GPU exists, vello_cpu (multithreaded SIMD) as the no-GPU fallback. The eventual home for every graph surface (dep/arch/release dashboards, korp, graph-DB browsing).
Documentation
//! **Metro view — inject-assert headless test.** Build a 2-line [`MetroMap`]
//! (one all-lit → green, one with an unlit emitter → red), drive [`MetroView`]
//! one headless egui frame through the shared `facett_core::harness`, and assert
//! its `state_json` reports exactly what was drawn — line A green, line B red
//! with the unlit station named — without a single pixel. Real data in, real
//! verdict out (not no-crash).

use facett_core::{Facet, harness};
use facett_graphview::{MetroBranch, MetroLine, MetroMap, MetroStation, MetroView, StationKind};

/// The injected fixture: A is fully lit (green) and its gRPC verb FORKS to BOTH
/// caller arms (UI viz + CLI, both lit); B has one unlit emitter (red).
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), // UNLIT
            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());

    // Drive one real headless egui frame — this IS the render the pixels come
    // from, so the vertex count proves it actually drew the tracks/stops.
    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);

    // Line A: green, no unlit stations.
    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");
    // The pass-through is present but doesn't count as a station.
    assert_eq!(a["station_count"], 4, "4 gating stops; the pass-through isn't one");

    // Line B: red, the unlit emitter named.
    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");
    // And the unlit stop is the emitter, reported lit=false in the station list.
    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);

    // FORK: line A's gRPC verb diverges to TWO marked caller arms (UI + CLI), both
    // lit — asserted on the serialised branch topology (LAW 6), through the real
    // headless render above (so the diverging arms actually tessellated).
    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() {
    // The discovery-contract ctor must produce a real, renderable map.
    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);
    // Themeable + resizable + selectable per the contract.
    let caps = view.caps();
    assert!(caps.themeable && caps.resizable && caps.selectable);
}