use super::Harness;
use super::derive::settle;
use crate::boundary::Query;
use crate::boundary::dispatch::Deps;
use crate::boundary::reply::Reply;
use crate::cli_outbound::Cli;
use crate::git_tree::AgentState;
use crate::watch::Mark;
use crate::{AppModel, boundary::answer::queue::QueueRow};
fn queue(model: &AppModel, deps: &Deps) -> Vec<QueueRow> {
let Ok(Reply::Attention(rows)) = model.answer(deps, &Query::Attention, 0) else {
panic!("attention answers attention");
};
rows
}
#[test]
fn a_clean_rest_stirs_the_strip_just_as_a_wounded_one_does() {
let h = Harness::new();
h.write_response(
"c-1",
b"{\"type\":\"finish\",\"reason\":\"stop\"}\n{\"type\":\"end\"}\n",
);
let (_c, mut model) = h.model();
assert_eq!(
model.tree(&h.ws).map(|t| t.agents[0].state),
Some(AgentState::Quiescent),
"a complete response with no wound is a clean rest (§4.4)"
);
assert_eq!(model.strip_total(), 1, "your turn has come (§6 rule 2)");
model.focus_agent(&h.ws, "c-1");
assert_eq!(model.strip_total(), 0, "acked at the tip it rests on");
}
#[test]
fn the_tick_holds_the_focused_agents_acknowledgement() {
let h = Harness::new();
let (clock, mut model) = h.model();
model.focus_agent(&h.ws, "c-1");
assert_eq!(model.strip_total(), 0, "focusing acked the unseen stop");
h.fx.mark_ref("refs/lernie/notify/c-1");
model.dirty_handle().mark_all([(h.ws.clone(), Mark::Watch)]);
settle(&mut model, &clock);
assert!(
model
.focused_agent()
.is_some_and(|a| a.notify_oid.is_some())
);
assert_eq!(
model.strip_total(),
0,
"evidence that arrived while you were looking is already seen"
);
model.focus_workspace(&crate::naming::leaf(&h.ws));
h.fx.mark_ref("refs/lernie/budget-exhausted/c-1");
model.dirty_handle().mark_all([(h.ws.clone(), Mark::Watch)]);
settle(&mut model, &clock);
assert_eq!(
model.strip_total(),
1,
"evidence that arrived while you weren't looking stirs the strip"
);
}
#[test]
fn the_desktop_escalation_reads_the_strip_s_own_queue() {
let h = Harness::new();
h.write_response(
"c-1",
b"{\"type\":\"finish\",\"reason\":\"stop\"}\n{\"type\":\"end\"}\n",
);
let (_c, mut model) = h.model();
assert!(model.notify_unfocused(), "armed by default (§4.1)");
let deps = model.boundary_deps(&Cli::new("/no/lernie"), &Cli::new("/no/bl"));
let alerts = crate::alert::of_queue(&queue(&model, &deps));
assert_eq!(
model.strip_total(),
alerts.len(),
"one alert per thing the strip counts"
);
let one = alerts
.first()
.expect("the resting conversation is announced");
assert_eq!(one.summary, "ws · hello");
assert_eq!(one.body, "came to rest — your turn");
model.focus_agent(&h.ws, "c-1");
assert!(crate::alert::of_queue(&queue(&model, &deps)).is_empty());
}