use super::{
CLOSE, EMPTY_WORKTREE, HEADING, NO_STEPS, NO_WORKTREE, NOT_ANSWERED_FILES, NOT_ANSWERED_STEPS,
OPEN, TRUNCATED, auth, entry, headline, orphaned, previewed, provenance, render, wounded,
};
use crate::paint_probe::frame::Window;
use crate::reply::files::{FileRow, Files, Listing, Preview};
use crate::reply::steps::Steps;
use crate::test_support::window::{click, pane, recorded, seated, step};
use crate::ui::Model;
#[test]
fn a_shut_pane_paints_nothing_and_reports_it() {
let mut model = seated();
let mut stood = true;
let painted = pane(|ui| stood = render(ui, &mut model));
assert!(!stood, "a shut pane reports that it painted nothing");
assert!(!painted.contains(HEADING), "{painted}");
}
#[test]
fn the_answered_pane_paints_both_halves_whole() {
let mut model = recorded();
let painted = pane(|ui| {
render(ui, &mut model);
});
for word in [
"on 20260830T051200Z-a1b2",
"001 complete — 99 tokens",
"2026-08-30T05:12Z to 2026-08-30T05:14Z at abcdef1",
"002 failed — 99 tokens, 2 attempts",
"an orphaned mail tail — driver died",
"wound: refused — no bytes",
"a sign-in is wanted on housevendor",
"src/",
"src/a.rs 12 B",
TRUNCATED,
"working in /home/u/elsewhere",
CLOSE,
] {
assert!(painted.contains(word), "{word:?}:\n{painted}");
}
}
#[test]
fn every_empty_state_is_its_own_sentence() {
let unanswered = Model {
listing: Some(crate::ui::Listing::Records),
..seated()
};
let quiet = Model {
records: crate::ui::Records {
steps: Some(Steps {
rows: Vec::new(),
orphan: crate::reply::steps::NONE.to_owned(),
orphan_reason: None,
}),
files: Some(Files {
listing: None,
preview: None,
working_dir: None,
}),
..unanswered.records.clone()
},
..unanswered.clone()
};
let bare = Model {
records: crate::ui::Records {
files: Some(Files {
listing: Some(Listing {
rows: Vec::new(),
truncated: false,
}),
preview: None,
working_dir: None,
}),
..quiet.records.clone()
},
..quiet.clone()
};
let cases: Vec<(Box<Model>, &str)> = vec![
(Box::new(unanswered.clone()), NOT_ANSWERED_STEPS),
(Box::new(unanswered), NOT_ANSWERED_FILES),
(Box::new(quiet.clone()), NO_STEPS),
(Box::new(quiet), NO_WORKTREE),
(Box::new(bare), EMPTY_WORKTREE),
];
for (mut model, expected) in cases {
let painted = pane(|ui| {
render(ui, &mut model);
});
assert!(
painted.lines().any(|line| line == expected),
"{expected:?}:\n{painted}"
);
}
}
#[test]
fn a_preview_paints_in_each_of_its_four_classes() {
assert_eq!(previewed(&Preview::Text("body".to_owned())), "body");
assert_eq!(
previewed(&Preview::Truncated {
text: "head".to_owned(),
size: 999
}),
"head\n… 999 bytes in all"
);
assert_eq!(previewed(&Preview::Binary { size: 4 }), "binary — 4 bytes");
let said = previewed(&Preview::Unknown("hologram".to_owned()));
assert!(said.contains("hologram"), "{said}");
let mut model = recorded();
if let Some(files) = model.records.files.as_mut() {
files.preview = Some(Preview::Text("fn main() {}".to_owned()));
}
let painted = pane(|ui| {
render(ui, &mut model);
});
assert!(painted.contains("fn main() {}"), "{painted}");
}
#[test]
fn the_done_control_closes_the_pane() {
let mut model = recorded();
let window = Window::new();
click(&window, CLOSE, |ctx| {
egui::CentralPanel::default().show(ctx, |ui| {
render(ui, &mut model);
});
});
assert!(!model.showing(crate::ui::Listing::Records));
assert!(model.records.steps.is_some(), "the answers stay");
}
#[test]
fn the_quiet_rows_say_nothing_and_the_half_absences_read_right() {
let quiet = step("001");
assert_eq!(wounded(&quiet), None, "no wound, no badge");
assert_eq!(auth(&quiet), None, "no sign-in wanted");
let mut wordless = step("001");
wordless.wound = "output_limit".to_owned();
wordless.wound_reason = None;
assert_eq!(wounded(&wordless), Some("wound: output_limit".to_owned()));
let mut unrouted = step("001");
unrouted.wound = crate::reply::steps::REFUSED.to_owned();
assert_eq!(auth(&unrouted), Some("a sign-in is wanted".to_owned()));
let mut half = step("001");
half.started_at = None;
assert_eq!(
provenance(&half),
Some("at abcdef1".to_owned()),
"one timestamp is no span"
);
half.commit = None;
assert_eq!(provenance(&half), None, "nothing recorded, no line");
assert_eq!(headline(&step("001")), "001 complete — 99 tokens");
let dirless = FileRow {
path: "src".to_owned(),
size: 0,
dir: true,
};
assert_eq!(entry(&dirless), "src/");
let unorphaned = Steps {
rows: Vec::new(),
orphan: crate::reply::steps::NONE.to_owned(),
orphan_reason: None,
};
assert_eq!(orphaned(&unorphaned), None);
let mute = Steps {
orphan: "tool_window".to_owned(),
..unorphaned
};
assert_eq!(
orphaned(&mute),
Some("an orphaned tool_window tail".to_owned())
);
}
#[test]
fn the_open_control_stands_the_pane_up_from_the_composer() {
let mut model = seated();
let window = Window::new();
click(&window, OPEN, |ctx| {
egui::CentralPanel::default().show(ctx, |ui| {
crate::ui::composer::render(ui, &mut model);
});
});
assert!(model.showing(crate::ui::Listing::Records), "the pane is up");
assert!(model.outbox.is_empty(), "a look composes nothing");
}