#![allow(clippy::unwrap_used, clippy::expect_used, reason = "unit tests")]
use super::{ObuType, read_leb128, split_obus};
use crate::DecodeError;
#[test]
fn leb128_single_byte_values_round_trip() {
assert_eq!(read_leb128(&[0x00]).unwrap(), (0, 1));
assert_eq!(read_leb128(&[0x7F]).unwrap(), (127, 1));
}
#[test]
fn leb128_multi_byte_boundary_values_round_trip() {
assert_eq!(read_leb128(&[0x80, 0x01]).unwrap(), (128, 2));
assert_eq!(read_leb128(&[0xAC, 0x02]).unwrap(), (300, 2));
assert_eq!(read_leb128(&[0x00, 0xFF]).unwrap(), (0, 1));
}
#[test]
fn leb128_truncated_continuation_is_invalid_input() {
let err = read_leb128(&[0x80]).unwrap_err();
assert!(matches!(err, DecodeError::InvalidInput));
}
#[test]
fn leb128_never_terminating_within_8_bytes_is_invalid_input() {
let bytes = [0x80u8; 8];
let err = read_leb128(&bytes).unwrap_err();
assert!(matches!(err, DecodeError::InvalidInput));
}
fn wrap_obu(obu_type: u8, payload: &[u8]) -> Vec<u8> {
let mut out = vec![(obu_type << 3) | 0b10];
let len = u8::try_from(payload.len()).unwrap();
out.push(len); out.extend_from_slice(payload);
out
}
#[test]
fn split_obus_temporal_delimiter_sequence_header_and_frame() {
let mut packet = wrap_obu(2, &[]); packet.extend(wrap_obu(1, &[0xAA, 0xBB])); packet.extend(wrap_obu(6, &[0x01, 0x02, 0x03]));
let obus = split_obus(&packet).unwrap();
assert_eq!(obus.len(), 3);
assert_eq!(obus[0].obu_type, ObuType::TemporalDelimiter);
assert!(obus[0].payload.is_empty());
assert_eq!(obus[1].obu_type, ObuType::SequenceHeader);
assert_eq!(obus[1].payload, &[0xAA, 0xBB]);
assert_eq!(obus[2].obu_type, ObuType::Frame);
assert_eq!(obus[2].payload, &[0x01, 0x02, 0x03]);
}
#[test]
fn split_obus_empty_packet_returns_empty() {
assert!(split_obus(&[]).unwrap().is_empty());
}
#[test]
fn split_obus_maps_every_documented_type() {
for (raw, expected) in [
(1u8, ObuType::SequenceHeader),
(2, ObuType::TemporalDelimiter),
(3, ObuType::FrameHeader),
(4, ObuType::TileGroup),
(6, ObuType::Frame),
(7, ObuType::RedundantFrameHeader),
(15, ObuType::Other(15)),
] {
let packet = wrap_obu(raw, &[]);
let obus = split_obus(&packet).unwrap();
assert_eq!(obus[0].obu_type, expected, "raw obu_type {raw}");
}
}
#[test]
fn split_obus_rejects_forbidden_bit_set() {
let packet = vec![0x80, 0x00]; let err = split_obus(&packet).unwrap_err();
assert!(matches!(err, DecodeError::InvalidInput));
}
#[test]
fn split_obus_rejects_extension_flag() {
let packet = vec![0b0000_1110u8];
let err = split_obus(&packet).unwrap_err();
assert!(matches!(err, DecodeError::Unsupported));
}
#[test]
fn split_obus_rejects_missing_size_field() {
let packet = vec![0b0000_1000u8];
let err = split_obus(&packet).unwrap_err();
assert!(matches!(err, DecodeError::Unsupported));
}
#[test]
fn split_obus_rejects_truncated_payload() {
let packet = vec![0x0A, 0x05, 0xAA, 0xBB];
let err = split_obus(&packet).unwrap_err();
assert!(matches!(err, DecodeError::InvalidInput));
}