use super::{Phase, Start};
use crate::reply::read;
use crate::test_support::window::{own, seated};
use crate::ui::{Aim, Model};
use serde_json::json;
fn staged(workspace: &str, goal: &str) -> crate::reply::Read {
read(&json!({"ok": true, "kind": "prepared",
"prepared": {"workspace": workspace, "goal": goal}}))
}
#[test]
fn a_start_is_two_acts_and_the_second_is_composed_from_the_first_s_answer() {
let mut model = Model {
conversation: None,
draft: "do the thing".to_owned(),
..seated()
};
model.stage("home");
assert_eq!(
model.outbox,
vec![crate::ui::Posted::act(crate::verbs::prepare(
"home".to_owned()
))]
);
assert_eq!(model.draft, "", "what was staged is no longer a draft");
assert_eq!(
model.start.as_ref().map(|start| start.phase.clone()),
Some(Phase::Staging)
);
model.absorb(&own().channel, staged("home", ""));
assert_eq!(model.outbox.len(), 2, "the fire is composed, not posted");
assert_eq!(model.outbox[1].envelope["op"], json!("prompt"));
assert_eq!(model.outbox[1].envelope["goal"], json!("do the thing"));
model.absorb(
&own().channel,
read(&json!({"ok": true, "kind": "started", "conversation": "brisk-otter"})),
);
let start = model.start.as_ref().expect("the start");
assert_eq!(start.phase, Phase::Started("brisk-otter".to_owned()));
assert!(!start.outstanding());
assert_eq!(start.line(), "started «brisk-otter» in home");
}
#[test]
fn the_fire_goes_where_the_start_was_staged_even_if_the_aim_moved() {
let mut model = Model {
conversation: None,
draft: "do it".to_owned(),
..seated()
};
model.stage("home");
model.aim = Some(Aim {
channel: "elsewhere".to_owned(),
address: "other".to_owned(),
});
model.absorb(&own().channel, staged("home", ""));
assert_eq!(
model.outbox[1].envelope["prepared"]["workspace"],
json!("home")
);
}
#[test]
fn a_blank_goal_stages_nothing_and_keeps_what_was_typed() {
let mut model = Model {
draft: " ".to_owned(),
..Model::default()
};
model.stage("home");
assert!(model.outbox.is_empty());
assert_eq!(model.start, None);
assert_eq!(model.draft, " ", "the draft is still the operator's");
}
#[test]
fn a_body_nothing_staged_fires_on_its_own_terms_or_not_at_all() {
let mut model = Model::default();
model.absorb(&own().channel, staged("home", "the rung's own prefill"));
assert_eq!(model.outbox.len(), 1);
assert_eq!(
model.outbox[0].envelope["goal"],
json!("the rung's own prefill")
);
assert_eq!(
model.start.as_ref().map(|start| start.phase.clone()),
Some(Phase::Firing)
);
let mut bare = Model::default();
bare.absorb(&own().channel, staged("home", " "));
assert!(bare.outbox.is_empty(), "a blank goal never fires");
assert_eq!(bare.start, None);
}
#[test]
fn a_receipt_with_nothing_held_still_carries_the_minted_name() {
for (model, address) in [(Model::default(), ""), (seated(), "home")] {
let mut model = model;
model.absorb(
&own().channel,
read(&json!({"ok": true, "kind": "started", "conversation": "brisk-otter"})),
);
assert_eq!(
model.start,
Some(Start {
address: address.to_owned(),
goal: String::new(),
phase: Phase::Started("brisk-otter".to_owned()),
})
);
}
}
#[test]
fn a_start_in_flight_reads_the_same_whichever_act_is_out() {
let staging = Start {
address: "home".to_owned(),
goal: "do it".to_owned(),
phase: Phase::Staging,
};
let firing = Start {
phase: Phase::Firing,
..staging.clone()
};
assert_eq!(staging.line(), "starting in home: do it…");
assert_eq!(firing.line(), staging.line());
assert!(staging.outstanding() && firing.outstanding());
}