Files
ww/lib/bytes/trim_test.ww
Hojun-Cho 4f37a8b425 lib: split bytes tests into equal/index/contains/tokenize/trim per ref/hare/bytes
Pure move: bytes_test.ww dissolves along its banner seams into sibling
equal_test.ww, index_test.ww (u8 + []u8 arms of index/rindex),
contains_test.ww (contains/hasprefix/hassuffix), tokenize_test.ww
(tokenize/rtokenize/peektoken/remainingtokens + splitn/rsplitn/split +
cut/rcut), and trim_test.ww, mirroring ref/hare/bytes/{equal,index,
contains,tokenize,trim}.ha ownership (Hare keeps splitn and cut in
tokenize.ha; contains.ha owns hasprefix/hassuffix). Blocks are
byte-identical; only the banner lines are deleted. Helpers stay with
their sole consumers: expect_token/expect_done/expect_tok in
tokenize_test.ww, beq in trim_test.ww.

Consumers: Makefile LIBRARY_TESTS replaces the bytes_test.ww entry
with the five new entries at the same position; the
test/byteid/libbyteid_test.ww roster row becomes five fx rows,
NENTEXPECT 48->52 (+4).
2026-08-08 17:20:50 +09:00

96 lines
3.0 KiB
Plaintext

// trimtest — exercises bytes.ltrim/rtrim/trim. A failing row aborts
// via the assert/abort builtin (task #5 @test conversion).
// Vectors mirror ref/hare/bytes/trim.ha.
package bytes_test;
import bytes;
// ref/hare/bytes/trim.ha:29 — Hare's @test fn trim pins
// `trim([0,1,2,3,5,0], 0) == [1,2,3,5]`, `trim([0,0,0], 0) == []`,
// `trim([], 0) == []`. ww spreads the matrix across ltrim/rtrim/trim.
fn beq(got: []u8, want: []u8) bool = {
if (got.len != want.len) { return false; };
let i: i32 = 0;
for (i < got.len) {
if (got[i] != want[i]) { return false; };
i += 1;
};
return true;
};
@test fn ltrim_cases() void = {
let z: [1]u8;
// [0,0,1,2] / 0 -> [1,2]
let a: [4]u8; a[0] = 0u8; a[1] = 0u8; a[2] = 1u8; a[3] = 2u8;
let ea: [2]u8; ea[0] = 1u8; ea[1] = 2u8;
assert(!(!beq(bytes.ltrim(a[0:4], 0u8), ea[0:2])));
// [1,2,3] / 0 -> [1,2,3] (no leading match)
let b: [3]u8; b[0] = 1u8; b[1] = 2u8; b[2] = 3u8;
assert(!(!beq(bytes.ltrim(b[0:3], 0u8), b[0:3])));
// [0,0,0] / 0 -> [] (full match) — the bare `let c: [3]u8;` zero-init
// row that surfaced #16 (a dirtied slot read non-zero, ltrim trimmed
// nothing). Now reads {0,0,0} and trims to empty.
let c: [3]u8;
assert(!(!beq(bytes.ltrim(c[0:3], 0u8), z[0:0])));
// [] / 0 -> [] (empty input)
assert(!(!beq(bytes.ltrim(z[0:0], 0u8), z[0:0])));
};
@test fn rtrim_cases() void = {
let z: [1]u8;
// [1,2,0,0] / 0 -> [1,2]
let a: [4]u8; a[0] = 1u8; a[1] = 2u8; a[2] = 0u8; a[3] = 0u8;
let ea: [2]u8; ea[0] = 1u8; ea[1] = 2u8;
assert(!(!beq(bytes.rtrim(a[0:4], 0u8), ea[0:2])));
// [1,2,3] / 0 -> [1,2,3] (no trailing match)
let b: [3]u8; b[0] = 1u8; b[1] = 2u8; b[2] = 3u8;
assert(!(!beq(bytes.rtrim(b[0:3], 0u8), b[0:3])));
// [0,0,0] / 0 -> [] (full match)
let c: [3]u8;
assert(!(!beq(bytes.rtrim(c[0:3], 0u8), z[0:0])));
// [] / 0 -> [] (empty input)
assert(!(!beq(bytes.rtrim(z[0:0], 0u8), z[0:0])));
};
@test fn trim_cases() void = {
let z: [1]u8;
// [0,1,2,3,5,0] / 0 -> [1,2,3,5]
let a: [6]u8;
a[0] = 0u8; a[1] = 1u8; a[2] = 2u8;
a[3] = 3u8; a[4] = 5u8; a[5] = 0u8;
let ea: [4]u8; ea[0] = 1u8; ea[1] = 2u8; ea[2] = 3u8; ea[3] = 5u8;
assert(!(!beq(bytes.trim(a[0:6], 0u8), ea[0:4])));
// [0,5,0] / 5 -> [0,5,0] (only 5 in trim set; boundary mismatch)
let b: [3]u8; b[0] = 0u8; b[1] = 5u8; b[2] = 0u8;
assert(!(!beq(bytes.trim(b[0:3], 5u8), b[0:3])));
// [0,1,42,1,0] / {0,42} -> [1,42,1] (multi-byte trim set)
let c: [5]u8;
c[0] = 0u8; c[1] = 1u8; c[2] = 42u8; c[3] = 1u8; c[4] = 0u8;
let ec: [3]u8; ec[0] = 1u8; ec[1] = 42u8; ec[2] = 1u8;
assert(!(!beq(bytes.trim(c[0:5], 0u8, 42u8), ec[0:3])));
// [0,0,0] / 0 -> [] (full match)
let d: [3]u8;
assert(!(!beq(bytes.trim(d[0:3], 0u8), z[0:0])));
// [] / 0 -> [] (empty input, Hare ref/hare/bytes/trim.ha:34)
assert(!(!beq(bytes.trim(z[0:0], 0u8), z[0:0])));
// [1,2,3,5] / 0 -> [1,2,3,5] (Hare ref/hare/bytes/trim.ha:31)
let e: [4]u8; e[0] = 1u8; e[1] = 2u8; e[2] = 3u8; e[3] = 5u8;
assert(!(!beq(bytes.trim(e[0:4], 0u8), e[0:4])));
};