open-standards/wai/wai-rs/tests/floor.rs
Transaction Science 632f8cf394 wai: the developer's path, hello, create, dev and verify, a floor build with no system library, and nine examples
wai-rs gains the feature floor (the mandatory floor of SPEC 5: PNG, FLAC and
zstd, decoded with no system codec library) and quickstart (the floor, and the
receipt checks hello and verify run). The wai command line gains four verbs,
one module each, named in one table (dx::VERBS):

- hello: name, dispatch, rebuild and receipt on a picture made here, the
  receipt laid out as http-delivery 8 lays receipts beside an object;
- create: a new project from one of the examples, whose files the binary
  holds; tests/cli_dx.rs holds them to wai/examples/ byte for byte;
- dev: the relay, the room service and the room page on one loopback origin,
  as a production front serves them; --check checks each piece through it;
- verify: the receipt indexes under a directory, checked offline.

The project file a template writes, wai.json, is read in one place
(dx/project.rs). wai/examples/ holds video-room, watch-together, messaging,
encoder-ingest, package-and-deliver, verify-receipts, apple-app, android-app
and remote-desktop, each with a README and a test that runs it through
wai create and wai dev. wai/quickstart/ builds the room client and the
archive that holds wai, the relay, the room service, the remote host and the
packager.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 22:58:39 -04:00

133 lines
5.7 KiB
Rust

