use proptest::prelude::*;
use tekhsi_rs::data::{AnalogSamples, Waveform};
use tekhsi_rs::{WaveformHeader, WfmType, decode_waveform_chunks};
fn make_header(wfm_type: WfmType, width: i32, samples: i32) -> WaveformHeader {
WaveformHeader {
wfmtype: wfm_type as i32,
sourcewidth: width as u32,
noofsamples: samples as u64,
sourcename: "test".to_string(),
verticalunits: "V".to_string(),
horizontal_units: "s".to_string(),
iq_window_type: "Rectangle".to_string(),
hasdata: true,
chunksize: 1024,
..Default::default()
}
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(1000))]
#[test]
fn prop_decode_analog_f32_no_panic(
sample_count in 0..10_000i32,
chunks in proptest::collection::vec(proptest::collection::vec(any::<u8>(), 0..100), 0..50)
) {
let header = make_header(WfmType::WfmtypeAnalogFloat, 4, sample_count);
let result = decode_waveform_chunks(&header, &chunks);
if let Ok(Waveform::Analog(wfm)) = result {
assert_eq!(wfm.y_axis_values.len(), sample_count as usize);
}
}
#[test]
fn prop_decode_analog_i16_no_panic(
sample_count in 0..10_000i32,
chunks in proptest::collection::vec(proptest::collection::vec(any::<u8>(), 0..100), 0..50)
) {
let header = make_header(WfmType::WfmtypeAnalog16, 2, sample_count);
let result = decode_waveform_chunks(&header, &chunks);
if let Ok(Waveform::Analog(wfm)) = result {
assert_eq!(wfm.y_axis_values.len(), sample_count as usize);
}
}
#[test]
fn prop_decode_digital_i16_no_panic(
sample_count in 0..10_000i32,
chunks in proptest::collection::vec(proptest::collection::vec(any::<u8>(), 0..100), 0..50)
) {
let header = make_header(WfmType::WfmtypeDigital16, 2, sample_count);
let result = decode_waveform_chunks(&header, &chunks);
if let Ok(Waveform::Digital(wfm)) = result {
assert_eq!(wfm.y_axis_bytes.len(), sample_count as usize);
}
}
#[test]
fn prop_decode_f32_split_across_chunks(
values in proptest::collection::vec(any::<f32>(), 1..1000),
split_idx in 1..3999usize ) {
let sample_count = values.len() as i32;
let header = make_header(WfmType::WfmtypeAnalogFloat, 4, sample_count);
let mut all_bytes = Vec::new();
for v in &values {
all_bytes.extend_from_slice(&v.to_le_bytes());
}
let split = split_idx % all_bytes.len();
if split == 0 { return Ok(()); }
let (first, second) = all_bytes.split_at(split);
let chunks = vec![first.to_vec(), second.to_vec()];
let result = decode_waveform_chunks(&header, &chunks).expect("should succeed");
if let Waveform::Analog(wfm) = result {
if let AnalogSamples::F32(decoded) = wfm.y_axis_values {
assert_eq!(decoded, values);
} else {
panic!("Wrong sample type");
}
}
}
}