use idun::parse::*;
#[test]
fn parse_eeg_packet_too_short() {
assert!(parse_eeg_packet(&[]).is_none());
assert!(parse_eeg_packet(&[0x01]).is_none());
}
#[test]
fn parse_eeg_packet_header() {
let data = vec![0xAA, 42, 1, 2, 3, 4, 5];
let header = parse_eeg_packet(&data).unwrap();
assert_eq!(header.tag, 0xAA);
assert_eq!(header.index, 42);
assert_eq!(header.payload, vec![1, 2, 3, 4, 5]);
}
#[test]
fn parse_eeg_packet_minimal() {
let data = vec![0x00, 0xFF];
let header = parse_eeg_packet(&data).unwrap();
assert_eq!(header.tag, 0x00);
assert_eq!(header.index, 255);
assert!(header.payload.is_empty());
}
#[test]
fn parse_impedance_empty() {
assert!(parse_impedance(&[]).is_none());
}
#[test]
fn parse_impedance_1byte() {
assert_eq!(parse_impedance(&[200]), Some(200));
}
#[test]
fn parse_impedance_2byte_le() {
assert_eq!(parse_impedance(&[0x34, 0x12]), Some(0x1234));
}
#[test]
fn parse_impedance_4byte_le() {
assert_eq!(parse_impedance(&[0x88, 0x13, 0x00, 0x00]), Some(5000));
}
#[test]
fn parse_impedance_3byte_le() {
assert_eq!(parse_impedance(&[0x40, 0x42, 0x0F]), Some(0x000F4240));
}
#[test]
fn parse_impedance_large_4byte() {
assert_eq!(
parse_impedance(&[0xFF, 0xFF, 0xFF, 0xFF]),
Some(u32::MAX)
);
}
#[test]
fn parse_impedance_extra_bytes_ignored() {
assert_eq!(
parse_impedance(&[0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF]),
Some(1)
);
}
#[test]
fn parse_eeg_packet_max_index() {
let data = vec![0x00, 0xFF, 0xAA];
let header = parse_eeg_packet(&data).unwrap();
assert_eq!(header.index, 255);
}
#[test]
fn parse_eeg_packet_large_payload() {
let mut data = vec![0xBB, 0x10];
data.extend_from_slice(&[0x80; 30]);
let header = parse_eeg_packet(&data).unwrap();
assert_eq!(header.tag, 0xBB);
assert_eq!(header.index, 16);
assert_eq!(header.payload.len(), 30);
}
#[cfg(feature = "local-decode")]
mod local_decode {
use idun::parse::*;
#[test]
fn try_decode_eeg_12bit_empty() {
let samples = try_decode_eeg_12bit(&[]);
assert!(samples.is_empty());
}
#[test]
fn try_decode_eeg_12bit_one_group() {
let samples = try_decode_eeg_12bit(&[0x80, 0x00, 0x00]);
assert_eq!(samples.len(), 2);
assert!((samples[0] - 0.0).abs() < 0.001);
assert!((samples[1] - (-1000.0)).abs() < 0.001);
}
#[test]
fn try_decode_eeg_12bit_mid_scale() {
let samples = try_decode_eeg_12bit(&[0x80, 0x08, 0x00]);
assert_eq!(samples.len(), 2);
assert!((samples[0] - 0.0).abs() < 0.001);
assert!((samples[1] - 0.0).abs() < 0.001);
}
#[test]
fn try_decode_eeg_12bit_multiple_groups() {
let payload = [0x80, 0x08, 0x00, 0x80, 0x08, 0x00];
let samples = try_decode_eeg_12bit(&payload);
assert_eq!(samples.len(), 4);
for s in &samples {
assert!((s - 0.0).abs() < 0.001);
}
}
#[test]
fn try_decode_eeg_12bit_partial_group_ignored() {
let samples = try_decode_eeg_12bit(&[0x80, 0x08, 0x00, 0xFF]);
assert_eq!(samples.len(), 2);
}
#[test]
fn compute_rms_empty() {
assert_eq!(compute_rms(&[]), 0.0);
}
#[test]
fn compute_rms_dc() {
let samples = vec![10.0, 10.0, 10.0, 10.0];
assert!((compute_rms(&samples) - 10.0).abs() < 0.001);
}
#[test]
fn compute_rms_symmetric() {
let samples = vec![-5.0, 5.0, -5.0, 5.0];
assert!((compute_rms(&samples) - 5.0).abs() < 0.001);
}
#[test]
fn try_decode_imu_too_short() {
assert!(try_decode_imu_i16le(&[0; 11]).is_none());
}
#[test]
fn try_decode_imu_zeros() {
let data = [0u8; 12];
let (accel, gyro) = try_decode_imu_i16le(&data).unwrap();
assert_eq!(accel.x, 0.0);
assert_eq!(accel.y, 0.0);
assert_eq!(accel.z, 0.0);
assert_eq!(gyro.x, 0.0);
assert_eq!(gyro.y, 0.0);
assert_eq!(gyro.z, 0.0);
}
#[test]
fn try_decode_imu_nonzero() {
let mut data = [0u8; 12];
data[0] = 0xE8; data[1] = 0x03; data[6] = 0xE8; data[7] = 0x03; let (accel, gyro) = try_decode_imu_i16le(&data).unwrap();
assert!((accel.x - 1000.0 * 0.0000610352).abs() < 0.001);
assert!((gyro.x - 1000.0 * 0.0074768).abs() < 0.01);
}
#[test]
fn parse_notification_short() {
assert!(parse_notification(&[]).is_empty());
assert!(parse_notification(&[0x01]).is_empty());
}
#[test]
fn try_decode_eeg_12bit_max_values() {
let samples = try_decode_eeg_12bit(&[0xFF, 0xFF, 0xFF]);
assert_eq!(samples.len(), 2);
assert!((samples[0] - 999.511).abs() < 0.01);
assert!((samples[1] - 999.511).abs() < 0.01);
}
#[test]
fn try_decode_eeg_12bit_min_values() {
let samples = try_decode_eeg_12bit(&[0x00, 0x00, 0x00]);
assert_eq!(samples.len(), 2);
assert!((samples[0] - (-1000.0)).abs() < 0.001);
assert!((samples[1] - (-1000.0)).abs() < 0.001);
}
#[test]
fn try_decode_imu_negative_values() {
let mut data = [0u8; 12];
let neg: i16 = -1000;
let bytes = neg.to_le_bytes();
data[0] = bytes[0]; data[1] = bytes[1]; data[6] = bytes[0]; data[7] = bytes[1]; let (accel, gyro) = try_decode_imu_i16le(&data).unwrap();
assert!(accel.x < 0.0);
assert!((accel.x - (-1000.0 * 0.0000610352)).abs() < 0.001);
assert!(gyro.x < 0.0);
assert!((gyro.x - (-1000.0 * 0.0074768)).abs() < 0.01);
}
#[test]
fn try_decode_imu_exact_12_bytes() {
let data = [0u8; 12];
assert!(try_decode_imu_i16le(&data).is_some());
}
#[test]
fn try_decode_imu_extra_bytes() {
let data = [0u8; 20];
assert!(try_decode_imu_i16le(&data).is_some());
}
#[test]
fn compute_rms_single_value() {
assert!((compute_rms(&[7.0]) - 7.0).abs() < 0.001);
}
#[test]
fn compute_rms_negative_values() {
assert!((compute_rms(&[-3.0, -3.0, -3.0]) - 3.0).abs() < 0.001);
}
#[test]
fn parse_notification_unknown_short_payload() {
let data = vec![0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
let results = parse_notification(&data);
assert!(!results.is_empty());
match &results[0] {
ParsedPacket::Unknown { index, tag, .. } => {
assert_eq!(*tag, 0x01);
assert_eq!(*index, 0x02);
}
_ => panic!("Expected Unknown variant for short payload"),
}
}
#[test]
fn parse_notification_produces_results() {
let mut data = vec![0xAA, 0x01];
data.extend_from_slice(&[0x80, 0x08, 0x00].repeat(10)); let results = parse_notification(&data);
assert!(!results.is_empty());
}
}