use super::{PROTOCOL, confirm, state};
use crate::channel::edition;
use crate::channel::{Reach, 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_its_major_and_its_edition_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, "edition": edition::EDITION })),
);
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_major_is_confirmed_and_answers_its_edition() {
let wire = stated(&json!({ "protocol": PROTOCOL, "edition": edition::EDITION + 3 }));
assert_eq!(confirm(&mut wire.as_slice()), Ok(edition::EDITION + 3));
}
#[test]
fn an_engine_that_states_no_edition_is_read_at_the_floor() {
for said in [
json!({ "protocol": PROTOCOL }),
json!({ "protocol": PROTOCOL, "edition": "nineteen" }),
json!({ "protocol": PROTOCOL, "edition": -1 }),
json!({ "protocol": PROTOCOL, "edition": u64::from(u32::MAX) + 1 }),
] {
let wire = stated(&said);
assert_eq!(confirm(&mut wire.as_slice()), Ok(edition::FLOOR), "{said}");
}
}
#[test]
fn a_mismatch_names_both_versions_and_the_remedy() {
let wire = stated(&json!({ "protocol": 99 }));
let reach = confirm(&mut wire.as_slice()).expect_err("refused");
let refusal = reach.said();
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}"
);
assert!(!reach.crossed(), "a stated mismatch never crossed");
}
#[test]
fn every_way_of_stating_nothing_is_the_one_sentence() {
let silences = [
stated(&json!({"op": "advertise"})),
stated(&json!(["not an object"])),
stated(&json!({"protocol": "one"})),
{
let mut wire = Vec::new();
frame::write_end(&mut wire).expect("terminator");
wire
},
];
for wire in silences {
let reach = confirm(&mut wire.as_slice()).expect_err("refused");
assert!(
reach.said().contains("the engine speaks no version"),
"{}",
reach.said()
);
assert!(!reach.crossed(), "a peer that spoke adjudicated nothing");
}
}
#[test]
fn a_preface_this_end_could_not_read_leaves_the_request_in_doubt() {
let reach = confirm(&mut [].as_slice()).expect_err("refused");
assert_eq!(
reach,
Reach::Unanswered("the engine stated no version: failed to fill whole buffer".to_owned())
);
assert!(reach.crossed());
}