use std::env;
use std::path::{Path, PathBuf};
static EXPECTED_PAGES: &[&str] = &[
"git-perf.1",
"git-perf-measure.1",
"git-perf-add.1",
"git-perf-push.1",
"git-perf-pull.1",
"git-perf-report.1",
"git-perf-audit.1",
"git-perf-bump-epoch.1",
"git-perf-remove.1",
"git-perf-prune.1",
];
static EXPECTED_COMMANDS: &[&str] = &[
"git-perf",
"git-perf-measure",
"git-perf-add",
"git-perf-push",
"git-perf-pull",
"git-perf-report",
"git-perf-audit",
"git-perf-bump-epoch",
"git-perf-remove",
"git-perf-prune",
];
fn find_man_dir() -> PathBuf {
let out_dir = env::var("OUT_DIR").unwrap();
let target_dir = Path::new(&out_dir)
.ancestors()
.find(|p| p.file_name().unwrap_or_default() == "target")
.unwrap();
let possible_paths = [
target_dir.parent().unwrap().join("man").join("man1"),
target_dir.join("man").join("man1"),
std::env::current_dir().unwrap().join("man").join("man1"),
std::env::current_dir().unwrap().join("../man").join("man1"),
];
for path in &possible_paths {
if path.exists() {
if let Ok(entries) = std::fs::read_dir(path) {
let mut has_manpages = false;
for entry in entries.flatten() {
if entry.path().extension().is_some_and(|ext| ext == "1") {
has_manpages = true;
break;
}
}
if has_manpages {
return path.clone();
}
}
}
}
possible_paths[0].clone()
}
fn find_docs_dir() -> PathBuf {
let out_dir = env::var("OUT_DIR").unwrap();
let target_dir = Path::new(&out_dir)
.ancestors()
.find(|p| p.file_name().unwrap_or_default() == "target")
.unwrap();
let possible_paths = [
target_dir.parent().unwrap().join("docs"),
std::env::current_dir().unwrap().join("docs"),
std::env::current_dir().unwrap().join("../docs"),
];
for path in &possible_paths {
if path.exists() && path.join("manpage.md").exists() {
return path.clone();
}
}
possible_paths[0].clone()
}
#[test]
fn test_manpage_generation() {
let man_dir = find_man_dir();
if !man_dir.exists() {
panic!(
"Man directory does not exist: {}. This suggests the build script did not run or generated files in a different location. Please ensure 'cargo build' is run before 'cargo test'.",
man_dir.display()
);
}
for page in EXPECTED_PAGES.iter() {
let page_path = &man_dir.join(page);
assert!(
page_path.exists(),
"Missing man page: {}",
page_path.display()
);
let content = std::fs::read_to_string(page_path)
.unwrap_or_else(|_| panic!("Failed to read manpage: {}", page_path.display()));
assert!(
!content.trim().is_empty(),
"Manpage {} is empty",
page_path.display()
);
assert!(
content.contains(".TH"),
"Manpage {} does not contain .TH header",
page_path.display()
);
let command_name = if page.starts_with("git-perf-") {
page.replace("git-perf-", "").replace(".1", "")
} else {
page.replace(".1", "")
};
let full_command_name = page.replace(".1", "");
assert!(
content.contains(&command_name) || content.contains(&full_command_name),
"Manpage {} does not contain command name '{}' or '{}'",
page_path.display(),
command_name,
full_command_name
);
}
println!("All {} manpages found and validated.", EXPECTED_PAGES.len());
}
#[test]
fn test_markdown_generation() {
let docs_dir = find_docs_dir();
let markdown_path = docs_dir.join("manpage.md");
assert!(
markdown_path.exists(),
"Missing markdown documentation: {}",
markdown_path.display()
);
let content = std::fs::read_to_string(&markdown_path).unwrap_or_else(|_| {
panic!(
"Failed to read markdown documentation: {}",
markdown_path.display()
)
});
assert!(
!content.trim().is_empty(),
"Markdown documentation {} is empty",
markdown_path.display()
);
for command in EXPECTED_COMMANDS.iter() {
assert!(
content.contains(command),
"Markdown documentation does not contain command: {}",
command
);
}
println!(
"All {} commands found in markdown documentation.",
EXPECTED_COMMANDS.len()
);
}
#[test]
fn test_manpage_content_validation() {
let man_dir = find_man_dir();
let main_manpage = man_dir.join("git-perf.1");
assert!(main_manpage.exists(), "Main manpage does not exist");
let content = std::fs::read_to_string(&main_manpage).expect("Failed to read main manpage");
let required_sections = [".TH", ".SH NAME", ".SH SYNOPSIS", ".SH DESCRIPTION"];
for section in &required_sections {
assert!(
content.contains(section),
"Main manpage missing required section: {}",
section
);
}
let subcommands = [
"git\\-perf\\-measure(1)",
"git\\-perf\\-add(1)",
"git\\-perf\\-push(1)",
"git\\-perf\\-pull(1)",
"git\\-perf\\-report(1)",
"git\\-perf\\-audit(1)",
];
for subcommand in &subcommands {
assert!(
content.contains(subcommand),
"Main manpage missing subcommand reference: {}",
subcommand
);
}
}
#[test]
fn test_markdown_content_validation() {
let docs_dir = find_docs_dir();
let markdown_path = docs_dir.join("manpage.md");
assert!(
markdown_path.exists(),
"Markdown documentation does not exist"
);
let content =
std::fs::read_to_string(&markdown_path).expect("Failed to read markdown documentation");
let required_sections = ["# Command-Line Help", "## `git-perf`", "**Usage:**"];
for section in &required_sections {
assert!(
content.contains(section),
"Markdown documentation missing required section: {}",
section
);
}
let subcommands = [
"git-perf-measure",
"git-perf-add",
"git-perf-push",
"git-perf-pull",
"git-perf-report",
"git-perf-audit",
];
for subcommand in &subcommands {
assert!(
content.contains(subcommand),
"Markdown documentation missing subcommand reference: {}",
subcommand
);
}
}