use std::path::PathBuf;
use contextgraph_host::wire::Envelope;
fn examples_dir() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.expect("workspace root")
.join("examples")
}
#[test]
fn every_reference_message_deserializes_through_the_rust_types() {
let path = examples_dir().join("reference-messages.json");
let raw = std::fs::read_to_string(&path)
.unwrap_or_else(|e| panic!("could not read {}: {e}", path.display()));
let messages: Vec<serde_json::Value> =
serde_json::from_str(&raw).expect("reference-messages.json is a JSON array");
assert!(
!messages.is_empty(),
"the reference transcript must not be empty — an empty fixture proves nothing"
);
for (index, message) in messages.iter().enumerate() {
let envelope: Envelope = serde_json::from_value(message.clone()).unwrap_or_else(|e| {
panic!(
"reference-messages.json[{index}] does not deserialize into the Rust \
wire types: {e}\n message: {message}\n\
The schema, the examples, and `Envelope` describe one wire — if you \
changed a wire type, update the examples in the same commit."
)
});
let reencoded = serde_json::to_value(&envelope).expect("envelope re-serializes");
let back: Envelope =
serde_json::from_value(reencoded).expect("re-serialized envelope re-parses");
assert_eq!(
back, envelope,
"reference-messages.json[{index}] did not survive a serde round-trip"
);
}
}
#[test]
fn every_line_of_the_stdio_session_deserializes_through_the_rust_types() {
let path = examples_dir().join("full-stdio-session.ndjson");
let raw = std::fs::read_to_string(&path)
.unwrap_or_else(|e| panic!("could not read {}: {e}", path.display()));
let mut lines = 0;
for (index, line) in raw.lines().enumerate() {
if line.trim().is_empty() {
continue;
}
lines += 1;
serde_json::from_str::<Envelope>(line).unwrap_or_else(|e| {
panic!(
"full-stdio-session.ndjson line {} does not deserialize into the Rust \
wire types: {e}\n line: {line}",
index + 1
)
});
}
assert!(lines > 0, "the NDJSON transcript must not be empty");
}
#[test]
fn the_transcript_is_a_complete_session_not_an_arbitrary_bag_of_messages() {
let path = examples_dir().join("full-stdio-session.ndjson");
let raw = std::fs::read_to_string(path).expect("stdio transcript readable");
let kinds: Vec<String> = raw
.lines()
.filter(|l| !l.trim().is_empty())
.map(|l| {
let value: serde_json::Value = serde_json::from_str(l).expect("valid JSON line");
value["type"].as_str().expect("a type tag").to_string()
})
.collect();
assert_eq!(kinds.first().map(String::as_str), Some("handshake"));
assert!(kinds.iter().any(|k| k == "handshake_ack"));
assert!(kinds.iter().any(|k| k == "query"));
assert!(kinds.iter().any(|k| k == "frames"));
assert_eq!(kinds.last().map(String::as_str), Some("shutdown"));
}
#[test]
fn a_correlated_query_in_the_transcript_is_answered_with_the_same_id() {
let path = examples_dir().join("full-stdio-session.ndjson");
let raw = std::fs::read_to_string(path).expect("stdio transcript readable");
let mut query_id = None;
let mut frames_id = None;
for line in raw.lines().filter(|l| !l.trim().is_empty()) {
match serde_json::from_str::<Envelope>(line).expect("valid envelope") {
Envelope::Query { id, .. } => query_id = id,
Envelope::Frames { id, .. } => frames_id = id,
_ => {}
}
}
assert!(
query_id.is_some(),
"the example query should carry an id so the transcript documents correlation"
);
assert_eq!(
query_id, frames_id,
"the example `frames` reply must echo the `query` id (SPEC.md H4)"
);
}