use std::fs;
use std::path::Path;
use serde_json::{Value, json};
use tempfile::tempdir;
use super::ledger::{Ledger, signature};
use super::{committed, destination, protocol, run, shapes, store};
mod ledger;
#[test]
fn gate() {
let verdict = run(destination(), &committed());
assert_eq!(verdict, Ok(()), "{verdict:?}");
}
fn blessed(dir: &Path) {
assert_eq!(run(Some(dir.to_owned()), dir), Ok(()));
}
#[test]
fn a_regenerated_corpus_passes_its_own_gate_twice() {
let dir = tempdir().expect("scratch");
blessed(dir.path());
assert_eq!(run(None, dir.path()), Ok(()));
let record = fs::read_to_string(dir.path().join("shapes.json")).expect("record");
blessed(dir.path());
assert_eq!(run(None, dir.path()), Ok(()));
assert_eq!(
fs::read_to_string(dir.path().join("shapes.json")).expect("record"),
record,
"a no-op regeneration is byte-identical"
);
}
#[test]
fn every_shape_is_a_stamped_file_of_frames() {
let dir = tempdir().expect("scratch");
blessed(dir.path());
let all = shapes();
assert!(all.len() > 80, "{} shapes", all.len());
for shape in &all {
let text = fs::read_to_string(dir.path().join(shape.path())).expect("fixture");
let value = serde_json::from_str::<Value>(&text).expect("canonical json");
assert_eq!(value["protocol"], json!(protocol()), "{}", shape.key());
assert_eq!(value["shape"], json!(shape.name), "{}", shape.key());
assert!(!shape.frames.is_empty(), "{} has no frames", shape.key());
}
assert!(all.iter().any(|s| s.key() == "request/message"));
assert!(all.iter().any(|s| s.key() == "reply/refusal"));
}
#[test]
fn a_stale_fixture_and_an_orphan_are_both_named() {
let dir = tempdir().expect("scratch");
blessed(dir.path());
fs::write(dir.path().join("request/ack.json"), "{}\n").expect("tamper");
fs::write(dir.path().join("reply/ghost.json"), "{}\n").expect("orphan");
let refusal = run(None, dir.path()).expect_err("stale");
assert!(refusal.contains("request/ack.json"), "{refusal}");
assert!(refusal.contains("reply/ghost.json"), "{refusal}");
assert!(refusal.contains("make corpus"), "{refusal}");
assert!(refusal.contains("PROTOCOL"), "{refusal}");
blessed(dir.path());
assert!(!dir.path().join("reply/ghost.json").exists());
assert_eq!(run(None, dir.path()), Ok(()));
}
#[test]
fn a_signature_reads_fields_and_not_bytes() {
let one = signature(&[json!({ "op": "stop", "children": true, "tags": ["a"] })]);
let two = signature(&[
json!({ "op": "stop", "children": false, "tags": [] }),
json!({ "op": "stop", "children": true, "tags": ["a", "b"] }),
]);
assert_eq!(one, two, "samples are not shapes");
assert!(one.contains("/children:bool"), "{one:?}");
assert!(one.contains("/tags/[]:string"), "{one:?}");
let renamed = signature(&[json!({ "op": "stop", "kids": true, "tags": ["a"] })]);
assert_ne!(one, renamed, "a renamed field is a moved shape");
assert_eq!(
signature(&[json!({ "at": Value::Null })])
.into_iter()
.collect::<Vec<_>>(),
vec!["/at:null", ":object"]
);
}
#[test]
fn an_unreadable_record_is_empty_and_an_unwritable_destination_refuses() {
let empty = Ledger::read("not json");
assert_eq!((empty.protocol, empty.floor, empty.edition()), (0, 0, 0));
let dir = tempdir().expect("scratch");
let blocked = dir.path().join("file");
fs::write(&blocked, "").expect("seed");
assert!(store::bless(&blocked.join("under")).is_err());
}
#[test]
fn the_hello_states_the_committed_edition_and_floor() {
let record =
Ledger::read(&fs::read_to_string(committed().join("shapes.json")).expect("record"));
assert_eq!(
crate::wire::hello::EDITION,
record.edition(),
"the compiled EDITION is not the record's newest stamp"
);
assert_eq!(
crate::wire::hello::FLOOR,
record.floor,
"the compiled FLOOR is not the record's floor"
);
assert_eq!(record.protocol, protocol());
}