use super::{PROTOCOL, confirm, state};
use crate::channel::Failure;
use crate::channel::frame;
use serde_json::{Value, json};
fn stated(v: &Value) -> Vec<u8> {
let mut wire = Vec::new();
frame::write_value(&mut wire, v).expect("write");
wire
}
#[test]
fn this_end_states_one_integer_in_one_frame() {
let mut wire = Vec::new();
state(&mut wire).expect("state");
let mut read = wire.as_slice();
assert_eq!(
frame::read_value(&mut read).expect("read"),
Some(json!({ "protocol": PROTOCOL })),
);
assert_eq!(
frame::read_value(&mut read).ok(),
None,
"the preface is one frame and nothing follows it here"
);
}
#[test]
fn an_engine_of_this_version_is_confirmed() {
let wire = stated(&json!({ "protocol": crate::corpus::PROTOCOL }));
assert_eq!(confirm(&mut wire.as_slice()), Ok(()));
}
#[test]
fn a_mismatch_names_both_versions_and_the_remedy() {
let wire = stated(&json!({ "protocol": 99 }));
let Failure::Skew(refusal) = confirm(&mut wire.as_slice()).expect_err("refused") else {
panic!("a stated version this end does not speak is not the wire");
};
assert!(
refusal.contains(&format!("version {PROTOCOL}")),
"{refusal}"
);
assert!(refusal.contains("engine speaks 99"), "{refusal}");
assert!(refusal.contains("upgrade the older component"), "{refusal}");
assert!(
!refusal.contains("negotiat") || refusal.contains("no negotiation"),
"the refusal must not offer a negotiation: {refusal}"
);
}
#[test]
fn a_preface_that_arrived_and_states_nothing_is_skew() {
let arrived = [
stated(&json!({"op": "advertise"})),
stated(&json!(["not an object"])),
stated(&json!({"protocol": "one"})),
];
for wire in arrived {
let Failure::Skew(refusal) = confirm(&mut wire.as_slice()).expect_err("refused") else {
panic!("a frame the peer wrote is not the wire");
};
assert!(
refusal.contains("the engine speaks no version"),
"{refusal}"
);
}
}
#[test]
fn a_preface_that_never_arrived_is_the_wire() {
let Failure::Wire(refusal) = confirm(&mut [].as_slice()).expect_err("refused") else {
panic!("a peer that hung up mid-preface is not a version this end cannot speak");
};
assert!(
refusal.contains("the engine speaks no version"),
"the sentence is the same sentence: {refusal}"
);
}