Files
ww/lib/ascii/asciitest.ww
Hojun-Cho 2338ea5d59 ww: lib tests run via -T test mode; bare mains retired (closes @test conversion)
'ww test' gains the istest build path (-T injection in build_one/
buildone) and do_test/dotest accept -I, mirroring do_run - both twins.
The 35 converted lib tests drop their interim bare mains (-T
synthesizes the entry from @test fns and rejects a user main); their
35 C run-drivers flip 'ww run' -> 'ww test'; 989_lib_byteid compiles
lib tests under -T (8 user-main probe fixtures stay non-T, gated on
the fixture field). Abort-on-first-failure stands until the deferred
record-and-continue harness lands with the multi-package arc.
2026-06-10 20:45:46 +09:00

68 lines
2.3 KiB
Plaintext

// asciitest — exercises lib/ascii case folding. Run with
// `ww run lib/ascii/asciitest.ww`. A failing row aborts via the
// assert/abort builtin (task #5 @test conversion).
//
// Vectors mirror Hare's @test fn strcasecmp in ref/hare/ascii/string.ha.
package ascii_test;
import ascii;
// checkfold — one table row: strlower(in) == lo and strupper(in) == up.
fn checkfold(in: str, lo: str, up: str) void = {
match (ascii.strlower(in)) {
case let got: str => { assert(!(got != lo)); };
case nomem => { abort(); };
};
match (ascii.strupper(in)) {
case let got: str => { assert(!(got != up)); };
case nomem => { abort(); };
};
};
// ref/hare/ascii/string.ha:70 case-fold vectors. The こ row pins that a
// UTF-8 multibyte sequence (all bytes >=0x80) passes through unchanged.
@test fn strfold_cases() void = {
checkfold("ABC", "abc", "ABC");
checkfold("abc", "abc", "ABC");
checkfold("[[[", "[[[", "[[[");
checkfold("こ", "こ", "こ");
checkfold("", "", "");
checkfold("aB1z", "ab1z", "AB1Z");
};
// checkbuf — strlower_buf/strupper_buf into an exactly-sized buf.
fn checkbuf(in: str, lo: str, up: str) void = {
let lstore: [16]u8; let lbuf: []u8 = lstore[0:16]; lbuf.len = 0;
match (ascii.strlower_buf(in, lbuf)) {
case let got: str => { assert(!(got != lo)); };
case nomem => { abort(); };
};
let ustore: [16]u8; let ubuf: []u8 = ustore[0:16]; ubuf.len = 0;
match (ascii.strupper_buf(in, ubuf)) {
case let got: str => { assert(!(got != up)); };
case nomem => { abort(); };
};
};
@test fn strfold_buf_cases() void = {
checkbuf("ABC", "abc", "ABC");
checkbuf("aB1z", "ab1z", "AB1Z");
checkbuf("", "", "");
// non-ASCII pins UTF-8 multibyte passthrough through the _buf path
// directly (all bytes >=0x80, untouched by the byte-wise fold).
checkbuf("こ", "こ", "こ");
// cap exactly == s.len must succeed — pins the `<` boundary in the
// buf.cap check (a `<=` off-by-one would wrongly return nomem here).
let exact: [3]u8; let ebuf: []u8 = exact[0:3]; ebuf.len = 0;
match (ascii.strlower_buf("ABC", ebuf)) {
case let got: str => { assert(!(got != "abc")); };
case nomem => { abort(); };
};
let small: [2]u8; let sbuf: []u8 = small[0:2]; sbuf.len = 0;
match (ascii.strlower_buf("ABC", sbuf)) {
case let got: str => { abort(); };
case nomem => void;
};
};