use crate::app::tests::Harness;
use crate::boundary::reply::Reply;
use crate::boundary::{Action, Gesture, codec};
use crate::watch::Mark;
fn nudge() -> Action {
Action::Nudge {
workspace: "ws".to_owned(),
agent: "c-1".to_owned(),
}
}
#[test]
fn a_post_puts_the_codec_spelling_of_the_act_on_the_wire() {
let h = Harness::new();
let (_clock, mut rig) = h.model();
let (post, outbox) = crate::wire::post::pair();
rig.model.adopt_post(post);
let ticket = rig.model.post_act(&nudge());
let (sent, envelope) = outbox.next().expect("the act is queued at once");
assert_eq!(sent, ticket);
assert_eq!(envelope, codec::encode(&Gesture::Act(nudge())));
}
#[test]
fn the_root_is_re_derived_when_the_receipt_lands_and_not_before() {
let h = Harness::new();
let (_clock, mut rig) = h.model();
let (post, outbox) = crate::wire::post::pair();
rig.model.adopt_post(post);
let ticket = rig.model.post_act(&nudge());
rig.model.settle_acts();
assert!(
rig.model.dirty_handle().drain().is_empty(),
"the act has not happened yet, so nothing has changed to re-read"
);
let (sent, _) = outbox.next().expect("queued");
outbox.publish(sent, Ok(Reply::Nudged));
rig.model.settle_acts();
assert_eq!(
rig.model.dirty_handle().drain(),
[(h.roots.yog_state.clone(), Mark::Watch)]
.into_iter()
.collect(),
"a lernie verb's ops line lands under the yog state root"
);
assert_eq!(rig.model.act_receipt(ticket), Some(Ok(Reply::Nudged)));
}
#[test]
fn a_ball_verb_re_derives_the_project_it_named() {
let h = Harness::new();
let (_clock, mut rig) = h.model();
let project = h.roots.home.join("dev").join("proj");
rig.deriver.projects = vec![project.clone()];
rig.publish();
let (post, outbox) = crate::wire::post::pair();
rig.model.adopt_post(post);
let close = |name: &str| Action::Close {
project: name.to_owned(),
id: "bl-0000".to_owned(),
name: "ws".to_owned(),
};
let known = rig.model.post_act(&close("proj"));
let unknown = rig.model.post_act(&close("nowhere"));
for expected in [project, h.roots.yog_state.clone()] {
let (sent, _) = outbox.next().expect("queued");
outbox.publish(sent, Ok(Reply::Acked));
rig.model.settle_acts();
assert_eq!(
rig.model.dirty_handle().drain(),
[(expected, Mark::Watch)].into_iter().collect()
);
}
assert!(rig.model.act_receipt(known).is_some());
assert!(rig.model.act_receipt(unknown).is_some());
}
#[test]
fn a_model_with_no_wire_answers_its_own_post() {
let h = Harness::new();
let (_clock, mut rig) = h.model();
let ticket = rig.model.post_act(&nudge());
let Some(Err(said)) = rig.model.act_receipt(ticket) else {
panic!("the send is its own receipt with nobody behind it");
};
assert!(said.contains("no wire"), "{said}");
}