use super::{ADVERTISE, ADVERTISED, COMPLETE, INVOCATIONS, PROTOCOL, QUEUED, REFUSAL, ROUTED};
use crate::channel::hello;
use crate::gestures::{self, Reply};
use crate::invocation::{Capture, capture_of};
use crate::json::str_of;
use crate::tools;
use serde_json::Value;
fn frame(text: &str) -> Value {
serde_json::from_str(text).expect("a corpus frame is JSON")
}
#[test]
fn the_version_this_build_states_is_the_version_the_engine_states() {
assert_eq!(
hello::PROTOCOL,
PROTOCOL,
"this foot pins {}, the engine's corpus states {PROTOCOL} — \
re-vendor src/corpus.rs from yog and move the pin with it",
hello::PROTOCOL,
);
}
#[test]
fn every_advertisement_round_trips() {
for text in ADVERTISE {
let set: Vec<tools::Tool> = frame(text)["tools"]
.as_array()
.expect("tools")
.iter()
.map(|row| tools::of_one(row).expect("a corpus element"))
.collect();
assert_eq!(gestures::advertise(&set).to_string(), text);
}
}
#[test]
fn the_follow_class_read_round_trips() {
assert_eq!(gestures::invocations().to_string(), INVOCATIONS);
}
#[test]
fn the_completion_round_trips() {
let sent = frame(COMPLETE);
let o = sent.as_object().expect("an object");
let capture = capture_of(&o["capture"]).expect("a corpus capture");
assert_eq!(
capture,
Capture {
stdout: "hello\n".to_owned(),
stderr: "warned\n".to_owned(),
exit_code: 3,
}
);
let id = str_of(o, "invocation").expect("the handle");
assert_eq!(gestures::complete(&id, &capture).to_string(), COMPLETE);
}
#[test]
fn the_advertised_receipt_carries_the_engine_s_reading() {
assert_eq!(
gestures::decode(&frame(ADVERTISED[0])),
Ok(Ok(Reply::Advertised { wrote: false }))
);
assert_eq!(
gestures::decode(&frame(ADVERTISED[1])),
Ok(Ok(Reply::Advertised { wrote: true }))
);
}
#[test]
fn the_receipt_the_engine_sent_before_the_bump_is_refused() {
assert_eq!(
gestures::decode(&frame(r#"{"kind":"advertised","ok":true}"#)),
Err("reply: missing field \"wrote\"".to_owned())
);
}
#[test]
fn every_queued_row_decodes() {
let rows: Vec<Reply> = QUEUED
.iter()
.map(|text| {
gestures::decode(&frame(text))
.expect("readable")
.expect("an answer")
})
.collect();
assert_eq!(rows[0], Reply::Invocations(vec![]));
let Reply::Invocations(ordinary) = &rows[1] else {
panic!("invocations");
};
assert_eq!(ordinary[0].id, "inv-1");
assert_eq!(ordinary[0].tool, "Bash");
assert_eq!(ordinary[0].cwd, None);
let Reply::Invocations(lane) = &rows[2] else {
panic!("invocations");
};
assert_eq!(lane[0].cwd.as_deref(), Some("/w/home/agents/c-1"));
}
#[test]
fn the_routed_receipt_tells_unfinished_from_finished_saying_nothing() {
assert_eq!(
gestures::decode(&frame(ROUTED[0])),
Ok(Ok(Reply::Routed {
invocation: "inv-1".to_owned(),
capture: None
}))
);
assert_eq!(
gestures::decode(&frame(ROUTED[1])),
Ok(Ok(Reply::Routed {
invocation: "inv-2".to_owned(),
capture: Some(Capture {
stdout: "hello\n".to_owned(),
stderr: "warned\n".to_owned(),
exit_code: 3,
})
}))
);
}
#[test]
fn the_refusal_is_the_envelope_with_no_kind() {
assert_eq!(
gestures::decode(&frame(REFUSAL)),
Ok(Err("unknown op \"fhtagn\"".to_owned()))
);
}