//! 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() ); }