use crate::runner::{BinaryRunner, HelpOutput, RunResult};
pub(crate) const BAD_FLAG: &str = "--this-flag-does-not-exist-anc";
pub(crate) fn probe_bad_invocation(runner: &BinaryRunner) -> RunResult {
runner.run(&[BAD_FLAG], &[])
}
pub(crate) fn probe_bad_invocation_json(runner: &BinaryRunner) -> RunResult {
runner.run(&[BAD_FLAG, "--output", "json"], &[])
}
pub(crate) fn probe_help_json(runner: &BinaryRunner) -> RunResult {
runner.run(&["--help", "--output", "json"], &[])
}
pub(crate) fn advertises_json_output(help: &HelpOutput) -> bool {
let raw = help.raw().to_lowercase();
raw.contains("--output") && (raw.contains("json") || raw.contains("jsonl"))
}
pub(crate) fn parse_error_envelope(
result: &RunResult,
) -> Option<(serde_json::Value, &'static str)> {
if !result.stderr.trim().is_empty()
&& let Ok(v) = serde_json::from_str::<serde_json::Value>(result.stderr.trim())
{
return Some((v, "stderr"));
}
if !result.stdout.trim().is_empty()
&& let Ok(v) = serde_json::from_str::<serde_json::Value>(result.stdout.trim())
{
return Some((v, "stdout"));
}
None
}
#[cfg(test)]
mod tests {
use super::*;
use crate::runner::HelpOutput;
#[test]
fn advertises_json_when_output_and_json_present() {
let help = HelpOutput::from_raw(
"Options:\n --output <FMT> Output format [possible values: text, json]\n",
);
assert!(advertises_json_output(&help));
}
#[test]
fn advertises_json_when_jsonl_mentioned() {
let help = HelpOutput::from_raw("Options:\n --output <FMT> text, json, jsonl\n");
assert!(advertises_json_output(&help));
}
#[test]
fn does_not_advertise_when_output_missing() {
let help = HelpOutput::from_raw("Options:\n --format <FMT> output as json\n");
assert!(!advertises_json_output(&help));
}
#[test]
fn does_not_advertise_when_json_missing() {
let help = HelpOutput::from_raw("Options:\n --output <FMT> Output format\n");
assert!(!advertises_json_output(&help));
}
#[test]
fn bad_flag_constant_is_long_form() {
assert!(BAD_FLAG.starts_with("--"));
assert!(BAD_FLAG.len() > 5);
}
}