use super::{holding, own, posting};
use crate::offframe::poster::tick;
use crate::test_support::Scratch;
use crate::test_support::engine::Answer;
use crate::test_support::wire::{flat, wired};
use crate::ui::Aim;
use serde_json::json;
#[test]
fn an_act_that_never_left_this_box_says_so_and_says_it_is_safe_to_repeat() {
let scratch = Scratch::new();
let (link, mut model) = holding(
None,
crate::verbs::nudge("home".to_owned(), "a1b2".to_owned()),
);
tick(&link, scratch.path());
link.settle(&mut model);
let said = model.notice.expect("a notice").line();
assert!(said.contains("`nudge` was not sent"), "{said}");
assert!(said.contains("nothing happened"), "{said}");
assert!(said.contains("safe to do it again"), "{said}");
assert!(!said.contains("DOUBT"), "nothing crossed: {said}");
}
#[test]
fn an_act_that_crossed_with_no_answer_is_painted_in_doubt() {
let scratch = Scratch::new();
wired(&scratch, &flat(), vec![Answer::Hangup]);
let (link, mut model) = holding(
Some(Aim {
channel: own().name,
address: "home".to_owned(),
}),
crate::verbs::message("home".to_owned(), "a1b2".to_owned(), "ship it".to_owned()),
);
tick(&link, scratch.path());
link.settle(&mut model);
let said = model.notice.expect("a notice").line();
assert!(said.contains("`message` is IN DOUBT"), "{said}");
assert!(said.contains("it may have run"), "{said}");
assert!(said.contains("never resends an act"), "{said}");
assert!(
said.contains("the world is the record"),
"the recovery is a read: {said}"
);
}
#[test]
fn an_act_in_doubt_is_never_sent_again() {
let scratch = Scratch::new();
let engine = wired(
&scratch,
&flat(),
vec![
Answer::Hangup,
Answer::Frames(vec![json!({"ok": true, "kind": "nudged"})]),
],
);
let (link, mut model) = holding(
None,
crate::verbs::nudge("home".to_owned(), "a1b2".to_owned()),
);
tick(&link, scratch.path());
link.settle(&mut model);
tick(&link, scratch.path());
link.settle(&mut model);
let gesture = json!({"op": "nudge", "workspace": "home", "agent": "a1b2"});
assert_eq!(
engine
.heard()
.iter()
.filter(|said| **said == gesture)
.count(),
1,
"an act in doubt was sent a second time: {:?}",
engine.heard()
);
}
#[test]
fn an_acts_sentence_survives_a_roster_answer() {
let scratch = Scratch::new();
wired(&scratch, &flat(), vec![Answer::Hangup]);
let (link, mut model) = holding(
None,
crate::verbs::nudge("home".to_owned(), "a1b2".to_owned()),
);
tick(&link, scratch.path());
link.settle(&mut model);
assert!(model.notice.is_some(), "the act said something");
model.absorb(
&own(),
crate::reply::read(&json!({"ok": true, "kind": "workspaces", "rows": []})),
);
let said = model.notice.expect("still there").line();
assert!(said.contains("IN DOUBT"), "{said}");
assert!(
matches!(model.roster[0].held, crate::ui::Held::Heard),
"and the channel is not painted down over an act's failure"
);
}
#[test]
fn a_posted_read_that_went_unanswered_is_not_in_doubt() {
let scratch = Scratch::new();
wired(&scratch, &flat(), vec![Answer::Hangup]);
let (link, mut model) = posting(None, crate::ui::Posted::read(crate::verbs::workspaces()));
tick(&link, scratch.path());
link.settle(&mut model);
assert_eq!(model.notice, None, "a read is not an exchange in doubt");
assert!(
matches!(model.roster[0].held, crate::ui::Held::Unheld(_)),
"it is the channel's own relationship: {:?}",
model.roster[0].held
);
}