crates/holger-ui-recipe/tests/ui_row_equals_cargo_install.rs
//! **The `holger-ui` row is `cargo install --path crates/holger-ui`** (lane HOL-PRODUCTS:
//! each of Holger's four products is one crate, and its Build Thing row produces exactly
//! what the matching `cargo install` produces).
//!
//! holger-ui's product is its program: the console bundle's host and the same-origin
//! pass-through to holger. `cargo install` of it builds the host target, the release
//! profile, no feature; so does the row. The tree guard holds the row to a crate bound and
//! to crates it must never link: no outbound client beyond its own pass-through to the
//! configured holger, nothing sold, no public site (opt-in), no wasm host.
use std::collections::BTreeSet;
use std::process::Command;
use holger_ui_recipe::{declared, repo_root};
/// The `cargo install` line, run at the repository root, and what the row shows.
pub const UI_INSTALL: &str = "cargo install --locked --path crates/holger-ui";
/// Distinct crates of `cargo tree -p holger-ui -e normal` (measured on builder-64 2026-10-26
/// as the server crate's), and the bound that leaves room for a few.
const UI_CRATES_BOUND: usize = 130;
const FORBIDDEN: &[&str] = &[
"reqwest", "ureq", "hyper-rustls", "isahc", "curl", "attohttpc", "surf", "instant-acme", "hyper-tls", "native-tls", "openssl",
"monetize*", "holger-public-site", "wasmtime*", "nordisk-estate-svg",
];
/// Pure: the parts of a cargo argv that decide the binary, as `flag value` words.
fn point(args: &[String]) -> BTreeSet<String> {
let mut out = BTreeSet::new();
let mut it = args.iter();
while let Some(a) = it.next() {
match a.as_str() {
"build" | "install" | "--locked" => {}
"--path" => {
let dir = it.next().unwrap();
assert_eq!(dir, "crates/holger-ui", "the one path this test knows");
out.insert("-p holger-ui".into());
}
"--profile" => {
out.insert(format!("--profile {}", it.next().unwrap()));
}
"-p" | "--bin" | "--features" | "--target" => {
out.insert(format!("{a} {}", it.next().unwrap()));
}
other => {
out.insert(other.to_string());
}
}
}
out
}
fn install_point() -> BTreeSet<String> {
let words: Vec<String> = UI_INSTALL.split_whitespace().skip(1).map(String::from).collect();
let mut p = point(&words);
// `cargo install` builds the release profile, and the package's one bin.
p.insert("--profile release".into());
p.insert("--bin holger-ui".into());
p
}
#[test]
fn the_ui_row_is_declared() {
let set = declared();
let v = set.get("holger-ui").expect("the product `holger-ui` is a Build Thing row");
// This repository's one delivery: a bare `cargo xtask build` (holger's fast, the release
// door) must keep building without a `--suite`.
assert_eq!(v.suites, ["MVP"]);
assert_eq!(set.suites(), ["MVP"], "holger-ui ships one delivery");
assert!(!v.is_default, "(MVP, server)'s normal case stays mvp-ui");
}
#[test]
fn the_ui_row_builds_what_cargo_install_builds() {
let set = declared();
let v = set.get("holger-ui").expect("no `holger-ui` row");
let row = point(&v.cargo_args());
let install = install_point();
let only_row: Vec<&String> = row.difference(&install).collect();
let only_install: Vec<&String> = install.difference(&row).collect();
assert!(only_row.is_empty() && only_install.is_empty(), "the `holger-ui` row is not `{UI_INSTALL}`: only the row {only_row:?}, only the install {only_install:?}");
}
#[test]
fn the_product_package_has_one_bin_so_the_install_builds_only_it() {
let m = std::fs::read_to_string(repo_root().join("crates/holger-ui/Cargo.toml")).unwrap();
assert_eq!(m.matches("[[bin]]").count(), 1, "a second bin would make the install line build more than the row");
assert!(repo_root().join("crates/holger-ui/src/main.rs").is_file());
}
#[test]
fn the_ui_row_stays_slim_and_links_no_outbound_client() {
let out = Command::new(env!("CARGO"))
.current_dir(repo_root())
.args(["tree", "-p", "holger-ui", "-e", "normal", "--prefix", "none"])
.output()
.expect("cargo tree");
assert!(out.status.success(), "{}", String::from_utf8_lossy(&out.stderr));
let tree = String::from_utf8_lossy(&out.stdout);
let crates: BTreeSet<&str> = tree.lines().map(|l| l.trim_end_matches(" (*)").trim()).filter(|l| !l.is_empty()).collect();
assert!(crates.len() > 30, "an empty tree proves nothing:\n{tree}");
println!("row holger-ui: {} crates (bound {UI_CRATES_BOUND})", crates.len());
assert!(crates.len() <= UI_CRATES_BOUND, "the `holger-ui` row links {} crates, over its bound {UI_CRATES_BOUND}", crates.len());
let names: BTreeSet<&str> = crates.iter().filter_map(|l| l.split_whitespace().next()).collect();
let hits: Vec<&str> = FORBIDDEN
.iter()
.flat_map(|f| match f.strip_suffix('*') {
Some(p) => names.iter().copied().filter(|n| n.starts_with(p)).collect::<Vec<_>>(),
None => names.iter().copied().filter(|n| n == f).collect(),
})
.collect();
assert!(hits.is_empty(), "the `holger-ui` row links {hits:?}");
}
#[test]
fn the_readme_gives_the_install_line() {
let readme = std::fs::read_to_string(repo_root().join("README.md")).unwrap();
assert!(readme.contains(UI_INSTALL), "README.md does not give `{UI_INSTALL}`");
}
#[test]
fn a_differing_feature_is_seen() {
let a = point(&["build".into(), "-p".into(), "x".into(), "--features".into(), "metered".into()]);
let b = point(&["build".into(), "-p".into(), "x".into()]);
assert_ne!(a, b);
}