//! The mandatory floor (SPEC §5: PNG, FLAC, zstd) in a build with the `floor` feature and no
//! other: the library decodes each, and the `wai` binary encodes PNG and zstd and decodes all
//! three, with no system codec library linked. A codec outside the floor is refused, saying
//! which build has it.
#![cfg(feature = "floor")]
use std::path::{Path, PathBuf};
use std::process::Command;
use wai::codecs::{audio, image, text};
fn tmp(name: &str) -> PathBuf {
let d = std::env::temp_dir().join(format!("wai-floor-{name}-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&d);
std::fs::create_dir_all(&d).unwrap();
d
}
fn wai(args: &[&str]) -> std::process::Output {
Command::new(env!("CARGO_BIN_EXE_wai")).args(args).output().expect("wai runs")
}
/// CRC-8 (polynomial 0x07) and CRC-16 (0x8005) of RFC 9639 §9.1.8 and §9.3.
fn crc8(b: &[u8]) -> u8 {
b.iter().fold(0u8, |mut c, &x| {
c ^= x;
for _ in 0..8 {
c = if c & 0x80 != 0 { (c << 1) ^ 0x07 } else { c << 1 };
}
c
})
}
fn crc16(b: &[u8]) -> u16 {
b.iter().fold(0u16, |mut c, &x| {
c ^= (x as u16) << 8;
for _ in 0..8 {
c = if c & 0x8000 != 0 { (c << 1) ^ 0x8005 } else { c << 1 };
}
c
})
}
/// A FLAC stream (RFC 9639) of one frame of sixteen 16-bit mono samples at 8 kHz, in a
/// verbatim subframe: written field by field, so the test needs no encoder.
fn flac(samples: &[i16; 16]) -> Vec<u8> {
let mut b = b"fLaC".to_vec();
b.extend_from_slice(&[0x80, 0, 0, 34]); // the last metadata block: STREAMINFO, 34 bytes
b.extend_from_slice(&16u16.to_be_bytes()); // min and max block size
b.extend_from_slice(&16u16.to_be_bytes());
b.extend_from_slice(&[0, 0, 0, 0, 0, 0]); // frame sizes unknown
// 20 bits sample rate (8000), 3 bits channels-1 (0), 5 bits bps-1 (15), 36 bits samples (16).
let v: u64 = (8000u64 << 44) | (15u64 << 36) | 16;
b.extend_from_slice(&v.to_be_bytes());
b.extend_from_slice(&[0; 16]); // MD5 unknown
let start = b.len();
// Sync, fixed blocking; block size from an 8-bit field, rate from STREAMINFO; mono, 16 bits;
// frame 0; block size - 1.
b.extend_from_slice(&[0xff, 0xf8, 0x60, 0x08, 0x00, 15]);
let c = crc8(&b[start..]);
b.push(c);
b.push(0x02); // a verbatim subframe, no wasted bits
for s in samples {
b.extend_from_slice(&s.to_be_bytes());
}
let c = crc16(&b[start..]);
b.extend_from_slice(&c.to_be_bytes());
b
}
#[test]
fn the_library_decodes_the_floor() {
let rgb: Vec<u8> = (0..4 * 3 * 3).map(|i| (i * 7) as u8).collect();
let png = image::png_encode(&rgb, 3, 4).unwrap();
assert_eq!(image::png_decode(&png).unwrap(), (rgb, 3, 4));
let s: [i16; 16] = std::array::from_fn(|i| (i as i16 - 8) * 1000);
let (pcm, rate) = audio::flac_decode(&flac(&s)).unwrap();
assert_eq!(rate, 8000);
assert_eq!(pcm, s.iter().map(|&x| x as f32 / 32768.0).collect::<Vec<_>>());
let t = b"the mandatory floor".repeat(20);
assert_eq!(text::zstd_decode(&text::zstd_encode(&t, 3).unwrap()).unwrap(), t);
assert_eq!(wai::floor_capabilities(), &["wai.image.png", "wai.audio.flac", "wai.text.zstd"]);
}
fn ok(o: &std::process::Output) {
assert!(o.status.success(), "{}{}", String::from_utf8_lossy(&o.stdout), String::from_utf8_lossy(&o.stderr));
}
fn s(p: &Path) -> &str {
p.to_str().unwrap()
}
#[test]
fn the_cli_encodes_png_and_zstd_and_decodes_the_floor() {
let d = tmp("cli");
// PNG: a 4x3 picture in, the same pixels out.
let rgb: Vec<u8> = (0..36).map(|i| (i * 5) as u8).collect();
std::fs::write(d.join("pic.rgb"), &rgb).unwrap();
std::fs::write(d.join("pic.rgb.meta"), "3 4\n").unwrap();
ok(&wai(&["encode", "png", s(&d.join("pic.rgb")), "-o", s(&d.join("pic.wai"))]));
ok(&wai(&["decode", s(&d.join("pic.wai")), "-o", s(&d.join("pic.out"))]));
assert_eq!(std::fs::read(d.join("pic.out")).unwrap(), rgb);
// zstd.
let t = b"carried, compressed and rebuilt".repeat(9);
std::fs::write(d.join("t.txt"), &t).unwrap();
ok(&wai(&["encode", "zstd", s(&d.join("t.txt")), "-o", s(&d.join("t.wai"))]));
ok(&wai(&["decode", s(&d.join("t.wai")), "-o", s(&d.join("t.out"))]));
assert_eq!(std::fs::read(d.join("t.out")).unwrap(), t);
// FLAC: wrapped as it comes, decoded by the floor.
let smp: [i16; 16] = std::array::from_fn(|i| (i as i16) * 300);
std::fs::write(d.join("a.flac"), flac(&smp)).unwrap();
ok(&wai(&["wrap", "wai.audio.flac", s(&d.join("a.flac")), "-o", s(&d.join("a.wai"))]));
ok(&wai(&["decode", s(&d.join("a.wai")), "-o", s(&d.join("a.f32"))]));
let f: Vec<u8> = smp.iter().flat_map(|&x| (x as f32 / 32768.0).to_le_bytes()).collect();
assert_eq!(std::fs::read(d.join("a.f32")).unwrap(), f);
assert_eq!(std::fs::read_to_string(d.join("a.f32.meta")).unwrap().trim(), "8000");
let _ = std::fs::remove_dir_all(&d);
}
#[cfg(not(feature = "codecs"))]
#[test]
fn a_codec_outside_the_floor_is_refused_naming_the_build_that_has_it() {
let d = tmp("outside");
std::fs::write(d.join("x.txt"), b"x").unwrap();
let o = wai(&["encode", "xz", s(&d.join("x.txt")), "-o", s(&d.join("x.wai"))]);
assert!(!o.status.success());
assert!(String::from_utf8_lossy(&o.stderr).contains("`codecs` feature"), "{}", String::from_utf8_lossy(&o.stderr));
// A payload the floor does not decode is inert here, never guessed.
std::fs::write(d.join("y.jxl"), b"\xff\x0a").unwrap();
ok(&wai(&["wrap", "wai.image.jxl", s(&d.join("y.jxl")), "-o", s(&d.join("y.wai"))]));
let o = wai(&["decode", s(&d.join("y.wai")), "-o", s(&d.join("y.out"))]);
assert!(!o.status.success() && String::from_utf8_lossy(&o.stderr).contains("inert"), "{}", String::from_utf8_lossy(&o.stderr));
let _ = std::fs::remove_dir_all(&d);
}