Verify it yourself
Everything on the Fidelity page comes from commands you can run in a clone of the repository. Most of them need only Rust: C’s outputs are committed, as hashes or as goldens.
The checks
Section titled “The checks”cargo test --workspace # every ratchet, both kinds of checkcargo run --release -p graphviz-pure-diff -- e2e --list # full-SVG identity, list differencescargo run --release -p graphviz-pure-diff -- --filter clust --worst 20 # layout geometry, a subsetcargo run --release -p graphviz-pure-diff -- render # renderers on C's own layoutscargo run --release -p graphviz-pure-diff -- structure # same nodes, edges and labels as C, on canvasnode scripts/wasm-e2e.mjs --pkg <wasm-bindgen nodejs output> # the same check under WASMscripts/update-baselines.sh [--portable] # after an improvementcargo test --workspace runs the corpus checks as ratchets (crates/graphviz-pure-diff/tests/*_fidelity.rs): each one fails if a file listed in its baseline stops matching. The profile is chosen by the build: macOS uses Apple’s libm and the *.json baselines; Linux, WASM, or macOS with --features graphviz-pure-core/portable-math use the portable math library and the *.portable.json baselines.
To see the portable profile on a Mac:
cargo build --release -p graphviz-pure-diff --features graphviz-pure-core/portable-math --target-dir target/portabletarget/portable/release/gv-diff e2eThe WASM build
Section titled “The WASM build”The browser checks on this site run the same build as the npm package. To check it against the whole corpus in Node:
cargo build --release --target wasm32-unknown-unknown -p graphviz-pure-wasmwasm-bindgen --target nodejs --out-dir /tmp/gvwasm/pkg \ target/wasm32-unknown-unknown/release/graphviz_pure_wasm.wasmnode scripts/wasm-e2e.mjs --pkg /tmp/gvwasm/pkg --hashes /tmp/wasm-hashes.jsoncargo build --release -p graphviz-pure-diff && target/release/gv-diff e2e --hashes /tmp/native-hashes.jsoncmp /tmp/native-hashes.json /tmp/wasm-hashes.json # on Linux: WASM and native agree on every filewasm-bindgen-cli must match the wasm-bindgen version in Cargo.lock exactly; CI reads it from there.
The C reference
Section titled “The C reference”The reference is Graphviz 16.1.0 with only three of its plugins loaded: core, dot layout and neato layout. With no Pango text-layout plugin available, C measures text with the built-in font metric tables in lib/common/textspan_lut.c, which is what the port does. A default Graphviz installation measures text with Pango and cairo, places labels differently, and matches neither build.
scripts/gen-golden.sh builds such a plugin directory from an installed Graphviz 16.1.0 (Homebrew’s by default) and points GVBINDIR at it:
mkdir -p ~/src/gv-ref/lutpluginscp /opt/homebrew/lib/graphviz/libgvplugin_{core,dot_layout,neato_layout}.*dylib ~/src/gv-ref/lutplugins/GVBINDIR=~/src/gv-ref/lutplugins dot -c # writes the plugin configGVBINDIR=~/src/gv-ref/lutplugins dot -V # dot - graphviz version 16.1.0Then compare one file yourself. Pass files as arguments, not on stdin, as every check does:
cargo build --release -p graphviz-pure-cliGVBINDIR=~/src/gv-ref/lutplugins dot -Kneato -Tsvg graph.gv | grep -v '^<!-- Generated by ' > c.svgtarget/release/graphviz-pure -Kneato -Tsvg graph.gv | grep -v '^<!-- Generated by ' > rust.svgcmp c.svg rust.svg && echo identicalThe grep drops the generator comment, the one line gv-diff ignores (normalize in crates/graphviz-pure-diff/src/e2e.rs). Regenerating the references takes the same setup: scripts/gen-golden.sh, scripts/gen-render-golden.sh and GVBINDIR=<plugin dir> gv-diff e2e --generate.
C’s output for some inputs is not stable: it depends on heap addresses, or C reads freed memory. gv-diff e2e --generate runs C twice and records those inputs as unstable; they are skipped, and listed on the Fidelity page.
Where the goldens live
Section titled “Where the goldens live”| Path | What it holds | Used by |
|---|---|---|
tests/wild, tests/fixtures, tests/<engine>/, tests/render |
The inputs (.gv) of the nine corpora |
every check |
tests/golden/e2e.json |
64-bit FNV-1a hashes of C’s normalised -Tsvg, and the unstable list |
gv-diff e2e |
tests/golden/e2e-baseline{,.portable}.json |
The files that match, per profile | e2e ratchet |
tests/golden/*.dot, tests/golden/<engine>/*.dot |
C’s -Tdot layouts |
layout check |
tests/golden/*baseline{,.portable}.json |
Per-file element counts and errors, per profile | layout ratchets |
tests/golden/render/ |
C’s layouts (laid/) and its renderings in seven formats |
gv-diff render |
The render goldens are moving into a compressed archive, tests/golden/render.tar.xz, which the harness unpacks before comparing; the baselines stay as JSON.
This site’s data
Section titled “This site’s data”The site is built from the same files:
python3 -I scripts/site-data.py --measure # runs gv-diff e2e in both profiles -> site/src/data/fidelity.jsonscripts/site-samples.sh # needs the C reference -> site/public/samples, samples.jsonnode scripts/site-issues.mjs # docs/issues/manifest.json -> What's leftnode scripts/site-sync-docs.mjs # docs/porting/*.md -> Porting notesscripts/site-wasm.sh # the WASM build for the live checksWithout --measure, site-data.py counts the committed baselines instead of re-running the check. The generated JSON is committed, so the site builds in CI without the C reference.