use crate::agent_run::{
build_prompt_with_context, format_context_for_prompt, parse_agent_json_response, run_agent,
};
use std::collections::HashMap;
#[test]
fn format_context_for_prompt_empty() {
let ctx: HashMap<String, String> = HashMap::new();
assert_eq!(format_context_for_prompt(&ctx), "");
}
#[test]
fn format_context_for_prompt_includes_keys_sorted() {
let mut ctx: HashMap<String, String> = HashMap::new();
ctx.insert("b".to_string(), "B".to_string());
ctx.insert("a".to_string(), "A".to_string());
let out = format_context_for_prompt(&ctx);
assert!(out.starts_with("Context from previous steps:"));
assert!(out.find("a:\nA").unwrap_or(0) < out.find("b:\nB").unwrap_or(0));
}
#[test]
fn build_prompt_with_context_empty_context_returns_static() {
let ctx: HashMap<String, String> = HashMap::new();
assert_eq!(build_prompt_with_context("Do X.", &ctx), "Do X.");
}
#[test]
fn build_prompt_with_context_prepends_context_block() {
let mut ctx: HashMap<String, String> = HashMap::new();
ctx.insert("task".to_string(), "Implement Y.".to_string());
let out = build_prompt_with_context("Do it.", &ctx);
assert!(out.starts_with("Context from previous steps:"));
assert!(out.contains("Do it."));
assert!(out.contains("Implement Y."));
}
#[test]
fn parse_agent_json_response_success() {
let out =
parse_agent_json_response(r#"{"outcome":"success","context_updates":{"k":"v"}}"#).unwrap();
assert!(matches!(out.status, crate::types::OutcomeStatus::Success));
assert_eq!(out.context_updates.get("k").map(String::as_str), Some("v"));
}
#[test]
fn parse_agent_json_response_fail() {
let out = parse_agent_json_response(r#"{"outcome":"fail","context_updates":{}}"#).unwrap();
assert!(matches!(out.status, crate::types::OutcomeStatus::Error));
}
#[test]
fn parse_agent_json_response_partial_success() {
let out =
parse_agent_json_response(r#"{"outcome":"partial_success","context_updates":{"key":"value"}}"#)
.unwrap();
assert!(matches!(out.status, crate::types::OutcomeStatus::Success));
assert_eq!(
out.context_updates.get("key").map(String::as_str),
Some("value")
);
}
#[test]
fn parse_agent_json_response_invalid_json() {
assert!(parse_agent_json_response("not json").is_err());
}
#[test]
fn parse_agent_json_response_invalid_outcome() {
assert!(parse_agent_json_response(r#"{"outcome":"unknown","context_updates":{}}"#).is_err());
}
#[test]
fn parse_agent_json_response_empty() {
assert!(parse_agent_json_response("").is_err());
assert!(parse_agent_json_response(" ").is_err());
}
#[test]
fn run_agent_returns_parsed_outcome_when_agent_prints_success_json() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("out.json");
std::fs::write(
&path,
r#"{"outcome":"success","context_updates":{"k":"v"}}"#,
)
.unwrap();
let cmd = format!("cat {}", path.display());
let outcome = run_agent(&cmd, "prompt", Some(dir.path()));
assert!(matches!(
outcome.status,
crate::types::OutcomeStatus::Success
));
assert_eq!(
outcome.context_updates.get("k").map(String::as_str),
Some("v")
);
}
#[test]
fn run_agent_returns_error_outcome_when_agent_prints_fail_json() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("out.json");
std::fs::write(&path, r#"{"outcome":"fail","context_updates":{}}"#).unwrap();
let cmd = format!("cat {}", path.display());
let outcome = run_agent(&cmd, "prompt", Some(dir.path()));
assert!(matches!(outcome.status, crate::types::OutcomeStatus::Error));
}
#[test]
fn run_agent_uses_exit_code_when_stdout_empty_and_exit_zero() {
let outcome = run_agent("true", "prompt", None);
assert!(matches!(
outcome.status,
crate::types::OutcomeStatus::Success
));
}
#[test]
fn run_agent_uses_exit_code_when_stdout_empty_and_exit_nonzero() {
let outcome = run_agent("false", "prompt", None);
assert!(matches!(outcome.status, crate::types::OutcomeStatus::Error));
}