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]>
65 lines
2.9 KiB
Rust
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");
|
|
}
|