use super::fixture::world;
use super::screen::{Screen, press};
use crate::start::Prepared;
const BALL_GOAL: &str = "Ball bl-1234: fix the gate\n\nthe gate is stuck";
#[test]
fn a_pending_start_draft_replaces_the_composer_and_cancel_restores_it() {
let mut world = world();
let screen = Screen::new();
assert!(screen.idle(&mut world), "the cursor starts in the composer");
screen.frame(
&mut world,
vec![egui::Event::Text("ship the goal".to_owned())],
);
let before = screen.text(&mut world);
assert!(
before.contains("New prompt"),
"the composer is up:\n{before}"
);
assert!(
before.contains("ship the goal"),
"holding its own draft:\n{before}"
);
assert!(
!before.contains("Start goal →"),
"and nothing is pending yet:\n{before}"
);
let ws = world.ws.clone();
world.state.start.pending = Some(Prepared {
name: "ws".to_owned(),
workspace: ws.clone(),
cwd: ws,
goal: BALL_GOAL.to_owned(),
origin: crate::opslog::Origin::Balls,
});
let pending = screen.text(&mut world);
assert!(
pending.contains("Start goal →") && pending.contains("Send (detached prompt)"),
"the start draft is up:\n{pending}"
);
assert!(
!pending.contains("New prompt"),
"and it REPLACED the composer — one box, one Enter:\n{pending}"
);
assert_eq!(
pending.matches("will be named ").count(),
1,
"so exactly one name prediction is on screen:\n{pending}"
);
assert!(
!pending.contains("ship the goal"),
"the composer's draft is off screen, not a second live box:\n{pending}"
);
screen.frame(
&mut world,
vec![press(egui::Key::Escape, egui::Modifiers::NONE)],
);
assert!(
world.state.start.pending.is_none(),
"Escape cancels the pending start"
);
let after = screen.text(&mut world);
assert!(
after.contains("New prompt"),
"and the composer comes back:\n{after}"
);
assert!(
after.contains("ship the goal"),
"with its own draft intact — the start pane never held it:\n{after}"
);
assert!(
!after.contains("Start goal →"),
"and the draft box is gone:\n{after}"
);
}