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]>
80 lines
3.6 KiB
Rust
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`"));
|
|
}
|