#![allow(
clippy::disallowed_methods,
clippy::needless_range_loop,
clippy::format_collect,
clippy::format_push_string,
clippy::manual_assert,
clippy::uninlined_format_args,
clippy::unnecessary_debug_formatting,
clippy::unwrap_or_default,
clippy::expect_fun_call,
clippy::manual_repeat_n,
clippy::unnecessary_map_or
)]
use std::process::Command;
fn registered_commands() -> Vec<&'static str> {
#[cfg_attr(not(feature = "code"), allow(unused_mut))]
let mut cmds = vec![
"run",
"serve",
"chat",
"inspect",
"debug",
"validate",
"validate-manifest",
"lint",
"explain",
"tensors",
"trace",
"diff",
"hex",
"tree",
"flow",
"export",
"import",
"convert",
"stamp",
"compile",
"merge",
"quantize",
"rosetta",
"pull",
"list",
"rm",
"registry",
"publish",
"finetune",
"prune",
"distill",
"train",
"pretrain",
"tokenize",
"tune",
"bench",
"eval",
"check",
"qa",
"qualify",
"canary",
"compare-hf",
"parity",
"gpu",
"profile",
"ptx",
"ptx-map",
"cbtop",
"data",
"pipeline",
"tui",
"monitor",
"runs",
"experiment",
"showcase",
"probar",
"diagnose",
"ollama-chat-lint",
"ollama-tools-lint",
"dry-sampling-lint",
"awq-lint",
"fp8-lint",
"nf4-lint",
"gptq-lint",
"oom-lint",
"tool-use-lint",
"gbnf-lint",
"typical-p-lint",
"registry-quota-lint",
"imatrix-lint",
"embeddings-lint",
"unified-search-lint",
"rm-gc-lint",
"shared-cache-lint",
"oracle",
"grad-norm",
"encrypt",
"decrypt",
"mcp",
];
#[cfg(feature = "code")]
cmds.push("code");
cmds
}
fn apr_binary() -> Command {
let mut cmd = Command::new(env!("CARGO_BIN_EXE_apr"));
cmd.env("NO_COLOR", "1");
cmd
}
fn get_help_commands() -> Vec<String> {
let output = apr_binary()
.arg("--help")
.output()
.expect("failed to run apr --help");
let stdout = String::from_utf8_lossy(&output.stdout);
let mut commands = Vec::new();
let mut in_commands = false;
for line in stdout.lines() {
if line.starts_with("Commands:") {
in_commands = true;
continue;
}
if in_commands {
if line.starts_with("Options:") || line.is_empty() && commands.len() > 5 {
break;
}
let trimmed = line.trim();
if let Some(cmd_name) = trimmed.split_whitespace().next() {
if !cmd_name.is_empty()
&& cmd_name
.chars()
.next()
.map_or(false, |c| c.is_ascii_lowercase())
&& !cmd_name.contains('(')
&& !cmd_name.contains(')')
{
commands.push(cmd_name.to_string());
}
}
}
}
commands
}
#[test]
fn test_all_commands_respond_to_help() {
let mut failures = Vec::new();
for cmd in registered_commands() {
let output = apr_binary()
.args([cmd, "--help"])
.output()
.unwrap_or_else(|e| panic!("failed to run apr {} --help: {}", cmd, e));
if !output.status.success() {
failures.push(format!(
"apr {} --help exited with {:?}",
cmd,
output.status.code()
));
}
}
assert!(
failures.is_empty(),
"FALSIFY-CLI-003: Commands that failed --help:\n{}",
failures.join("\n")
);
}
#[test]
fn test_all_contract_commands_exist() {
let help_commands = get_help_commands();
let mut missing = Vec::new();
for cmd in registered_commands() {
if !help_commands.iter().any(|h| h == cmd) {
missing.push(cmd);
}
}
assert!(
missing.is_empty(),
"FALSIFY-CLI-001: Commands in contract but missing from `apr --help`: {:?}",
missing
);
}
#[test]
fn test_no_unregistered_commands() {
let help_commands = get_help_commands();
let cmds = registered_commands();
let registered: std::collections::HashSet<&str> = cmds.iter().copied().collect();
let mut unregistered = Vec::new();
for cmd in &help_commands {
if !registered.contains(cmd.as_str()) {
if cmd != "help" {
unregistered.push(cmd.clone());
}
}
}
assert!(
unregistered.is_empty(),
"FALSIFY-CLI-002: Commands in `apr --help` but not in contract: {:?}\n\
Add them to contracts/apr-cli-commands-v1.yaml AND this test's registered_commands().",
unregistered
);
}
#[test]
fn test_command_count_matches() {
let help_commands = get_help_commands();
let help_count = help_commands
.iter()
.filter(|c| c.as_str() != "help")
.count();
let contract_count = registered_commands().len();
assert_eq!(
help_count, contract_count,
"FALSIFY-CLI-005: Command count mismatch.\n\
`apr --help` has {} commands, contract has {}.\n\
Help commands: {:?}",
help_count, contract_count, help_commands
);
}
#[test]
fn test_version_flag() {
let output = apr_binary()
.arg("--version")
.output()
.expect("failed to run apr --version");
assert!(output.status.success(), "apr --version should exit 0");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("apr"),
"apr --version should contain 'apr': got {:?}",
stdout
);
}
#[test]
fn test_no_args_exits_usage_error() {
let output = apr_binary()
.output()
.expect("failed to run apr with no args");
let code = output.status.code().unwrap_or(-1);
assert_eq!(
code, 2,
"apr with no args should exit 2 (usage error), got {}",
code
);
}
#[test]
fn pretrain_init_flag_registered() {
let output = apr_binary()
.args(["pretrain", "--help"])
.output()
.expect("failed to run apr pretrain --help");
assert!(
output.status.success(),
"apr pretrain --help should exit 0, got {:?}",
output.status.code()
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("--init"),
"FALSIFY-APR-PRETRAIN-INIT-007: `--init` flag missing from `apr pretrain --help`.\n\
Either clap definition drifted, or pretrain subcommand wasn't built with the flag.\n\
Full --help output:\n{}",
stdout
);
}
#[test]
fn tokenize_import_hf_subcommand_registered() {
let output = apr_binary()
.args(["tokenize", "import-hf", "--help"])
.output()
.expect("failed to run apr tokenize import-hf --help");
assert!(
output.status.success(),
"FALSIFY-TOK-IMPORT-HF-001: `apr tokenize import-hf --help` should exit 0, got {:?}\nstderr:\n{}",
output.status.code(),
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout);
for flag in ["--input", "--output", "--include-added-tokens"] {
assert!(
stdout.contains(flag),
"FALSIFY-TOK-IMPORT-HF-001: `{flag}` flag missing from `apr tokenize import-hf --help`.\n\
Either clap definition drifted, dispatch isn't wired, or the binary was built without the subcommand.\n\
Full --help output:\n{stdout}"
);
}
}