mod shape;
use super::{goal, render};
use crate::paint_probe::frame::{Window, locate_in, press};
use crate::test_support::window::{pane, seated};
use crate::ui::model::{Phase, Start};
use crate::ui::theme::glyph;
use crate::ui::{Aim, Model};
use serde_json::json;
fn unselected() -> Model {
Model {
conversation: None,
..seated()
}
}
fn aimed() -> Aim {
unselected().aim.expect("the fixture is aimed")
}
#[test]
fn a_wall_with_nothing_selected_offers_a_start() {
let mut model = unselected();
let painted = pane(|ui| render(ui, &mut model, &aimed()));
for expected in [goal("home", false).as_str(), glyph::PROMPT] {
assert!(
painted.lines().any(|line| line.starts_with(expected)),
"{expected:?}:\n{painted}"
);
}
}
#[test]
fn starting_composes_the_staging_act_and_posts_nothing() {
let mut model = unselected();
model.draft = "do the thing".to_owned();
let window = Window::new();
window.frame(Vec::new(), |ctx| {
egui::CentralPanel::default().show(ctx, |ui| render(ui, &mut model, &aimed()));
});
window.focus(egui::Id::new(crate::ui::keys::BOX_ID));
window.frame(vec![press(egui::Key::Enter)], |ctx| {
egui::CentralPanel::default().show(ctx, |ui| render(ui, &mut model, &aimed()));
});
assert_eq!(
model.outbox,
vec![crate::ui::Posted::act(
json!({"op": "prepare", "workspace": "home", "payload": {"rung": "bare"}})
)]
);
assert_eq!(
model.start.as_ref().map(|start| start.goal.clone()),
Some("do the thing".to_owned())
);
}
#[test]
fn enter_begins_what_was_typed() {
let mut model = unselected();
let window = Window::new();
let mut body = |ctx: &egui::Context| {
egui::CentralPanel::default().show(ctx, |ui| render(ui, &mut model, &aimed()));
};
let at = crate::paint_probe::frame::led_in(&window, &goal("home", false), &mut body)
.expect("the box");
crate::paint_probe::frame::click(&window, at, &mut body);
window.frame(
vec![egui::Event::Text("do the thing".to_owned())],
&mut body,
);
window.frame(vec![press(egui::Key::Enter)], &mut body);
window.frame(Vec::new(), &mut body);
assert_eq!(model.outbox.len(), 1, "{:?}", model.outbox);
assert_eq!(model.outbox[0].envelope["op"], json!("prepare"));
}
#[test]
fn enter_on_a_slash_line_begins_nothing() {
let mut model = unselected();
model.draft = "/plan".to_owned();
let window = Window::new();
let mut body = |ctx: &egui::Context| {
egui::CentralPanel::default().show(ctx, |ui| render(ui, &mut model, &aimed()));
};
let at = locate_in(&window, "/plan", &mut body).expect("the box");
crate::paint_probe::frame::click(&window, at, &mut body);
window.frame(vec![press(egui::Key::Enter)], &mut body);
assert!(model.outbox.is_empty(), "{:?}", model.outbox);
assert_eq!(model.start, None);
}
#[test]
fn a_start_in_flight_paints_its_sentence_and_offers_no_second_start() {
for phase in [Phase::Staging, Phase::Firing] {
let mut model = Model {
start: Some(Start {
address: "home".to_owned(),
goal: "do the thing".to_owned(),
phase,
spread: None,
}),
..unselected()
};
let painted = pane(|ui| render(ui, &mut model, &aimed()));
assert!(
painted.contains("starting in home: do the thing…"),
"{painted}"
);
assert!(
!painted.lines().any(|line| line == glyph::PROMPT),
"no control to press:\n{painted}"
);
}
}
#[test]
fn a_finished_start_paints_its_name_over_the_box_that_begins_the_next() {
let mut model = Model {
start: Some(Start {
address: "home".to_owned(),
goal: "do the thing".to_owned(),
phase: Phase::Started("brisk-otter".to_owned()),
spread: None,
}),
..unselected()
};
let painted = pane(|ui| render(ui, &mut model, &aimed()));
assert!(
painted.contains("started «brisk-otter» in home"),
"{painted}"
);
assert!(
painted.lines().any(|line| line == glyph::PROMPT),
"{painted}"
);
}
#[test]
fn a_refused_start_paints_its_sentence_over_the_box_that_carries_the_goal_back() {
let mut model = Model {
start: Some(Start {
address: "home".to_owned(),
goal: "do the thing".to_owned(),
phase: Phase::Refused("sign in first: no provider holds a credential".to_owned()),
spread: None,
}),
draft: "do the thing".to_owned(),
..unselected()
};
let painted = pane(|ui| render(ui, &mut model, &aimed()));
assert!(
painted.contains("not started in home: sign in first: no provider holds a credential"),
"{painted}"
);
assert!(
painted.lines().any(|line| line == glyph::PROMPT),
"{painted}"
);
assert!(
painted.contains("do the thing"),
"the goal is in the box:\n{painted}"
);
}
#[test]
fn a_refused_start_carries_the_doors_it_names() {
let refused = |why: &str| Model {
start: Some(Start {
address: "home".to_owned(),
goal: "do the thing".to_owned(),
phase: Phase::Refused(why.to_owned()),
spread: None,
}),
..unselected()
};
let mut model = refused("sign in first — write its key into this wall with /config brazen");
let mut body = |ctx: &egui::Context| {
egui::CentralPanel::default().show(ctx, |ui| render(ui, &mut model, &aimed()));
};
let window = Window::new();
crate::test_support::window::click(&window, "/config", &mut body);
assert!(model.covered(), "the config pane stands");
let mut model = refused("sign in first: no provider holds a credential");
let painted = pane(|ui| render(ui, &mut model, &aimed()));
assert!(!painted.lines().any(|line| line == "/config"), "{painted}");
}
#[test]
fn the_hint_names_the_wall_and_the_plan() {
let mut model = unselected();
let painted = pane(|ui| render(ui, &mut model, &aimed()));
assert!(painted.contains("on home is for"), "{painted}");
model.plan = true;
let planned = pane(|ui| render(ui, &mut model, &aimed()));
assert!(planned.contains(&goal("home", true)), "{planned}");
}
#[test]
fn a_wall_whose_worker_holds_no_credential_names_the_doors() {
let worker = crate::reply::roles::RoleRow {
role: "worker".to_owned(),
provider: "anthropic".to_owned(),
model: "m".to_owned(),
priority: false,
effort: None,
};
let row = |fact: &str| crate::reply::providers::ProviderRow {
name: "anthropic".to_owned(),
fact: fact.to_owned(),
blocked: None,
effort: true,
priority: true,
};
for (providers, unsigned) in [
(Some(vec![row("auth api_key · no credential stored")]), true),
(Some(vec![row("auth api_key · credential stored")]), false),
(None, false),
] {
let mut model = Model {
roles: Some(vec![worker.clone()]),
providers,
..unselected()
};
assert_eq!(super::unsigned(&model), unsigned);
let painted = pane(|ui| render(ui, &mut model, &aimed()));
assert_eq!(painted.contains(super::UNSIGNED), unsigned, "{painted}");
assert_eq!(
painted.contains(&goal("home", false)),
!unsigned,
"{painted}"
);
}
assert!(
!super::unsigned(&unselected()),
"no roles read, nothing claimed"
);
}