use super::fixture::{MINT_SEED, MINTED_FIRST, fake_lernie, seed_world, world};
use super::screen::{Screen, press};
use crate::cli_outbound::Cli;
use crate::start::Prepared;
use crate::test_support::spawn_guard;
use tempfile::tempdir;
fn predicted(screen: &str) -> String {
screen
.lines()
.find(|line| line.starts_with("will be named "))
.expect("the composer previews the name its Enter would mint")
.to_owned()
}
fn fire(screen: &Screen, world: &mut super::fixture::World, goal: &str) {
screen.frame(world, vec![egui::Event::Text(goal.to_owned())]);
screen.frame(world, vec![press(egui::Key::Enter, egui::Modifiers::NONE)]);
world.converge();
}
#[test]
fn consecutive_fires_each_predict_and_spend_a_seed_of_their_own() {
let bin = tempdir().unwrap();
let mut world = world();
seed_world(&world);
let _g = spawn_guard();
let screen = Screen::with_lernie(fake_lernie(bin.path()));
assert!(screen.idle(&mut world), "the cursor starts in the composer");
let first = predicted(&screen.text(&mut world));
let seed = world.state.start.mint_seed;
assert_eq!(seed, MINT_SEED, "the world starts from the pinned seed");
assert_eq!(
first,
format!("will be named {MINTED_FIRST}"),
"and the pinned seed's one draw is the word the suite may name"
);
fire(&screen, &mut world, "open the gate");
let respun = world.state.start.mint_seed;
assert_ne!(
respun, seed,
"a landed fire retires the seed it spent (bl-28ba)"
);
let second = predicted(&screen.text(&mut world));
assert_ne!(
second, first,
"so the next agent is predicted a fresh name, not the walk's next slot"
);
fire(&screen, &mut world, "shut the gate");
assert_ne!(
world.state.start.mint_seed, respun,
"and every fire after it retires its own"
);
let third = predicted(&screen.text(&mut world));
assert_ne!(third, second, "three fires, three unrelated names");
assert_ne!(third, first);
}
#[test]
fn a_launch_that_never_left_the_ground_keeps_its_prediction() {
let mut world = world();
let screen = Screen::new();
let absent = Cli::new("yog-absent-lernie");
let ws = world.ws.clone();
world.state.start.pending = Some(Prepared {
name: "ws".to_owned(),
workspace: ws.clone(),
cwd: ws,
goal: "fix the gate".to_owned(),
origin: crate::opslog::Origin::Balls,
});
let before = predicted(&screen.text(&mut world));
let seed = world.state.start.mint_seed;
assert!(
!super::super::start_pane::send_pending(
&mut world.model,
&mut world.state.start,
&absent,
&absent
),
"the absent binary fails the launch"
);
assert_eq!(
world.state.start.mint_seed, seed,
"a failed launch spends no seed — nothing took the name it predicted"
);
assert!(
world.state.start.pending.is_some(),
"the goal stands, so the prediction over it must too"
);
assert_eq!(
predicted(&screen.text(&mut world)),
before,
"and the retry is offered the same name the first attempt promised"
);
}
#[test]
fn the_ball_rungs_send_retires_the_seed_the_same_way() {
let bin = tempdir().unwrap();
let mut world = world();
seed_world(&world);
let _g = spawn_guard();
let lernie = fake_lernie(bin.path());
let ws = world.ws.clone();
world.state.start.pending = Some(Prepared {
name: "ws".to_owned(),
workspace: ws.clone(),
cwd: ws,
goal: "fix the gate".to_owned(),
origin: crate::opslog::Origin::Balls,
});
let seed = world.state.start.mint_seed;
assert!(super::super::start_pane::send_pending(
&mut world.model,
&mut world.state.start,
&lernie,
&lernie
));
assert_ne!(
world.state.start.mint_seed, seed,
"a landed ball-rung fire retires its seed too"
);
assert!(
world.state.start.pending.is_none(),
"and the draft it fired is spent with it"
);
}