use crate::agent::loop_commands::shell_arg;
pub(crate) fn receipt_write_command(
canonical_gap_id: &str,
verify_command: &str,
out_path: Option<&str>,
) -> String {
let base = format!(
"ripr receipt write --gap {} --verify-command {} --status not_run",
shell_arg(canonical_gap_id),
shell_arg(verify_command),
);
match out_path {
Some(path) => format!("{base} --out {}", shell_arg(path)),
None => base,
}
}
#[cfg(test)]
mod tests {
use super::receipt_write_command;
#[test]
fn receipt_write_command_emits_canonical_form_with_out_path() {
assert_eq!(
receipt_write_command(
"gap:rust:pricing:discount:threshold-boundary",
"cargo xtask fixtures boundary_gap",
Some("target/ripr/receipts/gap-rust-pricing.json"),
),
"ripr receipt write --gap gap:rust:pricing:discount:threshold-boundary --verify-command \"cargo xtask fixtures boundary_gap\" --status not_run --out target/ripr/receipts/gap-rust-pricing.json"
);
}
#[test]
fn receipt_write_command_emits_canonical_form_without_out_path() {
assert_eq!(
receipt_write_command(
"gap:rust:pricing:discount:threshold-boundary",
"cargo xtask fixtures boundary_gap",
None,
),
"ripr receipt write --gap gap:rust:pricing:discount:threshold-boundary --verify-command \"cargo xtask fixtures boundary_gap\" --status not_run"
);
}
#[test]
fn receipt_write_command_quotes_gap_id_with_special_chars() {
let cmd = receipt_write_command(
"gap:python:app/pricing.py:calculate_discount:predicate_boundary:amount>=threshold",
"pytest tests/test_pricing.py::test_smoke",
Some("target/ripr/receipts/gap.json"),
);
assert!(
cmd.starts_with("ripr receipt write --gap "),
"command must start with ripr receipt write --gap, got: {cmd}"
);
assert!(
!cmd.contains("ripr outcome"),
"receipt_write_command must never emit ripr outcome, got: {cmd}"
);
}
#[test]
fn receipt_write_command_status_is_always_not_run() {
let cmd = receipt_write_command("gap:rust:some:gap", "cargo test -p ripr", None);
assert!(
cmd.contains("--status not_run"),
"synthesized receipt command must use --status not_run, got: {cmd}"
);
}
}