Lint the test code, and fix the 74 findings it had been hiding
Every other repo's CI now runs clippy with --all-targets. libfreemkv, the crate the other seven build against and the one held up as the reference workflow, was the last one still linting the library only — so its ~3,000 tests, by far the largest body of test code in the project, had never been linted at all. Turning the flag on surfaced 74 findings. Most were mechanical and applied with clippy --fix. The rest, by hand: - Four discarded Results in decrypt.rs. css::descramble_region returns a Result and four CSS tests threw it away, so a descramble that FAILED would have surfaced as a confusing buffer-comparison mismatch instead of the actual error. They expect() now. - A dead `kp` field on the PlantedWalk fixture. The test deliberately asserts Kp as the explicit AES-G3(dk, 1) relation from [C] §3.2.4 rather than against a stored value — its doc comment says so — which makes the field not just unused but a trap: the obvious "fix" of asserting against it would quietly weaken the test to comparing the fixture with itself. Removed. - Two hand-rolled ICB counters in the HD-DVD fixtures, a needless mut, three vec!s that only ever needed arrays, a filter_map whose every arm was Some, and a Vec::new()+push chain. - Doc list indentation in mkv.rs and mp4/read.rs, which was mis-rendering in the generated docs. - A five-[u8; 16]-tuple return type named FourLevelParts. Three lints are allowed at the specific sites, with reasons, because they are wrong for this domain: the underscores in the bitstream-header literals mark BITFIELD boundaries, not digit groups, so regrouping them uniformly would satisfy the lint by destroying the only thing they encode; and in three table-validation loops the loop variable is the domain value under test (a DTS SFREQ code, an AMODE value, a palette entry number), which is what the assertion messages name.
This commit is contained in:
@@ -1738,7 +1738,7 @@ mod tests {
|
||||
/// byte 5 = bsid 16 so the E-AC-3 paths are taken. CRC finalized so the frame
|
||||
/// passes the decodability gate.
|
||||
fn make_eac3_frame(strmtyp: u8, substreamid: u8, size: usize) -> Vec<u8> {
|
||||
assert!(size >= MIN_FRAME_BYTES && size % 2 == 0);
|
||||
assert!(size >= MIN_FRAME_BYTES && size.is_multiple_of(2));
|
||||
let frmsiz = size / 2 - 1;
|
||||
let mut f = vec![0u8; size];
|
||||
f[0] = 0x0B;
|
||||
|
||||
@@ -921,7 +921,7 @@ mod tests {
|
||||
let core = make_dts_core(512);
|
||||
let garbage = vec![0xE4, 0x3F, 0xE3, 0x90, 0xCC, 0x6C]; // real Bourne head bytes
|
||||
let mut garbage = garbage;
|
||||
garbage.extend(std::iter::repeat(0xAB).take(300));
|
||||
garbage.extend(std::iter::repeat_n(0xAB, 300));
|
||||
let next = make_dts_core(512);
|
||||
let mut buf = core.clone();
|
||||
buf.extend_from_slice(&garbage);
|
||||
@@ -1931,6 +1931,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
// The loop variable is the DOMAIN VALUE being checked (a DTS SFREQ code), not a
|
||||
// cursor into a collection: it is what the assertion message names and
|
||||
// what the table is keyed by. `.iter().enumerate()` would rename the
|
||||
// thing under test to `i` and read worse.
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
fn sr_validity_table_marks_reserved_codes() {
|
||||
// The core-header sample-rate validity table must have ZERO (reject) at
|
||||
// exactly the reserved SFREQ codes {0,4,5,9,10} and a real rate
|
||||
|
||||
@@ -1456,6 +1456,11 @@ mod tests {
|
||||
/// offset on any real stream that sets it — mislabelling every picture's
|
||||
/// coding type.
|
||||
#[test]
|
||||
// The underscores in these literals mark BITFIELD boundaries in the
|
||||
// bitstream header being built (e.g. a 5-bit field then a 3-bit field),
|
||||
// not thousands-style digit groups. Regrouping them uniformly would
|
||||
// satisfy the lint by destroying the only thing they encode.
|
||||
#[allow(clippy::unusual_byte_groupings)]
|
||||
fn nonzero_num_extra_slice_header_bits_shifts_the_slice_type_offset() {
|
||||
use super::super::coding::CodingType;
|
||||
|
||||
@@ -2690,7 +2695,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
fn put_bit(&mut self, b: u32) {
|
||||
if self.nbits % 8 == 0 {
|
||||
if self.nbits.is_multiple_of(8) {
|
||||
self.bytes.push(0);
|
||||
}
|
||||
if b & 1 != 0 {
|
||||
|
||||
@@ -154,7 +154,7 @@ mod tests {
|
||||
/// 0xFF 0xFB 0x90 0x00 — the canonical MP3 frame header.
|
||||
fn mp3_frame(payload: usize) -> Vec<u8> {
|
||||
let mut f = vec![0xFF, 0xFB, 0x90, 0x00];
|
||||
f.extend(std::iter::repeat(0xAA).take(payload));
|
||||
f.extend(std::iter::repeat_n(0xAA, payload));
|
||||
f
|
||||
}
|
||||
|
||||
|
||||
@@ -417,9 +417,7 @@ mod tests {
|
||||
let (_dt, rx) =
|
||||
DemuxThread::spawn_zero_copy(pf_rx, rc_tx, (), None, Some(ts), None).unwrap();
|
||||
|
||||
pf_tx
|
||||
.send(Err(std::io::Error::new(std::io::ErrorKind::Other, "boom")))
|
||||
.unwrap();
|
||||
pf_tx.send(Err(std::io::Error::other("boom"))).unwrap();
|
||||
drop(pf_tx);
|
||||
|
||||
let batches = collect_batches(&rx, Duration::from_secs(5));
|
||||
|
||||
+6
-3
@@ -1880,7 +1880,7 @@ mod tests {
|
||||
// would straddle AACS unit boundaries and decrypt under the wrong
|
||||
// alignment.
|
||||
assert!(
|
||||
count as u32 % ALIGN == 0 || (count as u32) < ALIGN,
|
||||
(count as u32).is_multiple_of(ALIGN) || (count as u32) < ALIGN,
|
||||
"read count {count} is neither a whole number of units nor a sub-unit tail"
|
||||
);
|
||||
}
|
||||
@@ -2457,7 +2457,10 @@ mod tests {
|
||||
let h = halve_batch_size(size);
|
||||
assert!(h >= 1, "halve({size}) must never be 0");
|
||||
assert!(h <= size, "halve({size}) = {h} must not grow");
|
||||
assert!(h < 6 || h % 3 == 0, "halve({size}) = {h} is unit-unaligned");
|
||||
assert!(
|
||||
h < 6 || h.is_multiple_of(3),
|
||||
"halve({size}) = {h} is unit-unaligned"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2483,7 +2486,7 @@ mod tests {
|
||||
let d = double_batch_size(size, 4096);
|
||||
assert!(d >= size, "double({size}) = {d} must not shrink");
|
||||
assert!(
|
||||
d < 6 || d % 3 == 0,
|
||||
d < 6 || d.is_multiple_of(3),
|
||||
"double({size}) = {d} is unit-unaligned"
|
||||
);
|
||||
}
|
||||
|
||||
+8
-8
@@ -1043,15 +1043,15 @@ mod tests {
|
||||
|
||||
impl Stream for FakeStream {
|
||||
fn read(&mut self) -> std::io::Result<Option<PesFrame>> {
|
||||
if let Some((halt, after)) = &self.cancel_halt {
|
||||
if self.reads >= *after {
|
||||
halt.cancel();
|
||||
}
|
||||
if let Some((halt, after)) = &self.cancel_halt
|
||||
&& self.reads >= *after
|
||||
{
|
||||
halt.cancel();
|
||||
}
|
||||
if let Some(after) = self.halt_err_at_read {
|
||||
if self.reads >= after {
|
||||
return Err(crate::error::Error::Halted.into());
|
||||
}
|
||||
if let Some(after) = self.halt_err_at_read
|
||||
&& self.reads >= after
|
||||
{
|
||||
return Err(crate::error::Error::Halted.into());
|
||||
}
|
||||
let f = self.frames.pop_front();
|
||||
if f.is_some() {
|
||||
|
||||
@@ -1479,6 +1479,11 @@ mod tests {
|
||||
/// end_master without a multi-terabyte buffer, which is why this is
|
||||
/// tested at the encoder.
|
||||
#[test]
|
||||
// The underscores in these literals mark BITFIELD boundaries in the
|
||||
// bitstream header being built (e.g. a 5-bit field then a 3-bit field),
|
||||
// not thousands-style digit groups. Regrouping them uniformly would
|
||||
// satisfy the lint by destroying the only thing they encode.
|
||||
#[allow(clippy::unusual_byte_groupings)]
|
||||
fn fixed_width_vint8_is_big_endian_over_the_full_payload() {
|
||||
assert_eq!(
|
||||
fixed_width_vint8(0x00AA_BB_CC_DD_EE_FF_11),
|
||||
|
||||
@@ -766,7 +766,7 @@ mod tests {
|
||||
// First two packets: PAT, PMT. At least one video packet after.
|
||||
assert_eq!(pids[0], PID_PAT);
|
||||
assert_eq!(pids[1], PID_PMT);
|
||||
assert!(pids.iter().any(|p| *p == PID_VIDEO));
|
||||
assert!(pids.contains(&PID_VIDEO));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -810,8 +810,8 @@ mod tests {
|
||||
|
||||
assert_ts_well_formed(&sink);
|
||||
let pids = extract_pids(&sink);
|
||||
assert!(pids.iter().any(|p| *p == PID_VIDEO));
|
||||
assert!(pids.iter().any(|p| *p == PID_AUDIO));
|
||||
assert!(pids.contains(&PID_VIDEO));
|
||||
assert!(pids.contains(&PID_AUDIO));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1129,10 +1129,11 @@ mod tests {
|
||||
continue;
|
||||
}
|
||||
total_video += 1;
|
||||
if let Some(af) = af_body(pkt) {
|
||||
if !af.is_empty() && (af[0] & 0x10) != 0 {
|
||||
pcr_indices.push(video_idx);
|
||||
}
|
||||
if let Some(af) = af_body(pkt)
|
||||
&& !af.is_empty()
|
||||
&& (af[0] & 0x10) != 0
|
||||
{
|
||||
pcr_indices.push(video_idx);
|
||||
}
|
||||
video_idx += 1;
|
||||
}
|
||||
@@ -1582,7 +1583,7 @@ mod tests {
|
||||
}
|
||||
let pids = extract_pids(&sink);
|
||||
assert!(
|
||||
!pids.iter().any(|p| *p == PID_AUDIO),
|
||||
!pids.contains(&PID_AUDIO),
|
||||
"no audio track configured → no audio PID emitted"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2024,6 +2024,7 @@ mod tests {
|
||||
/// so a shipped DVD rip marked every P/B frame as a seek point;
|
||||
/// - the reader ignored ReferenceBlock and read the always-0 reserved bit,
|
||||
/// so EVERY BlockGroup frame read back as a non-keyframe.
|
||||
///
|
||||
/// Downstream that silently dropped all video on `mkv://`(MPEG-2)→`m2ts://`
|
||||
/// (TsMuxer drops non-key video until the first keyframe) and made
|
||||
/// `mkv://`→`mkv://` / `stdio://` fail E6008 (MkvMuxer opens a cluster only
|
||||
|
||||
@@ -522,6 +522,11 @@ mod tests {
|
||||
|
||||
/// A synthetic legacy AC-3 header: syncword, crc, fscod=0 (48k),
|
||||
/// frmsizecod, bsid=8, bsmod=0, acmod=7 (3/2), lfeon=1 → 5.1.
|
||||
// The underscores in these literals mark BITFIELD boundaries in the
|
||||
// bitstream header being built (e.g. a 5-bit field then a 3-bit field),
|
||||
// not thousands-style digit groups. Regrouping them uniformly would
|
||||
// satisfy the lint by destroying the only thing they encode.
|
||||
#[allow(clippy::unusual_byte_groupings)]
|
||||
fn ac3_frame_5_1() -> Vec<u8> {
|
||||
let mut f = vec![0x0B, 0x77, 0x00, 0x00];
|
||||
// byte4: fscod(2)=0 | frmsizecod(6)=0b010110 (22)
|
||||
@@ -556,6 +561,11 @@ mod tests {
|
||||
|
||||
/// A synthetic Annex-E (E-AC-3) syncframe: bsid=16, fscod=0 (48 kHz),
|
||||
/// numblkscod=3 (6 blocks), acmod=7 (3/2), lfeon=1 → 5.1, frmsiz=63 (128 B).
|
||||
// The underscores in these literals mark BITFIELD boundaries in the
|
||||
// bitstream header being built (e.g. a 5-bit field then a 3-bit field),
|
||||
// not thousands-style digit groups. Regrouping them uniformly would
|
||||
// satisfy the lint by destroying the only thing they encode.
|
||||
#[allow(clippy::unusual_byte_groupings)]
|
||||
fn eac3_frame_5_1() -> Vec<u8> {
|
||||
// E-AC-3: syncword | strmtyp/substreamid/frmsiz | fscod/numblks/acmod/lfeon | bsid
|
||||
let mut f = vec![0x0B, 0x77];
|
||||
@@ -840,6 +850,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
// The loop variable is the DOMAIN VALUE being checked (a DTS AMODE value), not a
|
||||
// cursor into a collection: it is what the assertion message names and
|
||||
// what the table is keyed by. `.iter().enumerate()` would rename the
|
||||
// thing under test to `i` and read worse.
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
fn ddts_channel_layout_speaker_count_matches_declared_channels() {
|
||||
// The `ddts` box carries BOTH a channel count and a 16-bit speaker mask,
|
||||
// and a decoder may trust either. They must agree for all 16 AMODEs.
|
||||
|
||||
+7
-2
@@ -1226,6 +1226,11 @@ mod tests {
|
||||
}
|
||||
|
||||
// A minimal AC-3 5.1 frame the audio parser accepts.
|
||||
// The underscores in these literals mark BITFIELD boundaries in the
|
||||
// bitstream header being built (e.g. a 5-bit field then a 3-bit field),
|
||||
// not thousands-style digit groups. Regrouping them uniformly would
|
||||
// satisfy the lint by destroying the only thing they encode.
|
||||
#[allow(clippy::unusual_byte_groupings)]
|
||||
fn ac3_frame() -> Vec<u8> {
|
||||
vec![
|
||||
0x0B,
|
||||
@@ -1503,11 +1508,11 @@ mod tests {
|
||||
t.duration_secs = 7200.0;
|
||||
let r = estimate_reserve(&t, &[0, 1]);
|
||||
assert!(
|
||||
r % (4 << 20) == 0,
|
||||
r.is_multiple_of(4 << 20),
|
||||
"reserve is 4 MiB-aligned + 4 MiB buffer"
|
||||
);
|
||||
assert!(
|
||||
r >= 12 << 20 && r <= 20 << 20,
|
||||
(12 << 20..=20 << 20).contains(&r),
|
||||
"≈12-16 MB for a 2h feature, got {r}"
|
||||
);
|
||||
|
||||
|
||||
+18
-8
@@ -1087,6 +1087,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
// The underscores in these literals mark BITFIELD boundaries in the
|
||||
// bitstream header being built (e.g. a 5-bit field then a 3-bit field),
|
||||
// not thousands-style digit groups. Regrouping them uniformly would
|
||||
// satisfy the lint by destroying the only thing they encode.
|
||||
#[allow(clippy::unusual_byte_groupings)]
|
||||
fn write_then_read_round_trip() {
|
||||
// Mux a small A/V title to an in-memory MP4, then demux it back and
|
||||
// check the streams, codec_private, and sample payloads survive.
|
||||
@@ -1453,6 +1458,11 @@ mod tests {
|
||||
/// one of any of them round-trips through this crate unnoticed while making
|
||||
/// the file unplayable elsewhere.
|
||||
#[test]
|
||||
// The underscores in these literals mark BITFIELD boundaries in the
|
||||
// bitstream header being built (e.g. a 5-bit field then a 3-bit field),
|
||||
// not thousands-style digit groups. Regrouping them uniformly would
|
||||
// satisfy the lint by destroying the only thing they encode.
|
||||
#[allow(clippy::unusual_byte_groupings)]
|
||||
fn moov_tree_carries_the_mandatory_track_header_and_media_boxes() {
|
||||
use crate::disc::{
|
||||
AudioChannels, AudioStream, Codec, DiscTitle, FrameRate, HdrFormat, LabelPurpose,
|
||||
@@ -2148,8 +2158,8 @@ mod tests {
|
||||
mdia.extend_from_slice(&mdhd);
|
||||
mdia.extend_from_slice(&hdlr);
|
||||
mdia.extend_from_slice(&minf);
|
||||
let trak = mp4_box(b"trak", &mp4_box(b"mdia", &mdia));
|
||||
trak
|
||||
|
||||
mp4_box(b"trak", &mp4_box(b"mdia", &mdia))
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2449,10 +2459,10 @@ mod tests {
|
||||
}
|
||||
|
||||
/// A `VisualSampleEntry` body with DISTINCT width and height, plus optional
|
||||
/// child boxes (ISO/IEC 14496-12 §12.1.3): 6 reserved + 2 data_reference_index
|
||||
/// + 16 pre_defined/reserved, then width(2) at 24 and height(2) at 26, then 50
|
||||
/// more bytes of resolution / frame_count / compressorname / depth / pre_defined
|
||||
/// to the 78-byte fixed part.
|
||||
/// child boxes (ISO/IEC 14496-12 §12.1.3). The fixed part is 78 bytes:
|
||||
/// 6 reserved, 2 data_reference_index, 16 pre_defined/reserved, width(2) at
|
||||
/// offset 24, height(2) at 26, then 50 more bytes of resolution,
|
||||
/// frame_count, compressorname, depth and pre_defined.
|
||||
fn visual_entry(width: u16, height: u16, children: &[u8]) -> Vec<u8> {
|
||||
let mut b = vec![0u8; 78];
|
||||
b[24..26].copy_from_slice(&width.to_be_bytes());
|
||||
@@ -2492,7 +2502,7 @@ mod tests {
|
||||
|
||||
// And a VisualSampleEntry too short to hold the fixed part is refused
|
||||
// rather than read out of a shorter buffer.
|
||||
let short = stsd_with(b"avc1", &vec![0u8; 40]);
|
||||
let short = stsd_with(b"avc1", &[0u8; 40]);
|
||||
assert!(
|
||||
parse_stsd(&short).is_none(),
|
||||
"a truncated VisualSampleEntry has no dimensions to read"
|
||||
@@ -2519,7 +2529,7 @@ mod tests {
|
||||
assert_eq!(info.height, 0, "an audio entry declares no height");
|
||||
|
||||
// Too short for the 28-byte fixed part: fall back to stereo, not to 0.
|
||||
let short = stsd_with(b"ac-3", &vec![0u8; 12]);
|
||||
let short = stsd_with(b"ac-3", &[0u8; 12]);
|
||||
let info = parse_stsd(&short).expect("a short audio entry still names a codec");
|
||||
assert_eq!(
|
||||
info.channels, 2,
|
||||
|
||||
+12
-11
@@ -4258,7 +4258,7 @@ mod tests {
|
||||
let sb = s.start_byte();
|
||||
if unit_byte >= sb && unit_byte < sb + s.byte_len() {
|
||||
let n = (unit_byte - sb) / crate::aacs::content::ALIGNED_UNIT_LEN as u64;
|
||||
let key = if n % 2 == 0 {
|
||||
let key = if n.is_multiple_of(2) {
|
||||
FMTS_INDEX_KEYS[(s.index - 1) as usize]
|
||||
} else {
|
||||
FMTS_ALT_KEY
|
||||
@@ -4281,16 +4281,17 @@ mod tests {
|
||||
buf: &mut [u8],
|
||||
recovery: bool,
|
||||
) -> crate::error::Result<usize> {
|
||||
if let Some((a, b)) = self.fault_span {
|
||||
if lba >= a && lba < b {
|
||||
self.probe_reads += 1;
|
||||
self.maybe_cancel();
|
||||
return Err(crate::error::Error::DiscRead {
|
||||
sector: lba as u64,
|
||||
status: None,
|
||||
sense: None,
|
||||
});
|
||||
}
|
||||
if let Some((a, b)) = self.fault_span
|
||||
&& lba >= a
|
||||
&& lba < b
|
||||
{
|
||||
self.probe_reads += 1;
|
||||
self.maybe_cancel();
|
||||
return Err(crate::error::Error::DiscRead {
|
||||
sector: lba as u64,
|
||||
status: None,
|
||||
sense: None,
|
||||
});
|
||||
}
|
||||
if lba < FMTS_CONTENT_LBA {
|
||||
self.meta_reads += 1;
|
||||
|
||||
+4
-4
@@ -232,10 +232,10 @@ mod tests {
|
||||
fn pids(t: &DiscTitle) -> Vec<u16> {
|
||||
t.streams
|
||||
.iter()
|
||||
.filter_map(|s| match s {
|
||||
Stream::Video(v) => Some(v.pid),
|
||||
Stream::Audio(a) => Some(a.pid),
|
||||
Stream::Subtitle(s) => Some(s.pid),
|
||||
.map(|s| match s {
|
||||
Stream::Video(v) => v.pid,
|
||||
Stream::Audio(a) => a.pid,
|
||||
Stream::Subtitle(s) => s.pid,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
+3
-3
@@ -1539,7 +1539,7 @@ mod tests {
|
||||
// 0xAA filler and the embedded 00 00 01 sequence must be absent — the
|
||||
// malformed PES header contributed ZERO bytes to the elementary stream.
|
||||
assert!(
|
||||
!pes.data.iter().any(|&b| b == 0xAA),
|
||||
!pes.data.contains(&0xAA),
|
||||
"garbage PES-header bytes must not appear in the elementary stream"
|
||||
);
|
||||
assert!(
|
||||
@@ -2124,7 +2124,7 @@ mod tests {
|
||||
assert_eq!(out.len(), 1);
|
||||
// None of the 0xEE AF-only bytes may appear.
|
||||
assert!(
|
||||
!out[0].data.iter().any(|&b| b == 0xEE),
|
||||
!out[0].data.contains(&0xEE),
|
||||
"AF-only packet bytes must never be appended as ES"
|
||||
);
|
||||
assert_eq!(out[0].data, vec![0x01, 0x02, 0x03, 0x04]);
|
||||
@@ -2165,7 +2165,7 @@ mod tests {
|
||||
assert_eq!(out.len(), 1);
|
||||
assert_eq!(out[0].data, vec![0x77, 0x88]);
|
||||
assert!(
|
||||
!out[0].data.iter().any(|&b| b == 0xBB),
|
||||
!out[0].data.contains(&0xBB),
|
||||
"adaptation-field stuffing must not appear in the ES"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user