test(pf-encode): guard TrackedEncoder's forwarding completeness (WP7.7, cheap half)
A defaulted Encoder method that TrackedEncoder doesn't forward silently no-ops through the wrapper — the host loop only ever holds the wrapped box, so the feature dies for every session with nothing in the logs. The trap has bitten three times (set_wire_chunking's §4.4 chunking probe, set_pipelined's LN3 escalation, applied_bitrate_bps's ABR truth), and every Phase 7 consolidation that adds a trait method re-arms it. Source-text parse of the trait and the forwarding impl (both top-level rustfmt items: block ends at the first column-0 brace, method names sit on 'fn '-prefixed lines), then set equality — the reverse direction is already a compile error, so equality == completeness. Mutation-verified: removing set_wire_chunking's forward fails naming exactly that method. 16/16 today. Limit stated in the test doc: name-set equality only — a forward whose body delegates to the WRONG inner method still passes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1610,4 +1610,64 @@ mod tests {
|
|||||||
};
|
};
|
||||||
assert_eq!(none.wire_mask(), None);
|
assert_eq!(none.wire_mask(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// WP7.7 guard (the cheap half): every `Encoder` trait method must be explicitly forwarded by
|
||||||
|
/// `TrackedEncoder`. A defaulted trait method that isn't forwarded silently no-ops through the
|
||||||
|
/// wrapper — the trap has bitten three times (`set_wire_chunking`'s §4.4 chunking probe,
|
||||||
|
/// `set_pipelined`'s LN3 escalation, `applied_bitrate_bps`'s ABR truth), and every Phase 7
|
||||||
|
/// consolidation that adds a trait method re-arms it. Source-text parse, not reflection: both
|
||||||
|
/// blocks are top-level rustfmt items, so each ends at the first column-0 `}` and every method
|
||||||
|
/// name sits on a line starting `fn ` (a wrapped signature still carries the name there).
|
||||||
|
#[test]
|
||||||
|
fn tracked_encoder_forwards_every_trait_method() {
|
||||||
|
fn item_block<'a>(src: &'a str, marker: &str) -> &'a str {
|
||||||
|
let start = src
|
||||||
|
.find(marker)
|
||||||
|
.unwrap_or_else(|| panic!("marker {marker:?} not found — update this guard"));
|
||||||
|
let body = &src[start..];
|
||||||
|
let end = body
|
||||||
|
.find("\n}")
|
||||||
|
.unwrap_or_else(|| panic!("no column-0 close brace after {marker:?}"));
|
||||||
|
&body[..end]
|
||||||
|
}
|
||||||
|
fn fn_names(block: &str) -> std::collections::BTreeSet<&str> {
|
||||||
|
block
|
||||||
|
.lines()
|
||||||
|
.map(str::trim_start)
|
||||||
|
.filter(|l| !l.starts_with("//"))
|
||||||
|
.filter_map(|l| l.strip_prefix("fn "))
|
||||||
|
.map(|rest| {
|
||||||
|
rest.split(|c: char| !(c.is_ascii_alphanumeric() || c == '_'))
|
||||||
|
.next()
|
||||||
|
.expect("split yields at least one item")
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
// `find` takes the FIRST occurrence: the real impl precedes this test's own copy of the
|
||||||
|
// marker string in the included source.
|
||||||
|
let trait_fns = fn_names(item_block(
|
||||||
|
include_str!("enc/codec.rs"),
|
||||||
|
"pub trait Encoder: Send {",
|
||||||
|
));
|
||||||
|
let impl_fns = fn_names(item_block(
|
||||||
|
include_str!("lib.rs"),
|
||||||
|
"impl Encoder for TrackedEncoder {",
|
||||||
|
));
|
||||||
|
assert!(
|
||||||
|
trait_fns.len() >= 12,
|
||||||
|
"only {} trait methods parsed — the extraction markers have rotted, fix the parse \
|
||||||
|
before trusting this guard",
|
||||||
|
trait_fns.len()
|
||||||
|
);
|
||||||
|
let missing: Vec<_> = trait_fns.difference(&impl_fns).collect();
|
||||||
|
assert!(
|
||||||
|
missing.is_empty(),
|
||||||
|
"Encoder methods NOT forwarded by TrackedEncoder: {missing:?} — the host loop only \
|
||||||
|
ever holds the wrapped box, so an unforwarded default silently disables the feature \
|
||||||
|
for every session. Forward each one in `impl Encoder for TrackedEncoder`."
|
||||||
|
);
|
||||||
|
// The reverse direction (impl fn absent from the trait) is a compile error, so equality
|
||||||
|
// here is pure belt-and-braces against a parse regression.
|
||||||
|
assert_eq!(trait_fns, impl_fns);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user