lib/encoding+math tests: hand-main plumbing -> assert (@test conversion B2)

This commit is contained in:
2026-06-10 18:52:53 +09:00
parent 6ef2bbcb95
commit 56450e68ce
6 changed files with 451 additions and 462 deletions

View File

@@ -2,9 +2,8 @@
// Run with `out/bin/ww run lib/encoding/base64/base64_test.ww`. Mirrors
// Hare's base64 @test fns (ref/hare/encoding/base64/base64.ha:315,514,
// 601) over the RFC 4648 §10 vectors, table-driven (parallel arrays;
// tuple-row arrays are blocked by #111). Same signalled-then-fail()-
// with-+10 pattern as the rest of the 9xx stdlib tests; non-zero exit
// pinpoints the failing scenario.
// tuple-row arrays are blocked by #111). A failing row aborts via the
// assert/abort builtin (task #5 @test conversion).
//
// The streaming decoder (newdecoder) is deferred (#247-sibling), so the
// decode side is exercised through decodestr only.
@@ -16,11 +15,8 @@ import bytes;
import errors;
import io;
import memio;
import os;
import strings;
let signalled: i32 = 0;
fn fail() void = { os.exit(signalled + 10); };
fn streq(a: str, b: str) bool = {
if (a.len != b.len) { return false; };
@@ -38,19 +34,19 @@ fn streq(a: str, b: str) bool = {
fn enc_check(enc: *base64.encoding, raw: []u8, expect: str) void = {
let out: memio.stream = memio.dynamic();
match (base64.encode(&out.vt, enc, raw)) {
case let n: size => { if (n: i32 != raw.len) { fail(); }; };
case let e: io.error => fail();
case let n: size => { assert(!(n: i32 != raw.len)); };
case let e: io.error => abort();
};
if (!streq(memio.string(&out), expect)) { fail(); };
if (!streq(base64.encodestr(enc, raw), expect)) { fail(); };
assert(!(!streq(memio.string(&out), expect)));
assert(!(!streq(base64.encodestr(enc, raw), expect)));
};
// dec_check — decodestr(`encoded`) must round-trip back to `raw`.
// ref/hare/encoding/base64/base64.ha:514.
fn dec_check(enc: *base64.encoding, encoded: str, raw: []u8) void = {
match (base64.decodestr(enc, encoded)) {
case let b: []u8 => { if (!bytes.equal(b, raw)) { fail(); }; };
case let e: errors.invalid => fail();
case let b: []u8 => { assert(!(!bytes.equal(b, raw))); };
case let e: errors.invalid => abort();
};
};
@@ -58,7 +54,7 @@ fn dec_check(enc: *base64.encoding, encoded: str, raw: []u8) void = {
// ref/hare/encoding/base64/base64.ha:525.
fn inval_check(enc: *base64.encoding, encoded: str) void = {
match (base64.decodestr(enc, encoded)) {
case let b: []u8 => fail();
case let b: []u8 => abort();
case let e: errors.invalid => void;
};
};
@@ -105,7 +101,7 @@ fn inval_check(enc: *base64.encoding, encoded: str) void = {
let raw: [3]u8 = [0xFBu8, 0xFFu8, 0xBFu8];
let s_std: str = base64.encodestr(&base64.std_encoding, raw[0:3]);
let s_url: str = base64.encodestr(&base64.url_encoding, raw[0:3]);
if (streq(s_std, s_url)) { fail(); };
assert(!(streq(s_std, s_url)));
dec_check(&base64.std_encoding, s_std, raw[0:3]);
dec_check(&base64.url_encoding, s_url, raw[0:3]);
@@ -148,22 +144,22 @@ fn inval_check(enc: *base64.encoding, encoded: str) void = {
// ---- size calc ---- ref/hare/encoding/base64/base64.ha:601
@test fn sizes() void = {
if (base64.encodedsize(0) != 0) { fail(); };
if (base64.encodedsize(1) != 4) { fail(); };
if (base64.encodedsize(2) != 4) { fail(); };
if (base64.encodedsize(3) != 4) { fail(); };
if (base64.encodedsize(4) != 8) { fail(); };
if (base64.encodedsize(10) != 16) { fail(); };
if (base64.encodedsize(119) != 160) { fail(); };
if (base64.encodedsize(120) != 160) { fail(); };
if (base64.encodedsize(121) != 164) { fail(); };
if (base64.encodedsize(122) != 164) { fail(); };
if (base64.encodedsize(123) != 164) { fail(); };
if (base64.decodedsize(0) != 0) { fail(); };
if (base64.decodedsize(4) != 3) { fail(); };
if (base64.decodedsize(8) != 6) { fail(); };
if (base64.decodedsize(160) != 120) { fail(); };
if (base64.decodedsize(164) != 123) { fail(); };
assert(!(base64.encodedsize(0) != 0));
assert(!(base64.encodedsize(1) != 4));
assert(!(base64.encodedsize(2) != 4));
assert(!(base64.encodedsize(3) != 4));
assert(!(base64.encodedsize(4) != 8));
assert(!(base64.encodedsize(10) != 16));
assert(!(base64.encodedsize(119) != 160));
assert(!(base64.encodedsize(120) != 160));
assert(!(base64.encodedsize(121) != 164));
assert(!(base64.encodedsize(122) != 164));
assert(!(base64.encodedsize(123) != 164));
assert(!(base64.decodedsize(0) != 0));
assert(!(base64.decodedsize(4) != 3));
assert(!(base64.decodedsize(8) != 6));
assert(!(base64.decodedsize(160) != 120));
assert(!(base64.decodedsize(164) != 123));
};
// ---- round-trip every byte value 0..255 (std + url) ----
@@ -178,27 +174,27 @@ fn inval_check(enc: *base64.encoding, encoded: str) void = {
let s: str = base64.encodestr(&base64.std_encoding, src[0:256]);
match (base64.decodestr(&base64.std_encoding, s)) {
case let b: []u8 => {
if (b.len != 256) { fail(); };
if (!bytes.equal(b, src[0:256])) { fail(); };
assert(!(b.len != 256));
assert(!(!bytes.equal(b, src[0:256])));
};
case let e: errors.invalid => fail();
case let e: errors.invalid => abort();
};
let u: str = base64.encodestr(&base64.url_encoding, src[0:256]);
match (base64.decodestr(&base64.url_encoding, u)) {
case let b: []u8 => {
if (b.len != 256) { fail(); };
if (!bytes.equal(b, src[0:256])) { fail(); };
assert(!(b.len != 256));
assert(!(!bytes.equal(b, src[0:256])));
};
case let e: errors.invalid => fail();
case let e: errors.invalid => abort();
};
};
export fn main() i32 = {
signalled = 1; rfc4648_std();
signalled = 2; rfc4648_url();
signalled = 3; urlsafe_distinct();
signalled = 4; decode_invalid();
signalled = 5; sizes();
signalled = 6; roundtrip_all_bytes();
rfc4648_std();
rfc4648_url();
urlsafe_distinct();
decode_invalid();
sizes();
roundtrip_all_bytes();
return 0;
};