open-standards/wai/wai-rs/tests/format_probe.rs
Transaction Science 1f5cfe4068 wai-rs: format_probe — header probes for JPEG XS, H.265 with MV-HEVC, H.266, LCEVC, MHAS, AVS3, the IEEE 1857.11 header and the projection descriptor
Each probe identifies a payload as its capability's format and reads the
parameters its headers state, or refuses it with one of thirteen codes
(extensions/format-probes.md §12). Pure integer code over bytes, feature
format_probe, no new dependency. The corpus module generates and checks
format-probe-conformance/; wai_format_probe probes a file, generates the
corpus and verifies it, with the fetched LCEVC streams.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 07:55:38 -04:00

80 lines
3.6 KiB
Rust

//! Header probes (extensions/format-probes.md): the committed corpus `format-probe-conformance/`
//! regenerates byte for byte from its external vectors and holds no other generated file,
//! every vector, binding and fact gets its stated outcome, the extension's §2.4 and §12 tables
//! are the reference's probes and codes, and projection.md §4 lists only codes of §12.
#![cfg(feature = "format_probe")]
use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use wai::format_probe::{corpus, Refusal, PROBES};
fn wai_dir() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..")
}
fn walk(root: &Path, dir: &Path, out: &mut BTreeMap<String, Vec<u8>>) {
for e in std::fs::read_dir(dir).expect("a corpus directory").flatten() {
let p = e.path();
if p.is_dir() {
walk(root, &p, out);
} else {
let rel = p.strip_prefix(root).unwrap().to_string_lossy().replace('\\', "/");
out.insert(rel, std::fs::read(&p).unwrap());
}
}
}
fn committed() -> BTreeMap<String, Vec<u8>> {
let root = wai_dir().join("format-probe-conformance");
let mut out = BTreeMap::new();
for sub in ["ext", "gen"] {
walk(&root, &root.join(sub), &mut out);
}
out.insert("vectors.json".into(), std::fs::read(root.join("vectors.json")).expect("vectors.json"));
out
}
#[test]
fn the_corpus_regenerates_and_every_outcome_holds() {
let files = committed();
assert!(files.keys().filter(|k| k.starts_with("ext/")).count() >= 9, "the external vectors");
let fails = corpus::verify(&files);
assert!(fails.is_empty(), "{}: run `wai_format_probe gen`", fails.join("\n"));
}
fn section(text: &str, heading: &str) -> String {
let at = text.find(&format!("\n{heading}")).unwrap_or_else(|| panic!("{heading}"));
let end = text[at + 1..].find("\n## ").map_or(text.len(), |e| at + 1 + e);
text[at..end].to_string()
}
/// §2.4 lists exactly the probes and bases of `PROBES`, in order; §12 exactly the codes of
/// `Refusal::ALL`, in order.
#[test]
fn the_extension_lists_the_probes_and_the_codes() {
let text = std::fs::read_to_string(wai_dir().join("extensions/format-probes.md")).expect("the extension");
let rows: Vec<(String, String)> = section(&text, "## 2. Common rules")
.lines()
.filter(|l| l.starts_with("| `wai."))
.map(|l| {
let cells: Vec<&str> = l.split('|').map(str::trim).collect();
(cells[1].trim_matches('`').to_string(), cells[2].to_string())
})
.collect();
let want: Vec<(String, String)> = PROBES.iter().map(|(c, b)| (c.to_string(), b.label().to_string())).collect();
assert_eq!(rows, want, "§2.4's table and PROBES differ");
let codes: Vec<String> = section(&text, "## 12. Refusals")
.lines()
.filter(|l| l.starts_with("| `"))
.filter_map(|l| l.split('`').nth(1).map(String::from))
.collect();
let want: Vec<String> = Refusal::ALL.iter().map(|r| r.code().to_string()).collect();
assert_eq!(codes, want, "§12's table and Refusal::ALL differ");
// projection.md states the codes its reader and its binding check give.
let proj = std::fs::read_to_string(wai_dir().join("extensions/projection.md")).expect("projection.md");
let checks = section(&proj, "## 4. Checks");
for r in [Refusal::NoSignature, Refusal::LengthMismatch, Refusal::ReservedValue, Refusal::DescriptorInvalid] {
assert!(checks.contains(&format!("`{}`", r.code())), "projection.md §4 does not state {}", r.code());
}
assert!(section(&proj, "## 5. Binding to the rendition").contains("`layer_absent`"));
}