use std::collections::BTreeSet;
use std::process::Command;
use assert_cmd::cargo::CommandCargoExt;
fn generate_pages(dir: &std::path::Path) -> BTreeSet<String> {
let mut cmd = Command::cargo_bin("mk").expect("mk binary");
let out = cmd
.arg("gen-man")
.arg("--out")
.arg(dir)
.output()
.expect("invoke mk gen-man");
assert!(
out.status.success(),
"mk gen-man failed: status={:?} stderr={}",
out.status,
String::from_utf8_lossy(&out.stderr)
);
let mut names = BTreeSet::new();
for entry in std::fs::read_dir(dir).expect("read out dir") {
let entry = entry.expect("dir entry");
let name = entry.file_name().to_string_lossy().into_owned();
if name.ends_with(".1") {
names.insert(name);
}
}
names
}
#[test]
fn gen_man_produces_non_empty_page_set() {
let tmp = tempfile::tempdir().expect("tempdir");
let pages = generate_pages(tmp.path());
assert!(!pages.is_empty(), "expected at least one *.1 page");
}
#[test]
fn every_page_has_a_th_header() {
let tmp = tempfile::tempdir().expect("tempdir");
let pages = generate_pages(tmp.path());
for name in &pages {
let body = std::fs::read_to_string(tmp.path().join(name)).expect("read page");
assert!(!body.is_empty(), "page {name} is empty");
assert!(
body.contains(".TH"),
"page {name} lacks a .TH roff header; head:\n{}",
&body[..body.len().min(200)]
);
}
}
#[test]
fn root_page_exists() {
let tmp = tempfile::tempdir().expect("tempdir");
let pages = generate_pages(tmp.path());
assert!(
pages.contains("mk.1"),
"expected root page mk.1 in {pages:?}"
);
}
#[test]
fn exact_page_set_matches_live_command_tree() {
let tmp = tempfile::tempdir().expect("tempdir");
let produced = generate_pages(tmp.path());
let mut cmd = Command::cargo_bin("mk").expect("mk binary");
let schema_out = cmd.arg("gui-schema").output().expect("invoke gui-schema");
assert!(schema_out.status.success());
let v: serde_json::Value = serde_json::from_slice(&schema_out.stdout).expect("gui-schema JSON");
let subs = v["subcommands"].as_array().expect("subcommands array");
let mut expected: BTreeSet<String> = BTreeSet::new();
expected.insert("mk.1".to_string());
for s in subs {
let n = s["name"].as_str().expect("name string");
expected.insert(format!("mk-{n}.1"));
}
expected.insert("mk-gui-schema.1".to_string());
expected.insert("mk-gen-man.1".to_string());
assert_eq!(
produced, expected,
"produced man-page set does not match the live command tree"
);
}
#[test]
fn no_help_shadow_pages() {
let tmp = tempfile::tempdir().expect("tempdir");
let pages = generate_pages(tmp.path());
for name in &pages {
let stem = name.strip_suffix(".1").unwrap_or(name);
assert!(
stem != "mk-help" && !stem.contains("-help-") && !stem.ends_with("-help"),
"unexpected help shadow page {name:?} — a pre-.build() regression (C-1)"
);
}
}