test: salvage the orphaned labels/disc triage, and extract build_labels
Thirteen agents triaging src/labels and src/disc died on a saturated
machine, leaving 5,836 insertions across 28 files uncommitted in a
worktree. Recovered by 3-way apply onto twelve commits of drift; zero
conflicts. The diff was archived to freemkv-private first, because a
worktree is not a backup and this one had already nearly been lost.
One production change, and it is the right one: mpls_universal::parse
read every playlist off the disc AND converted the entries to labels in
a single function, so the conversion — stream-type mapping, dedup key,
the dense global counters — could only be reached through a synthetic
UDF image. Extracted to build_labels(&[Playlist]), which unit tests can
drive from already-parsed values. Behaviour-preserving: same iteration
order, same skip-on-error.
Two collisions resolved by hand:
A second mod pass_progress_tests, written independently against the
same survivors as the one committed in c610285. Kept mine — it covers
the distinct-counters case and the Progress blanket impl, which theirs
does not — but theirs had three clamp tests mine lacked: good_pct,
bad_pct and pending_pct also clamp an overshoot, and I had only tested
that for work_pct. Merged those in as one test and proved each of the
three clamps load-bearing by removing them individually.
An unused_parens warning in a new fixture.
Method note, recorded because it cost real time: git apply --3way
STAGES its result, so `git diff` reads empty and the tree looks
untouched. I nearly concluded the patch had silently failed. Worse, the
first attempt piped through `head -20`, so `echo exit=$?` reported
head's status rather than git's — the same mistake this audit has
already documented once. Check the real exit status, and check
--cached, not just the working tree.
This commit is contained in:
@@ -638,6 +638,87 @@ mod tests {
|
||||
assert!(audio.is_empty() || audio.iter().all(|l| l.stream_number <= 512));
|
||||
}
|
||||
|
||||
/// Spec: the FPL section also ends on an `SF_` marker (not just
|
||||
/// `SEG_`/`FPL_`). Only `assign_labels_fpl_section_ends_on_seg_boundary`
|
||||
/// existed before, which cannot distinguish a mutated `||` chain from
|
||||
/// the correct one (any single true operand already ends the section).
|
||||
/// This test isolates the `SF_` alternative specifically.
|
||||
/// Mutation: `||` -> `&&` in the end-of-section check would require
|
||||
/// ALL THREE prefixes to match simultaneously (impossible for a real
|
||||
/// single token), so the section would never end on `SF_` alone.
|
||||
#[test]
|
||||
fn assign_labels_fpl_section_ends_on_sf_boundary() {
|
||||
let mut flag = false;
|
||||
let tokens = strs(&[
|
||||
"FPL_MainFeature",
|
||||
"eng_MLP_",
|
||||
"SF_Something", // must end the FPL section
|
||||
"fra_AC3_", // must NOT be parsed
|
||||
]);
|
||||
let labels = assign_labels(&tokens, &mut flag);
|
||||
assert_eq!(labels.len(), 1, "only eng from FPL section");
|
||||
assert_eq!(labels[0].language, "eng");
|
||||
}
|
||||
|
||||
/// Spec: the two per-type caps are independent — the loop only stops
|
||||
/// early once BOTH audio and subtitle counters have reached
|
||||
/// `MAX_STREAMS_PER_TYPE`. Reaching the audio cap alone must not cut
|
||||
/// off subtitle processing.
|
||||
/// Mutation: `&&` -> `||` in the outer stop-condition would break the
|
||||
/// loop as soon as EITHER counter reaches the cap, silently dropping
|
||||
/// a legitimate subtitle stream that comes after audio saturates.
|
||||
#[test]
|
||||
fn assign_labels_audio_cap_alone_does_not_stop_subtitle_processing() {
|
||||
let mut flag = false;
|
||||
let mut tokens = vec!["FPL_MainFeature".to_string()];
|
||||
for i in 1..=(MAX_STREAMS_PER_TYPE as usize) {
|
||||
tokens.push(format!("Audio Stream {}", i));
|
||||
}
|
||||
// Subtitle counter is still 0 here — well under the cap.
|
||||
tokens.push("eng_SDH_".to_string());
|
||||
let labels = assign_labels(&tokens, &mut flag);
|
||||
let subs: Vec<_> = labels
|
||||
.iter()
|
||||
.filter(|l| l.stream_type == StreamLabelType::Subtitle)
|
||||
.collect();
|
||||
assert_eq!(
|
||||
subs.len(),
|
||||
1,
|
||||
"a subtitle stream after the audio cap (but under the subtitle \
|
||||
cap) must still be labeled"
|
||||
);
|
||||
}
|
||||
|
||||
/// Companion to the above: with the subtitle counter saturated but
|
||||
/// audio still under its cap, a subsequent audio token must still be
|
||||
/// processed. Isolates the first `>=` operand (`audio_num >=
|
||||
/// MAX_STREAMS_PER_TYPE`) from the second.
|
||||
/// Mutation: `audio_num >= MAX_STREAMS_PER_TYPE` -> `audio_num <
|
||||
/// MAX_STREAMS_PER_TYPE` would flip the stop-condition to trigger
|
||||
/// whenever audio is UNDER cap and subtitle is AT/over cap — exactly
|
||||
/// this scenario — dropping the trailing audio token.
|
||||
#[test]
|
||||
fn assign_labels_subtitle_cap_alone_does_not_stop_audio_processing() {
|
||||
let mut flag = false;
|
||||
let mut tokens = vec!["FPL_MainFeature".to_string()];
|
||||
for _ in 1..=(MAX_STREAMS_PER_TYPE as usize) {
|
||||
tokens.push("eng_SDH_".to_string());
|
||||
}
|
||||
// Audio counter is still 0 here — well under the cap.
|
||||
tokens.push("fra_MLP_".to_string());
|
||||
let labels = assign_labels(&tokens, &mut flag);
|
||||
let audio: Vec<_> = labels
|
||||
.iter()
|
||||
.filter(|l| l.stream_type == StreamLabelType::Audio)
|
||||
.collect();
|
||||
assert_eq!(
|
||||
audio.len(),
|
||||
1,
|
||||
"an audio stream after the subtitle cap (but under the audio \
|
||||
cap) must still be labeled"
|
||||
);
|
||||
}
|
||||
|
||||
/// Spec: subtitle placeholders (PG Stream N) do NOT advance the subtitle counter.
|
||||
/// Only audio placeholders (`Audio Stream N`) do.
|
||||
/// Mutation: also advance sub counter on PG placeholder → subtitle labels misnumbered.
|
||||
|
||||
Reference in New Issue
Block a user