97 lines
3.8 KiB
Rust
97 lines
3.8 KiB
Rust
use proptest::prelude::*;
|
|
|
|
use pipeview_core::frame::Framer;
|
|
use pipeview_core::frame::cobs::{CobsFramer, cobs_decode, cobs_encode};
|
|
use pipeview_core::frame::length::{LengthConfig, LengthPrefixedFramer};
|
|
use pipeview_core::protocol::Endian;
|
|
use pipeview_core::protocol::ProtocolDecoder;
|
|
use pipeview_core::protocol::hex::{HexConfig, HexDecoder};
|
|
use pipeview_core::protocol::plot::{PlotConfig, PlotDecoder, SampleType};
|
|
use pipeview_core::protocol::text::{TextDecoder, TextEncoding};
|
|
|
|
proptest! {
|
|
#![proptest_config(ProptestConfig::with_cases(256))]
|
|
|
|
// ── COBS ─────────────────────────────────────────────────────────
|
|
|
|
#[test]
|
|
fn cobs_roundtrip_any_payload(payload in prop::collection::vec(any::<u8>(), 0..512)) {
|
|
let encoded = cobs_encode(&payload);
|
|
let decoded = cobs_decode(&encoded).unwrap();
|
|
prop_assert_eq!(&decoded, &payload);
|
|
|
|
let mut framer = CobsFramer::new(1024 * 1024);
|
|
let mut wire = encoded;
|
|
wire.push(0x00);
|
|
let frames = framer.feed(&wire);
|
|
prop_assert_eq!(frames.len(), 1);
|
|
prop_assert_eq!(&frames[0], &payload);
|
|
}
|
|
|
|
// ── Length-prefixed ──────────────────────────────────────────────
|
|
|
|
#[test]
|
|
fn length_roundtrip_any_payload(
|
|
len_bytes in prop_oneof![Just(1usize), Just(2usize), Just(4usize)],
|
|
little_endian in any::<bool>(),
|
|
includes_self in any::<bool>(),
|
|
payload in prop::collection::vec(any::<u8>(), 0..200)
|
|
) {
|
|
let endian = if little_endian { Endian::Little } else { Endian::Big };
|
|
let raw_len = if includes_self {
|
|
payload.len() + len_bytes
|
|
} else {
|
|
payload.len()
|
|
};
|
|
|
|
let mut wire = Vec::with_capacity(len_bytes + payload.len());
|
|
match (len_bytes, endian) {
|
|
(1, _) => wire.push(raw_len as u8),
|
|
(2, Endian::Big) => wire.extend_from_slice(&(raw_len as u16).to_be_bytes()),
|
|
(2, Endian::Little) => wire.extend_from_slice(&(raw_len as u16).to_le_bytes()),
|
|
(4, Endian::Big) => wire.extend_from_slice(&(raw_len as u32).to_be_bytes()),
|
|
(4, Endian::Little) => wire.extend_from_slice(&(raw_len as u32).to_le_bytes()),
|
|
_ => unreachable!(),
|
|
}
|
|
wire.extend_from_slice(&payload);
|
|
|
|
let config = LengthConfig {
|
|
len_bytes,
|
|
endian,
|
|
length_includes_self: includes_self,
|
|
max_payload: 1024 * 1024,
|
|
};
|
|
let mut framer = LengthPrefixedFramer::new(config);
|
|
let frames = framer.feed(&wire);
|
|
prop_assert_eq!(frames.len(), 1);
|
|
prop_assert_eq!(&frames[0], &payload);
|
|
}
|
|
|
|
// ── Protocol decoders never panic on arbitrary bytes ─────────────
|
|
|
|
#[test]
|
|
fn plot_decode_arbitrary_bytes_never_panics(bytes in prop::collection::vec(any::<u8>(), 0..256)) {
|
|
let decoder = PlotDecoder::new(PlotConfig {
|
|
sample_type: SampleType::F32,
|
|
endian: Endian::Little,
|
|
channels: 2,
|
|
format: pipeview_core::protocol::plot::PlotFormat::Interleaved,
|
|
});
|
|
let _ = decoder.decode(&bytes);
|
|
}
|
|
|
|
#[test]
|
|
fn hex_decode_arbitrary_bytes_never_panics(bytes in prop::collection::vec(any::<u8>(), 0..256)) {
|
|
let decoder = HexDecoder::new(HexConfig::default());
|
|
let decoded = decoder.decode(&bytes);
|
|
prop_assert!(decoded.is_some());
|
|
}
|
|
|
|
#[test]
|
|
fn latin1_decode_arbitrary_bytes_never_panics(bytes in prop::collection::vec(any::<u8>(), 0..256)) {
|
|
let decoder = TextDecoder::new(TextEncoding::Latin1);
|
|
let decoded = decoder.decode(&bytes);
|
|
prop_assert!(decoded.is_some());
|
|
}
|
|
}
|