Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

facett-tabbar/tests/robot.rs

//! **Robot JSON-drive scenario for the tab bar**, driven through the SHARED
//! generic-Facet probe in `facett_core::harness` (no hand-rolled render+emit
//! boilerplate). The pane's `update_json` robot seam was a **dead no-op** — the
//! `impl_facet_via_elm!` bridge does not generate one and the pane never overrode
//! `Facet::update_json`, so a headless robot could not drive it (only the in-view
//! `ui_render` self-cell existed). Its `Msg` carries an internal FC-7
//! `AdvanceUnderline { target: egui::Rect, .. }` clock tick that is not serde-able;
//! that variant is `#[serde(skip)]` (a robot never drives it), leaving the one real
//! user interaction — `SelectTab` — fully drivable. This test (a) proves the
//! now-LIVE seam end-to-end — feed a scripted message list, watch `state_json`
//! transition — and (b) adds the shared probe's `headless_render` +
//! `responds_to_input` functional cells via `facett_core::testmatrix::probe_and_emit`
//! (a no-op unless built with `--features testmatrix`). The `responds_to_input`
//! aspect is NEW coverage: it would go RED if the JSON drive seam regressed back
//! to a no-op. See `.nornir/facett-platform-gaps.md`.

use facett_tabbar::{TabBarView, TabItem};

#[test]
fn robot_json_drive_scenario() {
    let mut view = TabBarView::new("top").with_tabs(vec![
        TabItem::new("Timeline", "🧵 Timeline"),
        TabItem::new("DepGraph", "🔗 Dep Graph"),
        TabItem::new("Release", "🚀 Release"),
    ]);

    // Switch tabs twice — the exact JSON a headless robot sends through the
    // `update_json` seam (serde-tagged, no concrete Msg type at the call site).
    let script = [
        r#"{"select_tab":"DepGraph"}"#, // header click
        r#"{"select_tab":"Release"}"#,  // another header click
    ];

    let probe = facett_core::testmatrix::probe_and_emit("facett-tabbar", &mut view, &script);

    // The initial render drew real geometry (the tab headers) over non-empty state.
    assert!(probe.drew(), "the tab bar must tessellate to vertices");
    assert!(probe.cardinality() > 0, "state_json reports the tabs");
    // The input surface is LIVE: at least one scripted message moved state.
    assert!(probe.responded(), "update_json must drive state — a dead seam is a regression");

    // Pane-specific: the switch lands in `active` and bumps the session switch tally.
    assert_eq!(probe.steps[0].state["active"], "DepGraph", "select_tab activates the tab");
    assert!(probe.steps[0].changed, "select_tab moved state");
    assert_eq!(probe.final_state["active"], "Release", "the second switch is active");
    assert_eq!(probe.final_state["switches"], 2, "two real switches recorded");
}