open-standards/wai/wai-vector/tests/corpus.rs
Transaction Science 10ba6e9bcc wai-vector: the text layer and section 5, text and accessibility (D7-7)
graphics-vector.md section 5 (Draft): what a sink exposes to assistive
technology and to a text consumer, and how. Each text block's active set (the
effective windows of the items that draw it, merged), the projection at a
frame and the transcript as exact JSON, the text record and its digest, ruby,
purposes, writing modes and the cluster rule.

- wai-vector: src/text.rs (no_std, no dependency), the a11y and text commands,
  and vectors verify recomputing every text record.
- The corpus: a new a11y group, each payload with its text record
  (<name>.a11y.jsonl) and its digest in the expected file; canonical and
  refusal vectors for TEXT. No existing expected file changes.
- tests/text_layer.rs: each rule of section 5, with expected JSON written by
  hand from the text, each falsified once.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 02:43:02 -04:00

65 lines
2.9 KiB
Rust

//! `vector-conformance/`: the generator reproduces every committed file, and every
//! expected file is recomputed from its vector alone, each text record included.
use std::path::PathBuf;
use wai_vector::vectors::{self, CORPUS};
use wai_vector::wvg1::SetStore;
fn wai() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..")
}
#[test]
fn the_generator_reproduces_the_committed_corpus() {
let files = vectors::generate().unwrap();
assert!(files.len() > 500);
for (rel, bytes) in files {
let have = std::fs::read(wai().join(&rel)).unwrap_or_else(|e| panic!("{rel}: {e}"));
assert!(have == bytes, "{rel}: the generator writes other bytes");
}
}
#[test]
fn every_expected_file_is_recomputed_from_its_vector() {
let corpus = wai().join(CORPUS);
let mut store = SetStore::new();
let mut sets: Vec<PathBuf> = std::fs::read_dir(corpus.join("sets")).unwrap().flatten().map(|e| e.path()).collect();
sets.sort();
for p in sets {
store.add(std::fs::read(p).unwrap());
}
let (mut n, mut records) = (0, 0);
let mut groups: Vec<PathBuf> = std::fs::read_dir(corpus.join("vectors")).unwrap().flatten().map(|e| e.path()).collect();
groups.sort();
for gdir in groups {
let group = gdir.file_name().unwrap().to_string_lossy().into_owned();
let mut files: Vec<PathBuf> = std::fs::read_dir(&gdir).unwrap().flatten().map(|e| e.path()).collect();
files.sort();
for f in files {
let name = f.file_stem().unwrap().to_string_lossy().into_owned();
let ext = f.extension().unwrap().to_string_lossy().into_owned();
if name == "index" || (ext == "json" && !vectors::INPUT_GROUPS.contains(&group.as_str())) {
continue;
}
let bytes = std::fs::read(&f).unwrap();
let got = vectors::recompute(&group, &ext, &bytes, &mut store).unwrap();
let exp = std::fs::read_to_string(corpus.join("expected").join(&group).join(format!("{name}.json"))).unwrap();
assert_eq!(got, exp, "{group}/{name}.{ext}");
n += 1;
// The text record beside it (§5.4), recomputed from the payload: the committed
// lines. The expected file above states their SHA-256 (`text_record`).
let path = corpus.join("expected").join(&group).join(format!("{name}.a11y.jsonl"));
match vectors::text_record(&group, &ext, &bytes, &mut store) {
Some(record) => {
let have = std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("{}: {e}", path.display()));
assert_eq!(record, have, "{group}/{name}: the text record");
records += 1;
}
None => assert!(!path.exists(), "{}: a record no vector accounts for", path.display()),
}
}
}
assert!(n > 250, "{n} vectors");
assert!(records > 10, "{records} text records");
}