//! Checks `kv_sync::replay` against the shared decision table (kestrove-spec/vectors/item_replay.json). use kv_sync::replay::{check_successor, next_version, Base}; use serde_json::Value; fn vectors() -> Value { serde_json::from_str(include_str!("vectors/item_replay.json")).unwrap() } fn base(v: &Value) -> Base<'_> { if v.is_null() { return Base::None; } let revision = v["revision"].as_u64().unwrap(); if v["tombstone"] == Value::Bool(true) { Base::Tombstone { revision } } else { Base::Live { revision, item: &v["item"] } } } #[test] fn check_table() { for case in vectors()["check"].as_array().unwrap() { let got = check_successor(base(&case["base"]), case["revision"].as_u64().unwrap(), &case["incoming"]); let want = case["result"].as_str().unwrap(); assert_eq!(if got.is_ok() { "accept" } else { "alarm" }, want, "{}", case["name"]); } } #[test] fn next_version_table() { for case in vectors()["next_version"].as_array().unwrap() { let local = Some(&case["local"]).filter(|v| !v.is_null()); let (seq, restores) = next_version(local, base(&case["base"])); assert_eq!(Some(seq), case["seq"].as_u64(), "{}", case["name"]); assert_eq!(restores, case["restores"].as_u64(), "{}", case["name"]); } } #[test] fn spec_copy_is_identical() { let spec = concat!(env!("CARGO_MANIFEST_DIR"), "/../../../kestrove-spec/vectors/item_replay.json"); if let Ok(s) = std::fs::read_to_string(spec) { assert_eq!(s, include_str!("vectors/item_replay.json"), "kestrove-spec copy differs"); } }