use std::fs;
use dvb_vbi::{DataField, DataUnitId, DataUnitPayload};
fn fixture() -> Vec<u8> {
let path = concat!(
env!("CARGO_MANIFEST_DIR"),
"/../fixtures/dvb-vbi/vbi_data_field.bin"
);
fs::read(path).expect("fixture vbi_data_field.bin must be committed")
}
#[test]
fn parses_fixture_fields() {
let data = fixture();
let field = DataField::parse(&data).expect("fixture must parse");
assert_eq!(field.data_identifier, 0x10);
assert_eq!(field.data_units.len(), 6, "6 data units");
let ids: Vec<DataUnitId> = field.data_units.iter().map(|u| u.id).collect();
assert_eq!(
ids,
vec![
DataUnitId::EbuTeletextNonSubtitle,
DataUnitId::Vps,
DataUnitId::Wss,
DataUnitId::ClosedCaptioning,
DataUnitId::Monochrome422Samples,
DataUnitId::Stuffing,
]
);
match &field.data_units[0].payload {
DataUnitPayload::Teletext(f) => {
assert_eq!(f.header.line_offset, 7);
assert!(f.header.field_parity);
assert_eq!(f.framing_code, dvb_vbi::FRAMING_CODE_EBU);
assert_eq!(f.txt_data_block.len(), dvb_vbi::TXT_DATA_BLOCK_LEN);
}
_ => panic!("expected Teletext"),
}
assert_eq!(
field.data_units[0].data_unit_length(),
dvb_vbi::TELETEXT_DATA_UNIT_LENGTH as usize
);
match &field.data_units[1].payload {
DataUnitPayload::Vps(f) => {
assert_eq!(f.header.line_offset, 16);
assert!(f.header.field_parity);
assert_eq!(f.vps_data_block.len(), dvb_vbi::VPS_DATA_BLOCK_LEN);
}
_ => panic!("expected VPS"),
}
match &field.data_units[2].payload {
DataUnitPayload::Wss(f) => {
assert_eq!(f.header.line_offset, 23);
assert_eq!(f.wss_data_block, 0x2A55);
}
_ => panic!("expected WSS"),
}
match &field.data_units[3].payload {
DataUnitPayload::ClosedCaptioning(f) => {
assert_eq!(f.header.line_offset, 21);
assert_eq!(f.closed_captioning_data_block, 0x9425);
}
_ => panic!("expected Closed Captioning"),
}
match &field.data_units[4].payload {
DataUnitPayload::Monochrome(f) => {
assert!(f.first_segment && f.last_segment && f.field_parity);
assert_eq!(f.line_offset, 10);
assert_eq!(f.first_pixel_position, 0);
assert_eq!(f.samples.len(), 6);
}
_ => panic!("expected Monochrome"),
}
match &field.data_units[5].payload {
DataUnitPayload::Stuffing { length } => assert_eq!(*length, 3),
_ => panic!("expected Stuffing"),
}
}
#[test]
fn fixture_byte_exact_round_trip() {
let data = fixture();
let field = DataField::parse(&data).unwrap();
let mut out = vec![0u8; field.serialized_len()];
let n = field.serialize_into(&mut out).unwrap();
assert_eq!(n, data.len());
assert_eq!(out, data, "serialize must be byte-identical to the fixture");
assert_eq!(DataField::parse(&out).unwrap(), field);
}
#[test]
fn truncating_the_fixture_fails_to_parse() {
let mut data = fixture();
data.pop();
assert!(
DataField::parse(&data).is_err(),
"a truncated data unit must be rejected"
);
}
#[cfg(feature = "serde")]
#[test]
fn serde_serializes() {
let data = fixture();
let field = DataField::parse(&data).unwrap();
let json = serde_json::to_string(&field).expect("serde must serialize");
assert!(json.contains("\"data_identifier\""));
assert!(json.contains("Vps") || json.contains("vps"));
}