use flyby::storage::{CustomFramer, Delimiter, FixedLength, Frame, LengthPrefixed, PrefixWidth};
#[test]
fn fixed_empty_buffer_returns_none() {
let mut f = FixedLength::new(8);
assert_eq!(f.next_record_len(&[]).unwrap(), None);
}
#[test]
fn fixed_partial_record_returns_none() {
let mut f = FixedLength::new(8);
assert_eq!(f.next_record_len(&[0u8; 7]).unwrap(), None);
}
#[test]
fn fixed_exact_boundary_returns_len() {
let mut f = FixedLength::new(8);
assert_eq!(f.next_record_len(&[0u8; 8]).unwrap(), Some(8));
}
#[test]
fn fixed_excess_bytes_still_returns_record_len() {
let mut f = FixedLength::new(8);
assert_eq!(f.next_record_len(&[0u8; 100]).unwrap(), Some(8));
}
#[test]
fn fixed_sequential_calls_return_same_len() {
let mut f = FixedLength::new(16);
let buf = vec![0u8; 100];
for _ in 0..5 {
assert_eq!(f.next_record_len(&buf).unwrap(), Some(16));
}
}
#[test]
fn lp_u8_empty_returns_none() {
let mut f = LengthPrefixed::new(PrefixWidth::U8, 256);
assert_eq!(f.next_record_len(&[]).unwrap(), None);
}
#[test]
fn lp_u8_zero_payload() {
let mut f = LengthPrefixed::new(PrefixWidth::U8, 256);
assert_eq!(f.next_record_len(&[0x00]).unwrap(), Some(1));
}
#[test]
fn lp_u8_full_record() {
let mut f = LengthPrefixed::new(PrefixWidth::U8, 256);
let mut buf = vec![5u8]; buf.extend_from_slice(b"hello");
assert_eq!(f.next_record_len(&buf).unwrap(), Some(6));
}
#[test]
fn lp_u8_partial_payload_returns_none() {
let mut f = LengthPrefixed::new(PrefixWidth::U8, 256);
let buf = vec![10u8, 0, 0, 0, 0];
assert_eq!(f.next_record_len(&buf).unwrap(), None);
}
#[test]
fn lp_u8_payload_exceeds_max_returns_err() {
let mut f = LengthPrefixed::new(PrefixWidth::U8, 3);
let buf = vec![10u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; assert!(f.next_record_len(&buf).is_err());
}
#[test]
fn lp_u16be_reads_two_byte_header() {
let mut f = LengthPrefixed::new(PrefixWidth::U16Be, 65535);
let mut buf = vec![0x01u8, 0x00]; buf.extend(vec![0u8; 256]);
assert_eq!(f.next_record_len(&buf).unwrap(), Some(258));
}
#[test]
fn lp_u32be_reads_four_byte_header() {
let mut f = LengthPrefixed::new(PrefixWidth::U32Be, 1024);
let mut buf = vec![0x00u8, 0x00, 0x00, 0x0A]; buf.extend(vec![0u8; 10]);
assert_eq!(f.next_record_len(&buf).unwrap(), Some(14));
}
#[test]
fn delim_empty_buffer_returns_none() {
let mut f = Delimiter::new(b'\n', 1024);
assert_eq!(f.next_record_len(&[]).unwrap(), None);
}
#[test]
fn delim_single_delimiter_byte() {
let mut f = Delimiter::new(b'\n', 1024);
assert_eq!(f.next_record_len(b"\n").unwrap(), Some(1));
}
#[test]
fn delim_delimiter_at_start() {
let mut f = Delimiter::new(b'|', 1024);
assert_eq!(f.next_record_len(b"|rest").unwrap(), Some(1));
}
#[test]
fn delim_typical_csv_line() {
let mut f = Delimiter::new(b'\n', 4096);
let line = b"2024-01-01,BTC/USD,42000.00,1.5\n";
assert_eq!(f.next_record_len(line).unwrap(), Some(line.len()));
}
#[test]
fn delim_no_delimiter_short_buf_returns_none() {
let mut f = Delimiter::new(b'\n', 100);
let buf = vec![b'x'; 50];
assert_eq!(f.next_record_len(&buf).unwrap(), None);
}
#[test]
fn delim_no_delimiter_at_max_len_returns_err() {
let mut f = Delimiter::new(b'\n', 10);
let buf = vec![b'x'; 10]; assert!(f.next_record_len(&buf).is_err());
}
#[test]
fn delim_delimiter_includes_byte_in_count() {
let mut f = Delimiter::new(b'\0', 1024);
assert_eq!(f.next_record_len(b"abc\0more").unwrap(), Some(4));
}
#[test]
fn custom_passthrough_always_returns_some() {
let mut f = CustomFramer::new(|buf: &[u8]| Ok(Some(buf.len())));
assert_eq!(f.next_record_len(b"anything").unwrap(), Some(8));
}
#[test]
fn custom_can_return_error() {
use flyby::core::{Error, ErrorKind};
let mut f =
CustomFramer::new(|_buf: &[u8]| Err(Error::new(ErrorKind::Decode, "corrupt magic")));
assert!(f.next_record_len(b"junk").is_err());
}
#[test]
fn custom_stateful_via_closure_captures() {
let mut toggle = false;
let mut f = CustomFramer::new(move |buf: &[u8]| {
let len = if toggle { 4 } else { 8 };
toggle = !toggle;
if buf.len() >= len {
Ok(Some(len))
} else {
Ok(None)
}
});
let buf = vec![0u8; 16];
assert_eq!(f.next_record_len(&buf).unwrap(), Some(8));
assert_eq!(f.next_record_len(&buf).unwrap(), Some(4));
}