//! Integration guard for the `aura graph` viewer's DOT generation.
//!
//! The viewer (`assets/graph-viewer.js`) builds the Graphviz DOT in JavaScript,
//! so the property "every node id genDot emits is a valid Graphviz identifier"
//! cannot be checked from Rust directly. This test shells out to `node`, running
//! the headless guard `tests/viewer_dot_ids.mjs`, which loads the real viewer
//! module and asserts the DOT-identifier rule over an inline-expanded nested
//! composite with numeric index keys (the shape `aura graph` emits).
//!
//! Why it matters: a path-joined id like `0__0` begins with a digit but is not a
//! pure numeral, so Graphviz misparses it and collapses the inline-expanded
//! interior onto a single phantom node — the inline-expand render bug. The guard
//! is Graphviz-version-independent (it checks the identifier grammar, not a
//! render).
//!
//! `node` is REQUIRED: if it is not on PATH this test FAILS (a skipped guard is
//! not a guard).

use std::path::PathBuf;
use std::process::Command;

#[test]
fn viewer_emits_valid_dot_node_identifiers() {
    let script = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
        .join("tests")
        .join("viewer_dot_ids.mjs");
    assert!(
        script.exists(),
        "guard script missing at {}",
        script.display()
    );

    let out = match Command::new("node").arg(&script).output() {
        Ok(out) => out,
        Err(e) => panic!(
            "node is required for the viewer DOT-id guard but could not be run \
             ({e}); install Node.js or ensure `node` is on PATH"
        ),
    };

    let stdout = String::from_utf8_lossy(&out.stdout);
    let stderr = String::from_utf8_lossy(&out.stderr);
    assert!(
        out.status.success(),
        "viewer DOT-id guard failed (exit {:?}).\n--- node stdout ---\n{stdout}\n--- node stderr ---\n{stderr}",
        out.status.code()
    );
}
