use crate::brain::tools::bash::{RECENT_BASH_WINDOW, check_recent_failure, record_bash_outcome};
use uuid::Uuid;
#[test]
fn fresh_session_has_no_history() {
let sid = Uuid::new_v4();
assert!(check_recent_failure(sid, "ls -la").is_none());
}
#[test]
fn successful_run_does_not_block_retry() {
let sid = Uuid::new_v4();
record_bash_outcome(sid, "git status".to_string(), false, None);
assert!(check_recent_failure(sid, "git status").is_none());
}
#[test]
fn failed_run_blocks_exact_retry() {
let sid = Uuid::new_v4();
record_bash_outcome(
sid,
"git push origin main".to_string(),
true,
Some("rejected: non-fast-forward".to_string()),
);
let msg = check_recent_failure(sid, "git push origin main").expect("should block");
assert!(msg.contains("already ran this exact command"));
assert!(msg.contains("Previous error:"));
assert!(msg.contains("non-fast-forward"));
}
#[test]
fn whitespace_normalization_catches_cosmetic_retries() {
let sid = Uuid::new_v4();
record_bash_outcome(
sid,
"git pull".to_string(),
true,
Some("conflict".to_string()),
);
assert!(check_recent_failure(sid, " git pull ").is_some());
}
#[test]
fn different_command_is_not_blocked() {
let sid = Uuid::new_v4();
record_bash_outcome(sid, "git push origin main".to_string(), true, None);
assert!(check_recent_failure(sid, "git push origin main --force-with-lease").is_none());
assert!(check_recent_failure(sid, "git push origin foo").is_none());
}
#[test]
fn move_to_front_keeps_one_entry_per_unique_command() {
let sid = Uuid::new_v4();
record_bash_outcome(sid, "cmd_a".to_string(), true, Some("err1".to_string()));
record_bash_outcome(sid, "cmd_b".to_string(), false, None);
record_bash_outcome(sid, "cmd_a".to_string(), true, Some("err2".to_string()));
let msg = check_recent_failure(sid, "cmd_a").expect("should block");
assert!(msg.contains("err2"));
assert!(!msg.contains("err1"));
}
#[test]
fn outcome_can_flip_from_fail_to_success() {
let sid = Uuid::new_v4();
record_bash_outcome(sid, "make build".to_string(), true, Some("err".to_string()));
assert!(check_recent_failure(sid, "make build").is_some());
record_bash_outcome(sid, "make build".to_string(), false, None);
assert!(check_recent_failure(sid, "make build").is_none());
}
#[test]
fn old_failure_falls_off_window() {
let sid = Uuid::new_v4();
record_bash_outcome(
sid,
"old_failing_cmd".to_string(),
true,
Some("err".to_string()),
);
for i in 0..RECENT_BASH_WINDOW {
record_bash_outcome(sid, format!("filler_cmd_{}", i), false, None);
}
assert!(check_recent_failure(sid, "old_failing_cmd").is_none());
}
#[test]
fn sessions_are_isolated() {
let sid_a = Uuid::new_v4();
let sid_b = Uuid::new_v4();
record_bash_outcome(
sid_a,
"broken_cmd".to_string(),
true,
Some("err".to_string()),
);
assert!(check_recent_failure(sid_a, "broken_cmd").is_some());
assert!(check_recent_failure(sid_b, "broken_cmd").is_none());
}
#[test]
fn rejection_message_names_the_window_size() {
let sid = Uuid::new_v4();
record_bash_outcome(sid, "x".to_string(), true, None);
let msg = check_recent_failure(sid, "x").expect("should block");
assert!(msg.contains(&RECENT_BASH_WINDOW.to_string()));
}
#[test]
fn rejection_message_carries_the_shared_variation_directive() {
let sid = Uuid::new_v4();
record_bash_outcome(
sid,
"oc-deploy ship --sha abc123".to_string(),
true,
Some("already shipped by sibling lane".to_string()),
);
let msg = check_recent_failure(sid, "oc-deploy ship --sha abc123").expect("should block");
assert!(msg.contains("Do not re-issue the same call"), "{msg}");
assert!(msg.contains("result you already have"), "{msg}");
assert!(msg.contains("report completion"), "{msg}");
assert!(msg.contains("already ran this exact command"), "{msg}");
assert!(msg.contains("Previous error:"), "{msg}");
}