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

nordisk/facett

facett-sdp/tests/render.rs

//! **CPU render-proof for facett-sdp.** The inline tests cover deps parsing,
//! validation, and `state_json`; the `SdpEditor::ui()` render path (the flow-list
//! editor with its name/deps/SQL boxes + Add/Remove buttons, and the Graph DAG
//! preview) is never executed there. This drives real `egui_kittest` frames in
//! **both** modes so the painter runs and the controls ride into the AccessKit
//! tree — asserting the surface renders non-blank AND that `state_json` reflects a
//! programmatic edit.

use egui_kittest::kittest::Queryable;
use egui_kittest::Harness;

use facett_sdp::{Flow, Mode, SdpEditor};

fn sample() -> SdpEditor {
    SdpEditor::new("etl").with_flows([
        Flow::new("raw", Vec::<String>::new(), "SELECT * FROM read_files('/in')"),
        Flow::new("clean", ["raw"], "SELECT * FROM raw WHERE ok"),
    ])
}

#[test]
fn edit_mode_paints_toggles_flows_and_add_button() {
    let ed = sample();
    // state_json exposes the pipeline as data before we ever render.
    let st = ed.state_json();
    assert_eq!(st["mode"], "Edit");
    assert_eq!(st["valid"], true);
    assert_eq!(st["flows"][0]["name"], "raw");
    assert_eq!(st["flows"][1]["deps"][0], "raw");

    let mut ed_ui = ed;
    let mut harness = Harness::new_ui(move |ui| {
        ed_ui.ui(ui);
    });
    harness.run();
    // Mode toggles, per-flow headings, and the add/remove controls reached the tree
    // → the surface rendered non-blank.
    assert!(harness.query_by_label("✎ Edit").is_some(), "the Edit toggle painted");
    assert!(harness.query_by_label("◈ Graph").is_some(), "the Graph toggle painted");
    assert!(harness.query_by_label("raw").is_some(), "the 'raw' flow heading painted");
    assert!(harness.query_by_label("clean").is_some(), "the 'clean' flow heading painted");
    assert!(harness.query_by_label("+ Add flow").is_some(), "the Add-flow button painted");
    // one Remove button per flow (two here) → prove the per-flow rows rendered.
    assert_eq!(harness.query_all_by_label("✕ Remove").count(), 2, "a Remove button per flow painted");
}

#[test]
fn graph_mode_renders_the_dag_without_panicking() {
    let mut ed = sample();
    ed.set_mode(Mode::Graph);
    assert_eq!(ed.state_json()["mode"], "Graph");
    let mut harness = Harness::new_ui(move |ui| {
        ed.ui(ui); // paints nodes + edges via the painter — must not panic
    });
    harness.run();
}

#[test]
fn state_json_reflects_a_programmatic_sql_edit() {
    let mut ed = sample();
    ed.set_flow_query(1, "SELECT id, upper(name) AS n FROM raw");
    let st = ed.state_json();
    assert_eq!(st["flows"][1]["query"], "SELECT id, upper(name) AS n FROM raw");
    assert_eq!(st["valid"], true);

    // Break a dep → invalid, with an error naming the unknown upstream.
    ed.set_flow_deps(1, ["ghost"]);
    let bad = ed.state_json();
    assert_eq!(bad["valid"], false);
    assert!(
        bad["errors"].as_array().unwrap().iter().any(|e| e.as_str().unwrap().contains("ghost")),
        "errors should name the unknown dep: {:?}",
        bad["errors"]
    );
}

#[test]
fn empty_editor_renders_cleanly() {
    let ed = SdpEditor::new("empty");
    assert_eq!(ed.state_json()["valid"], true);
    assert!(ed.state_json()["flows"].as_array().unwrap().is_empty());
    let mut ed_ui = ed;
    let mut harness = Harness::new_ui(move |ui| {
        ed_ui.ui(ui);
    });
    harness.run();
    assert!(harness.query_by_label("✎ Edit").is_some());
}