diff options
Diffstat (limited to 'tests/len_prefix.rs')
| -rw-r--r-- | tests/len_prefix.rs | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/tests/len_prefix.rs b/tests/len_prefix.rs new file mode 100644 index 0000000..d9597eb --- /dev/null +++ b/tests/len_prefix.rs @@ -0,0 +1,310 @@ +use zr_protocol::{ + codec::{decode::Decode, encode::Encode}, + types::prefix::length::LenPrefixed, +}; + +fn encode_to_bytes<T: Encode>(value: T) -> Vec<u8> { + let mut buf = Vec::new(); + value.encode(&mut buf).unwrap(); + buf +} + +// ────────────────────── Données simples ───────── + +#[test] +fn simple_u32_with_u8_length() { + let lp = LenPrefixed::<u8, u32>::new(42u32); + let buf = encode_to_bytes(lp); + assert_eq!(buf, vec![0x04, 0x00, 0x00, 0x00, 0x2A]); +} + +#[test] +fn simple_u16_with_u16_length() { + let lp = LenPrefixed::<u16, u16>::new(256u16); + let buf = encode_to_bytes(lp); + assert_eq!(buf, vec![0x00, 0x02, 0x01, 0x00]); +} + +#[test] +fn simple_u8_with_u8_length() { + let lp = LenPrefixed::<u8, u8>::new(0xABu8); + let buf = encode_to_bytes(lp); + assert_eq!(buf, vec![0x01, 0xAB]); +} + +#[test] +fn simple_u64_with_u32_length() { + let lp = LenPrefixed::<u32, u64>::new(0x0102030405060708u64); + let buf = encode_to_bytes(lp); + assert_eq!( + buf, + vec![0x00, 0x00, 0x00, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08] + ); +} + +// ────────────────────── Booléen ───────────────── + +#[test] +fn bool_true_with_u8_length() { + let lp = LenPrefixed::<u8, bool>::new(true); + let buf = encode_to_bytes(lp); + assert_eq!(buf, vec![0x01, 0x01]); +} + +#[test] +fn bool_false_with_u8_length() { + let lp = LenPrefixed::<u8, bool>::new(false); + let buf = encode_to_bytes(lp); + assert_eq!(buf, vec![0x01, 0x00]); +} + +// ────────────────────── Tableaux ──────────────── + +#[test] +fn array_4_bytes_with_u8_length() { + let lp = LenPrefixed::<u8, [u8; 4]>::new([0x01, 0x02, 0x03, 0x04]); + let buf = encode_to_bytes(lp); + assert_eq!(buf, vec![0x04, 0x01, 0x02, 0x03, 0x04]); +} + +#[test] +fn array_16_bytes_with_u16_length() { + let data: [u8; 16] = std::array::from_fn(|i| i as u8); + let lp = LenPrefixed::<u16, [u8; 16]>::new(data); + let buf = encode_to_bytes(lp); + assert_eq!(buf[0..2], [0x00, 0x10]); + assert_eq!(&buf[2..], &data[..]); +} + +#[test] +fn array_256_bytes_with_u16_length() { + let data: [u8; 256] = std::array::from_fn(|i| (i % 256) as u8); + let lp = LenPrefixed::<u16, [u8; 256]>::new(data); + let buf = encode_to_bytes(lp); + assert_eq!(buf[0..2], [0x01, 0x00]); + assert_eq!(&buf[2..], &data[..]); +} + +// ────────────────────── Roundtrip ─────────────── + +#[test] +fn roundtrip_u32_u8() { + let lp = LenPrefixed::<u8, u32>::new(42u32); + let buf = encode_to_bytes(lp); + + let mut reader = &buf[..]; + let decoded = LenPrefixed::<u8, u32>::decode(&mut reader).unwrap(); + assert_eq!(*decoded.as_ref(), 42u32); +} + +#[test] +fn roundtrip_u64_u16() { + let lp = LenPrefixed::<u16, u64>::new(u64::MAX); + let buf = encode_to_bytes(lp); + + let mut reader = &buf[..]; + let decoded = LenPrefixed::<u16, u64>::decode(&mut reader).unwrap(); + assert_eq!(*decoded.as_ref(), u64::MAX); +} + +#[test] +fn roundtrip_bool_u8() { + let lp = LenPrefixed::<u8, bool>::new(true); + let buf = encode_to_bytes(lp); + + let mut reader = &buf[..]; + let decoded = LenPrefixed::<u8, bool>::decode(&mut reader).unwrap(); + assert!(*decoded.as_ref()); +} + +#[test] +fn roundtrip_array_u8() { + let data = [0xDE, 0xAD, 0xBE, 0xEF]; + let lp = LenPrefixed::<u8, [u8; 4]>::new(data); + let buf = encode_to_bytes(lp); + + let mut reader = &buf[..]; + let decoded = LenPrefixed::<u8, [u8; 4]>::decode(&mut reader).unwrap(); + assert_eq!(*decoded.as_ref(), data); +} + +#[test] +fn roundtrip_negative_i32() { + let lp = LenPrefixed::<u8, i32>::new(-12345); + let buf = encode_to_bytes(lp); + + let mut reader = &buf[..]; + let decoded = LenPrefixed::<u8, i32>::decode(&mut reader).unwrap(); + assert_eq!(*decoded.as_ref(), -12345); +} + +#[test] +fn roundtrip_f64() { + let lp = LenPrefixed::<u8, f64>::new(3.141592653589793); + let buf = encode_to_bytes(lp); + + let mut reader = &buf[..]; + let decoded = LenPrefixed::<u8, f64>::decode(&mut reader).unwrap(); + assert_eq!(*decoded.as_ref(), 3.141592653589793); +} + +#[test] +fn roundtrip_u128() { + let lp = LenPrefixed::<u16, u128>::new(u128::MAX); + let buf = encode_to_bytes(lp); + + let mut reader = &buf[..]; + let decoded = LenPrefixed::<u16, u128>::decode(&mut reader).unwrap(); + assert_eq!(*decoded.as_ref(), u128::MAX); +} + +// ────────────────────── Imbrication ───────────── + +#[test] +fn nested_len_prefixed_u16_u8_u32() { + let inner = LenPrefixed::<u8, u32>::new(42u32); + let outer = LenPrefixed::<u16, LenPrefixed<u8, u32>>::new(inner); + let buf = encode_to_bytes(outer); + + // outer length = 1 (u8 prefix of inner) + 4 (u32) = 5 + assert_eq!(buf[0..2], [0x00, 0x05]); + // inner length = 4 + assert_eq!(buf[2], 0x04); + // inner data = 42 + assert_eq!(&buf[3..7], &[0x00, 0x00, 0x00, 0x2A]); +} + +#[test] +fn roundtrip_nested() { + let inner = LenPrefixed::<u8, u16>::new(1337u16); + let outer = LenPrefixed::<u16, LenPrefixed<u8, u16>>::new(inner); + let buf = encode_to_bytes(outer); + + let mut reader = &buf[..]; + let decoded_outer = LenPrefixed::<u16, LenPrefixed<u8, u16>>::decode(&mut reader).unwrap(); + let decoded_inner = decoded_outer.as_ref(); + assert_eq!(decoded_inner.as_ref(), &1337u16); +} + +#[test] +fn triple_nested() { + let l1 = LenPrefixed::<u8, u8>::new(0xAA); + let l2 = LenPrefixed::<u8, LenPrefixed<u8, u8>>::new(l1); + let l3 = LenPrefixed::<u16, LenPrefixed<u8, LenPrefixed<u8, u8>>>::new(l2); + let buf = encode_to_bytes(l3); + + let mut reader = &buf[..]; + let d3 = LenPrefixed::<u16, LenPrefixed<u8, LenPrefixed<u8, u8>>>::decode(&mut reader).unwrap(); + let d2 = d3.as_ref(); + let d1 = d2.as_ref(); + assert_eq!(*d1.as_ref(), 0xAAu8); +} + +// ────────────────────── Erreurs de décodage ───── + +#[test] +fn decode_empty_buffer_fails() { + let result = LenPrefixed::<u8, u32>::decode(&mut &[][..]); + assert!(result.is_err()); +} + +#[test] +fn decode_truncated_length_fails() { + let result = LenPrefixed::<u16, u32>::decode(&mut &[0x01][..]); + assert!(result.is_err()); +} + +#[test] +fn decode_length_exceeds_data_fails() { + let mut buf = Vec::new(); + 100u8.encode(&mut buf).unwrap(); + buf.extend_from_slice(&[0x01, 0x02]); + let result = LenPrefixed::<u8, u32>::decode(&mut &buf[..]); + assert!(result.is_err()); +} + +#[test] +fn decode_zero_length_with_zero_sized_type() { + let lp = LenPrefixed::<u8, [u8; 0]>::new([]); + let buf = encode_to_bytes(lp); + let mut reader = &buf[..]; + let decoded = LenPrefixed::<u8, [u8; 0]>::decode(&mut reader).unwrap(); + assert_eq!(*decoded.as_ref(), []); +} + +// ────────────────────── AsRef / AsMut ─────────── + +#[test] +fn as_ref_returns_inner() { + let lp = LenPrefixed::<u8, u32>::new(99u32); + assert_eq!(*lp.as_ref(), 99u32); +} + +#[test] +fn as_mut_allows_mutation() { + let mut lp = LenPrefixed::<u8, u32>::new(1u32); + *lp.as_mut() = 42; + assert_eq!(*lp.as_ref(), 42); +} + +// ────────────────────── Taille du buffer ──────── + +#[test] +fn u8_length_header_size() { + let lp = LenPrefixed::<u8, u8>::new(0); + let buf = encode_to_bytes(lp); + assert_eq!(buf.len(), 2); // 1 byte length + 1 byte data +} + +#[test] +fn u16_length_header_size() { + let lp = LenPrefixed::<u16, u8>::new(0); + let buf = encode_to_bytes(lp); + assert_eq!(buf.len(), 3); // 2 byte length + 1 byte data +} + +#[test] +fn u32_length_header_size() { + let lp = LenPrefixed::<u32, u8>::new(0); + let buf = encode_to_bytes(lp); + assert_eq!(buf.len(), 5); // 4 byte length + 1 byte data +} + +#[test] +fn u64_length_header_size() { + let lp = LenPrefixed::<u64, u8>::new(0); + let buf = encode_to_bytes(lp); + assert_eq!(buf.len(), 9); // 8 byte length + 1 byte data +} + +#[test] +fn large_data_length_correct() { + let data: [u8; 1000] = std::array::from_fn(|i| (i % 256) as u8); + let lp = LenPrefixed::<u16, [u8; 1000]>::new(data); + let buf = encode_to_bytes(lp); + assert_eq!(buf.len(), 2 + 1000); + assert_eq!(&buf[0..2], &[0x03, 0xE8]); // 1000 in u16 big-endian +} + +// ────────────────────── Sérialisation exacte ──── + +#[test] +fn exact_bytes_u8_prefix() { + let lp = LenPrefixed::<u8, u16>::new(256u16); + let buf = encode_to_bytes(lp); + assert_eq!(buf, vec![0x02, 0x01, 0x00]); +} + +#[test] +fn exact_bytes_negative_i16() { + let lp = LenPrefixed::<u8, i16>::new(-1); + let buf = encode_to_bytes(lp); + assert_eq!(buf, vec![0x02, 0xFF, 0xFF]); +} + +#[test] +fn exact_bytes_zero_u32() { + let lp = LenPrefixed::<u8, u32>::new(0u32); + let buf = encode_to_bytes(lp); + assert_eq!(buf, vec![0x04, 0x00, 0x00, 0x00, 0x00]); +} |
