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

nordisk/nornir

tests/robot_arch_metro.rs

//! **Robot-UI Architecture sub-view walk + Metro** — drive 🏛 Architecture's
//! sub-view selector through every lens (Deps → Live → Wiring → Boundaries →
//! CallGraph → Metro), then reload + fit, and nav the standalone 🚇 Metro tab.
//! Fills a robot-ui row per Architecture lens.
//!
//! Run: `cargo test --features "viz" --test robot_arch_metro`
#![cfg(feature = "viz")]

use std::path::PathBuf;
use std::sync::atomic::{AtomicU64, Ordering};

use egui_kittest::Harness;
use nornir::viz::UrdrThreadsApp;
use nornir_robotui::egui;
use nornir_robotui::{Action, Assert, Observable, RobotSession, Scenario, Step, status};
use serde_json::json;

struct VizApp(UrdrThreadsApp);
impl Observable for VizApp {
    fn state_json(&self) -> serde_json::Value {
        self.0.state_json()
    }
}

static SEQ: AtomicU64 = AtomicU64::new(0);

fn robot(tag: &str) -> RobotSession<'static, VizApp> {
    unsafe { std::env::set_var("NORNIR_VIZ_NO_DURABLE_ACTIONLOG", "1") };
    let n = SEQ.fetch_add(1, Ordering::Relaxed);
    let root = std::env::temp_dir().join(format!("nornir-arch-{tag}-{}-{n}", std::process::id()));
    let _ = std::fs::create_dir_all(&root);
    let app = UrdrThreadsApp::with_repos(root, "nornir".to_string(), PathBuf::new(), vec![]);
    let harness = Harness::builder()
        .with_size(egui::Vec2::new(1600.0, 1000.0))
        .build_ui_state(|ui, app: &mut VizApp| app.0.draw_ui(ui), VizApp(app));
    let mut r = RobotSession::new(harness, "nornir");
    r.run(4);
    r
}

fn assert_all_pass(rows: &[nornir_robotui::TestResultRow]) {
    for r in rows {
        assert_eq!(
            r.status,
            status::PASS,
            "step {:?} failed: {}",
            r.test_name,
            r.message
        );
    }
}

#[test]
fn robot_architecture_subview_walk() {
    let mut robot = robot("walk");
    robot
        .click_label("🏛 Architecture")
        .expect("Architecture header");
    robot.run(2);

    let subviews = [
        ("🔗 Dep Graph", "Deps"),
        ("📡 Live system", "Live"),
        ("🏛 Wiring", "Wiring"),
        ("📍 Hållpunkter", "Boundaries"),
        ("🕸 Call Graph", "CallGraph"),
        ("🚇 Metro (call path)", "Metro"),
    ];
    let mut scenario = Scenario::new("arch-subviews");
    for (label, id) in subviews {
        scenario = scenario.step(
            Step::new(format!("select {label} → sub_view == {id}"))
                .action(Action::ClickLabel(label.to_string()))
                .assert(Assert::State {
                    pointer: "/architecture/sub_view".into(),
                    expected: json!(id),
                }),
        );
    }
    scenario = scenario
        // Return to a graph lens (the ⊙ fit / arch control strip only renders on
        // the wiring/live graph views, not the Metro call-path lens).
        .step(
            Step::new("back to 🏛 Wiring lens → sub_view == Wiring")
                .action(Action::ClickLabel("🏛 Wiring".into()))
                .assert(Assert::State {
                    pointer: "/architecture/sub_view".into(),
                    expected: json!("Wiring"),
                }),
        )
        .step(
            Step::new("⊙ fit the graph")
                .action(Action::ClickLabel("⊙ fit".into()))
                .assert(Assert::Drew),
        );
    assert_all_pass(&robot.run_scenario(&scenario));
}

#[test]
fn robot_metro_tab_nav() {
    let mut robot = robot("metro");
    let scenario = Scenario::new("metro-journey")
        .step(
            Step::new("nav 🚇 Metro → Metro")
                .action(Action::ClickLabel("🚇 Metro".into()))
                .assert(Assert::State {
                    pointer: "/tab".into(),
                    expected: json!("Metro"),
                }),
        )
        .step(Step::new("metro pane drew").assert(Assert::Drew));
    assert_all_pass(&robot.run_scenario(&scenario));
}