use noxu_bind::{EntityBinding, EntryBinding, SerdeBinding, TupleSerdeBinding};
use noxu_db::DatabaseEntry;
use serde::{Deserialize, Serialize};
fn primitive_round_trip<T>(val: T)
where
T: Serialize + serde::de::DeserializeOwned + PartialEq + std::fmt::Debug,
{
let binding = SerdeBinding::<T>::new();
let mut buf = DatabaseEntry::new();
binding.object_to_entry(&val, &mut buf).unwrap();
assert!(
!buf.data().is_empty(),
"encoded entry must contain the version header at minimum"
);
let val2 = binding.entry_to_object(&buf).unwrap();
assert_eq!(val, val2);
}
#[test]
fn tck_serial_primitive_bindings() {
primitive_round_trip("abc".to_string());
primitive_round_trip('a');
primitive_round_trip(true);
primitive_round_trip(false);
primitive_round_trip(123_i8);
primitive_round_trip(123_i16);
primitive_round_trip(123_i32);
primitive_round_trip(123_i64);
primitive_round_trip(123.123_f32);
primitive_round_trip(123.123_f64);
}
#[test]
fn tck_serial_null_objects() {
let binding = SerdeBinding::<Option<String>>::new();
let mut buf = DatabaseEntry::new();
binding.object_to_entry(&None, &mut buf).unwrap();
assert!(
!buf.data().is_empty(),
"encoded None must include the version header (and the None tag)"
);
let result = binding.entry_to_object(&buf).unwrap();
assert_eq!(None, result);
}
#[test]
fn tck_serial_serial_binding_pair_round_trip() {
let key_binding = SerdeBinding::<String>::new();
let value_binding = SerdeBinding::<String>::new();
let key = "key#value?indexKey".to_string();
let value = "the-value".to_string();
let mut key_buf = DatabaseEntry::new();
let mut val_buf = DatabaseEntry::new();
key_binding.object_to_entry(&key, &mut key_buf).unwrap();
value_binding.object_to_entry(&value, &mut val_buf).unwrap();
assert!(!key_buf.data().is_empty());
assert!(!val_buf.data().is_empty());
assert_eq!(key, key_binding.entry_to_object(&key_buf).unwrap());
assert_eq!(value, value_binding.entry_to_object(&val_buf).unwrap());
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct Person {
name: String,
age: u32,
}
#[test]
fn tck_tuple_serial_marshalled_binding_round_trip() {
let binding = TupleSerdeBinding::<String, Person>::new(
|p: &Person| p.name.clone(),
|_k, v| v,
);
let original = Person { name: "Alice".to_string(), age: 30 };
let mut key_buf = DatabaseEntry::new();
let mut data_buf = DatabaseEntry::new();
binding.object_to_key(&original, &mut key_buf).unwrap();
binding.object_to_data(&original, &mut data_buf).unwrap();
assert!(!key_buf.data().is_empty());
assert!(!data_buf.data().is_empty());
let decoded = binding.entry_to_object(&key_buf, &data_buf).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn tck_serial_buffer_overhead_is_constant() {
let binding = SerdeBinding::<u32>::new();
let mut buf_small = DatabaseEntry::new();
let mut buf_big = DatabaseEntry::new();
binding.object_to_entry(&0u32, &mut buf_small).unwrap();
binding.object_to_entry(&u32::MAX, &mut buf_big).unwrap();
assert_eq!(buf_small.data()[..2], buf_big.data()[..2]);
assert_eq!(buf_small.data()[0], 0xCB); assert_eq!(buf_small.data()[1], 0x01); }
#[test]
fn tck_serial_encoding_is_deterministic() {
let value = ("hello".to_string(), 42u64, true);
let b1 = SerdeBinding::<(String, u64, bool)>::new();
let b2 = SerdeBinding::<(String, u64, bool)>::new();
let mut e1 = DatabaseEntry::new();
let mut e2 = DatabaseEntry::new();
b1.object_to_entry(&value, &mut e1).unwrap();
b2.object_to_entry(&value, &mut e2).unwrap();
assert_eq!(e1.data(), e2.data());
}
#[test]
fn tck_serde_version_header_rejects_missing_header() {
let mut entry = DatabaseEntry::new();
entry.set_data_vec(vec![]); let binding = SerdeBinding::<u32>::new();
let err = binding.entry_to_object(&entry).unwrap_err();
assert!(
matches!(err, noxu_bind::BindError::VersionMismatch { .. }),
"expected VersionMismatch on empty payload, got {err:?}",
);
}
#[test]
fn tck_serde_version_header_rejects_wrong_magic() {
let mut entry = DatabaseEntry::new();
entry.set_data_vec(vec![0x00, 0x01, 0x02, 0x03]);
let binding = SerdeBinding::<u32>::new();
let err = binding.entry_to_object(&entry).unwrap_err();
assert!(
matches!(
err,
noxu_bind::BindError::VersionMismatch { found_magic: 0x00, .. }
),
"expected VersionMismatch with found_magic=0x00, got {err:?}",
);
}
#[test]
fn tck_serde_version_header_rejects_wrong_version() {
let mut entry = DatabaseEntry::new();
entry.set_data_vec(vec![0xCB, 0xFF, 0x00]);
let binding = SerdeBinding::<u32>::new();
let err = binding.entry_to_object(&entry).unwrap_err();
assert!(
matches!(
err,
noxu_bind::BindError::VersionMismatch {
found_magic: 0xCB,
found_version: 0xFF,
..
}
),
"expected VersionMismatch with found_magic=0xCB found_version=0xFF, got {err:?}",
);
}