use super::{Model, Notice};
use crate::reply::{Outcome, Read, Reply};
use crate::test_support::window::{own, seated, seen};
use crate::ui::theme;
fn ran(exit: i32, stdout: &str, stderr: &str) -> Read {
Read::Answer(Reply::Outcome(Outcome {
exit,
stdout: stdout.to_owned(),
stderr: stderr.to_owned(),
}))
}
#[test]
fn a_receipt_replaces_the_notice_and_never_clears_it() {
let mut model = Model {
notice: Some(Notice::Refused("stale".to_owned())),
..Model::default()
};
let flat = own().channel;
for (reply, said) in [
(Reply::Nudged, "nudged — the advance is running"),
(Reply::Flagged, "flagged — it is on the queue now"),
(Reply::Acked, "the trail's watermark is where you are"),
(Reply::TrailCleared, "the trail is truncated"),
] {
model.absorb(&flat, Read::Answer(reply));
assert_eq!(model.notice, Some(Notice::Said(said.to_owned())));
}
model.absorb(&flat, ran(1, "", "the gate said no"));
assert_eq!(
model.notice,
Some(Notice::Refused("the gate said no".to_owned()))
);
model.absorb(&flat, ran(0, "", ""));
assert_eq!(model.notice, Some(Notice::Said("ok".to_owned())));
}
#[test]
fn a_successful_run_paints_its_own_sentence_in_the_annotation_ink() {
let mut model = seated();
model.absorb(
&own().channel,
ran(
0,
"litany: config/default already governs — nothing to retarget\n",
"",
),
);
let window = crate::paint_probe::frame::Window::new();
let shown = seen(&window, |ctx| crate::ui::render(ctx, &mut model));
let line = shown
.iter()
.find(|run| run.text.contains("nothing to retarget"))
.expect("the receipt reached the glass");
assert!(line.text.starts_with("ok · litany"), "{}", line.text);
assert_eq!(line.ink, theme::accent(theme::State::Annotation));
crate::test_support::window::escape(&window, |ctx| crate::ui::render(ctx, &mut model));
assert_eq!(model.notice, None);
}
#[test]
fn a_witnessed_act_s_receipt_says_nothing_in_the_slot() {
let mut model = Model {
notice: Some(Notice::Refused("stale".to_owned())),
..Model::default()
};
let flat = own().channel;
for op in [
crate::verbs::MESSAGE.word,
crate::verbs::INTERRUPT.word,
crate::verbs::MODEL.word,
crate::verbs::EFFORT,
crate::verbs::PRIORITY,
] {
model.receipt(&flat, op, ran(0, "deposited", ""));
assert_eq!(model.notice, None, "{op}");
}
model.receipt(&flat, "retarget", ran(0, "nothing to retarget", ""));
assert_eq!(
model.notice,
Some(Notice::Said("ok · nothing to retarget".to_owned()))
);
}
#[test]
fn a_receipt_is_retired_when_the_selection_moves_and_a_refusal_is_not() {
let said = || Some(Notice::Said("seen PortIt — off the queue".to_owned()));
let mut model = seated();
model.notice = said();
model.select("20260830T051200Z-a1b2");
assert_eq!(model.notice, said(), "the same selection keeps its receipt");
model.select("20260830T051300Z-c3d4");
assert_eq!(model.notice, None);
model.notice = said();
let aim = model.aim.clone().expect("seated is aimed");
model.begin_at(&aim);
assert_eq!(model.notice, None, "+ new leaves the conversation");
model.notice = Some(Notice::Refused("no".to_owned()));
model.select("20260830T051200Z-a1b2");
assert_eq!(model.notice, Some(Notice::Refused("no".to_owned())));
}
#[test]
fn after_a_move_the_slot_paints_the_new_selection_s_state() {
let mut model = seated();
model.notice = Some(Notice::Said("seen PortIt — off the queue".to_owned()));
let aim = model.aim.clone().expect("seated is aimed");
model.begin_at(&aim);
let window = crate::paint_probe::frame::Window::new();
let shown = seen(&window, |ctx| crate::ui::render(ctx, &mut model));
assert!(!shown.iter().any(|run| run.text.contains("off the queue")));
assert!(
shown
.iter()
.any(|run| run.text == crate::ui::status::diagnostics::READY)
);
}