dwarves-gui/tests/logo_asset_parity.rs
//! **The About logo really is inside this package — and really is the repo's logo.**
//!
//! `build.rs` transcodes `assets/dwarves.webp` into a PNG in `OUT_DIR`, and `src/about.rs`
//! `include_bytes!`es that PNG. Until 2026-08-24 the build script read
//! `../assets/dwarves.webp` — the dwarves repo's shared asset dir, one level ABOVE this
//! package root. That works in a checkout and cannot work from crates.io: `cargo package`
//! tarballs only files under the package root, so `../assets/` is not in the published
//! crate and the build script's (deliberately loud) `panic!` fired for every consumer:
//!
//! > `dwarves-gui build: could not decode ../assets/dwarves.webp as an image: …`
//!
//! The fix is a second copy of the 90 KB webp inside `dwarves-gui/assets/`. That copy is
//! what this file guards, in the two independent ways it can go wrong:
//!
//! 1. **It vanishes.** Then the published crate is unbuildable again — the exact defect
//! the copy was made to fix, silently reintroduced.
//! 2. **It drifts.** The artist updates `assets/dwarves.webp` for the README and the UI
//! keeps shipping last month's logo, with nothing anywhere saying so.
//!
//! On the SKIP: check (2) needs the repo-root copy, which by construction is absent from a
//! published tarball. So it is gated on a REPO MARKER (`../.nornir/build-variants.toml`,
//! the file the build receipt keys on) rather than on the asset's own absence. That
//! distinction is the difference between a guard that knows when it does not apply and a
//! guard that reports green because its input disappeared — this repo has been bitten by
//! the second kind (`8edaa23`: four CI guards green because a `#` was in front of them),
//! so the marker is checked FIRST and a marker with no asset beside it is a FAILURE.
use std::path::PathBuf;
fn crate_dir() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
}
/// The copy `build.rs` actually reads — must be inside the package root.
fn packaged_logo() -> PathBuf {
crate_dir().join("assets/dwarves.webp")
}
/// The repo-root copy `README.md` renders. Absent in a published tarball.
fn repo_logo() -> PathBuf {
crate_dir().join("../assets/dwarves.webp")
}
/// The marker that says "we are in the nordisk checkout, not a registry tarball".
fn repo_marker() -> PathBuf {
crate_dir().join("../.nornir/build-variants.toml")
}
/// THE PUBLISH CONTRACT: the logo is under the package root. This must hold everywhere —
/// checkout and published tarball alike — because `build.rs` panics without it.
#[test]
fn the_logo_is_inside_this_package_root() {
let p = packaged_logo();
assert!(
p.is_file(),
"{} is missing.\n`build.rs` reads `assets/dwarves.webp` relative to this \
manifest and PANICS if it cannot decode it, so without this file the published \
crate cannot build at all — and `cargo package` cannot reach outside the \
package root to find the repo-root copy.",
p.display()
);
let bytes = std::fs::read(&p).unwrap_or_else(|e| panic!("read {}: {e}", p.display()));
assert!(
!bytes.is_empty(),
"{} is EMPTY — an unreadable image is the same broken build as a missing one",
p.display()
);
// RIFF/WEBP magic: "RIFF" .... "WEBP". A truncated or wrong-format file would sail
// past a size check and die in `image::open` at build time instead.
assert!(
bytes.len() > 12 && &bytes[0..4] == b"RIFF" && &bytes[8..12] == b"WEBP",
"{} is not a WebP file (first 12 bytes: {:?}) — `build.rs` decodes it with an \
`image` build whose only enabled codecs are webp + png",
p.display(),
&bytes[..bytes.len().min(12)]
);
eprintln!(
"logo asset: {} present, {} bytes, WebP magic ok",
p.display(),
bytes.len()
);
}
/// THE DRIFT CONTRACT: the packaged copy is the repo's logo, not a fork of it.
///
/// Gated on the repo marker, never on the asset's absence — see the module docs.
#[test]
fn the_packaged_logo_matches_the_repo_root_logo() {
let marker = repo_marker();
if !marker.is_file() {
// No recipe ⇒ no checkout ⇒ there is no repo-root copy to compare against, and
// that is a fact about WHERE we are, not a defect. `the_logo_is_inside_this_
// package_root` above still runs and still carries the publish contract.
eprintln!(
"logo asset: no repo marker at {} — published-crate layout, drift check does \
not apply here (the package-root check above still ran)",
marker.display()
);
return;
}
// The marker IS there, so we are in the checkout and BOTH copies must be.
let (packaged, repo) = (packaged_logo(), repo_logo());
assert!(
repo.is_file(),
"the repo marker {} exists, so this is the nordisk checkout — but {} does not. \
Either the shared asset was deleted (README.md renders it) or the layout moved; \
a guard whose input silently vanished must go RED, not quietly pass.",
marker.display(),
repo.display()
);
assert!(packaged.is_file(), "{} is missing", packaged.display());
let a = std::fs::read(&repo).unwrap_or_else(|e| panic!("read {}: {e}", repo.display()));
let b = std::fs::read(&packaged).unwrap_or_else(|e| panic!("read {}: {e}", packaged.display()));
assert!(
!a.is_empty(),
"{} is EMPTY — this guard would then compare nothing to nothing",
repo.display()
);
assert!(
a == b,
"the packaged logo has DRIFTED from the repo's.\n {} = {} bytes\n {} = {} \
bytes\nThey must be identical: the second copy exists ONLY so the file lands \
inside the published tarball, so a difference means the shipped About box is \
rendering a logo the repo no longer has. Re-copy the repo-root asset over the \
packaged one.",
repo.display(),
a.len(),
packaged.display(),
b.len()
);
eprintln!(
"logo asset: packaged copy is byte-identical to the repo asset ({} bytes)",
a.len()
);
}
/// `build.rs` must read the asset from INSIDE the package. A guard on the bytes is worth
/// nothing if the build script has quietly gone back to reaching over the package
/// boundary — that reintroduces the original defect while both copies sit there agreeing.
#[test]
fn the_build_script_reads_the_packaged_copy_not_the_repo_copy() {
let bs = crate_dir().join("build.rs");
let src = std::fs::read_to_string(&bs).unwrap_or_else(|e| panic!("read {}: {e}", bs.display()));
// Only the CODE lines matter; the comments deliberately quote the old broken path to
// record what went wrong, so a naive substring search over the whole file would find
// `../assets/dwarves.webp` in the explanation and report a false red.
let code: Vec<&str> = src
.lines()
.map(|l| l.split("//").next().unwrap_or(""))
.filter(|l| !l.trim().is_empty())
.collect();
assert!(
!code.is_empty(),
"build.rs parsed to zero code lines — the filter is broken"
);
let offenders: Vec<&&str> = code
.iter()
.filter(|l| l.contains("../assets/dwarves.webp"))
.collect();
assert!(
offenders.is_empty(),
"build.rs reads the logo from OUTSIDE the package root again:\n {}\n`cargo \
package` will not carry `../assets/`, so the published crate goes back to \
panicking in its build script. Read `assets/dwarves.webp` instead.",
offenders
.iter()
.map(|l| l.trim())
.collect::<Vec<_>>()
.join("\n ")
);
assert!(
code.iter().any(|l| l.contains("\"assets/dwarves.webp\"")),
"build.rs no longer names `assets/dwarves.webp` at all — this guard has lost its \
subject and must not pass by finding nothing to object to"
);
eprintln!(
"logo asset: build.rs reads the package-root copy ({} code lines scanned)",
code.len()
);
}