use std::process::Command;
fn help_for(args: &[&str]) -> String {
let out = Command::new(env!("CARGO_BIN_EXE_assay"))
.args(args)
.arg("--help")
.output()
.expect("failed to run assay");
format!(
"{}{}",
String::from_utf8_lossy(&out.stdout),
String::from_utf8_lossy(&out.stderr)
)
}
fn option_block(help: &str, flag: &str) -> String {
let lines: Vec<&str> = help.lines().collect();
let start = lines
.iter()
.position(|l| l.contains(flag))
.unwrap_or_else(|| panic!("no {flag} in help"));
let mut block = lines[start].trim().to_string();
for line in &lines[start + 1..] {
let t = line.trim();
if t.is_empty() || t.starts_with('-') {
break;
}
block.push(' ');
block.push_str(t);
}
block
}
const FORMAT_ARGS: &[(&[&str], &str, &[&str])] = &[
(
&["evidence", "lint"],
"--format",
&["json", "sarif", "text"],
),
(&["evidence", "diff"], "--format", &["human", "json"]),
(
&["explain"],
"--format",
&["terminal", "markdown", "html", "json"],
),
(
&["profile", "show"],
"--format",
&["summary", "json", "yaml"],
),
(&["mcp", "discover"], "--format", &["table", "json", "yaml"]),
(&["sandbox"], "--profile-format", &["yaml", "json"]),
(
&["coverage"],
"--format",
&["text", "json", "md", "markdown"],
),
(&["baseline", "report"], "--format", &["json", "md"]),
(&["doctor"], "--format", &["text", "json"]),
];
const HIDDEN_ALIASES: &[(&[&str], &str, &str)] = &[
(&["explain"], "--format", "md"),
(&["coverage"], "--format", "github"),
];
#[test]
fn every_format_argument_advertises_its_accepted_values() {
for (cmd, flag, values) in FORMAT_ARGS {
let help = help_for(cmd);
let line = option_block(&help, flag);
assert!(
line.contains("[possible values:"),
"`assay {} {flag}` accepts any string: {line}",
cmd.join(" "),
);
for v in *values {
assert!(
line.contains(v),
"`assay {} {flag}` no longer accepts `{v}`: {line}",
cmd.join(" "),
);
}
}
}
const NO_SHARED_DEFAULT: &[(&[&str], &str, &str)] = &[(
&["coverage"],
"--format",
"coverage_applies_its_own_default_in_each_mode",
)];
#[test]
fn every_default_is_an_accepted_value() {
for (cmd, flag, values) in FORMAT_ARGS {
if NO_SHARED_DEFAULT
.iter()
.any(|(c, f, _)| c == cmd && f == flag)
{
continue;
}
let help = help_for(cmd);
let line = option_block(&help, flag);
let default = line
.split("[default: ")
.nth(1)
.and_then(|s| s.split(']').next())
.unwrap_or_else(|| panic!("`assay {} {flag}` has no default", cmd.join(" ")));
assert!(
values.contains(&default),
"`assay {} {flag}` defaults to `{default}`, which is not in its own accepted set {values:?}",
cmd.join(" "),
);
}
}
#[test]
fn every_listed_exception_names_a_live_test() {
let source = include_str!("format_value_parser.rs");
for (cmd, flag, test_name) in NO_SHARED_DEFAULT {
assert!(
source.contains(&format!("fn {test_name}(")),
"`assay {} {flag}` is skipped in favour of `{test_name}`, which is not in this file",
cmd.join(" "),
);
}
}
#[test]
fn coverage_applies_its_own_default_in_each_mode() {
let dir = tempfile::tempdir().expect("tempdir");
let trace = dir.path().join("t.jsonl");
std::fs::write(&trace, "{\"tool\":\"read\",\"args\":{}}\n").expect("write trace");
let out = dir.path().join("c.json");
let status = Command::new(env!("CARGO_BIN_EXE_assay"))
.args(["coverage", "--input"])
.arg(&trace)
.arg("--out")
.arg(&out)
.args(["--declared-tool", "read"])
.output()
.expect("failed to run assay");
assert!(
status.status.success(),
"`coverage --input` with no --format failed: {}",
String::from_utf8_lossy(&status.stderr)
);
let written = std::fs::read_to_string(&out).expect("read report");
serde_json::from_str::<serde_json::Value>(&written)
.expect("`--input` mode's default did not produce JSON");
let policy = dir.path().join("p.yaml");
std::fs::write(&policy, "version: 1\ntools:\n allow: [\"read\"]\n").expect("write policy");
let legacy_trace = dir.path().join("tr.jsonl");
std::fs::write(&legacy_trace, "{\"tool_calls\":[{\"name\":\"read\"}]}\n").expect("write trace");
let legacy = Command::new(env!("CARGO_BIN_EXE_assay"))
.args(["coverage", "--policy"])
.arg(&policy)
.arg("--trace-file")
.arg(&legacy_trace)
.output()
.expect("failed to run assay");
let stdout = String::from_utf8_lossy(&legacy.stdout);
assert!(
stdout.contains("Coverage Report"),
"legacy mode's default did not produce the text report: {stdout}"
);
assert!(
serde_json::from_str::<serde_json::Value>(&stdout).is_err(),
"legacy mode's default produced JSON: {stdout}"
);
}
#[test]
fn neither_coverage_mode_accepts_the_others_default() {
let dir = tempfile::tempdir().expect("tempdir");
let trace = dir.path().join("t.jsonl");
std::fs::write(&trace, "{\"tool\":\"read\",\"args\":{}}\n").expect("write trace");
let out = dir.path().join("c.json");
let rejected = Command::new(env!("CARGO_BIN_EXE_assay"))
.args(["coverage", "--input"])
.arg(&trace)
.arg("--out")
.arg(&out)
.args(["--declared-tool", "read", "--format", "text"])
.output()
.expect("failed to run assay");
let stderr = String::from_utf8_lossy(&rejected.stderr);
assert!(
!rejected.status.success(),
"`--input --format text` succeeded; it used to write JSON and say nothing"
);
assert!(
stderr.contains("--format text"),
"the refusal does not name the spelling it refused: {stderr}"
);
assert!(
!out.exists(),
"a refused --format still wrote an artifact at {}",
out.display()
);
let policy = dir.path().join("p.yaml");
std::fs::write(&policy, "version: 1\ntools:\n allow: [\"read\"]\n").expect("write policy");
let legacy_trace = dir.path().join("tr.jsonl");
std::fs::write(&legacy_trace, "{\"tool_calls\":[{\"name\":\"read\"}]}\n").expect("write trace");
let legacy = Command::new(env!("CARGO_BIN_EXE_assay"))
.args(["coverage", "--policy"])
.arg(&policy)
.arg("--trace-file")
.arg(&legacy_trace)
.args(["--format", "md"])
.output()
.expect("failed to run assay");
assert!(
!legacy.status.success(),
"legacy `--format md` succeeded; it is the other mode's spelling"
);
assert!(
String::from_utf8_lossy(&legacy.stderr).contains("--format md"),
"the refusal does not name the spelling it refused"
);
}
#[test]
fn an_unrecognized_format_is_rejected_rather_than_reinterpreted() {
let out = Command::new(env!("CARGO_BIN_EXE_assay"))
.args(["evidence", "lint", "/dev/null", "--format", "jsonn"])
.output()
.expect("failed to run assay");
assert!(
!out.status.success(),
"a typo'd --format exited successfully",
);
assert!(
out.stdout.is_empty(),
"rejected run still wrote to stdout, which is where the artifact would go",
);
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(
stderr.contains("invalid value 'jsonn'") && stderr.contains("possible values"),
"the error does not name the value or the accepted set: {stderr}",
);
}
#[test]
fn an_alias_is_accepted_without_being_advertised() {
for (cmd, flag, alias) in HIDDEN_ALIASES {
let out = Command::new(env!("CARGO_BIN_EXE_assay"))
.args(*cmd)
.args([*flag, *alias])
.output()
.expect("failed to run assay");
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(
!stderr.contains("invalid value"),
"`assay {} {flag} {alias}`: the alias was dropped rather than hidden: {stderr}",
cmd.join(" "),
);
let line = option_block(&help_for(cmd), flag);
assert!(
!line.contains(&format!("{alias},")) && !line.contains(&format!("{alias}]")),
"`assay {} {flag}` advertises `{alias}`, so it is a value and not a hidden alias: {line}",
cmd.join(" "),
);
}
}