lib: split strings tests per ref/hare/strings families + helpers file

Unblocked by the package-mode ruling: same-package test files now
compose everywhere (coordinator dir-mode owns test-library and the
libbyteid dir entry owns byte identity), so the per-file standalone
constraint is gone and Go's stdlib layout applies directly. The
15-banner strings_test.ww monolith dissolves into per-ref-file
family files — dup, concat, trim, sub, utf8, iter, tokenize
(tokenize+splitn+cut, all of ref tokenize.ha), pad, replace — plus
helpers_test.ww holding exactly the one cross-family helper (streq),
Go's shared test-helper idiom. Pure moves; family-local helpers
(expect_str_token et al.) stay in their family file. Leading banners
that merely restated the filename dropped; 6 interior sub-family
boundaries remain. lib/ census 141 -> 132.

libbyteid gains the dx() dir-mode entry form decided in B2: compose
every *_test.ww under moddir exactly as pkgcombined does
(module-reset separators, byte-lex order) and byte-id the composed
root through both driver stages. The five per-file strings fx
entries retire into one dx("lib/strings") — every source line they
covered is inside the composed unit, and the completeness scan still
keys the module. NENTEXPECT 60 -> 56.

Recorded, not split: fmt_test's 13 banners are scenario groups over
the one fprint surface and ref/hare/fmt itself keeps a single
+test.ha — a print/wrappers split would fight the ref; memio stays
per the standing ruling (everything ww ports lives in ref
stream.ha).
This commit is contained in:
2026-08-08 19:42:49 +09:00
parent 5a263cb115
commit 51cb8e7d64
12 changed files with 1483 additions and 1387 deletions

View File

@@ -43,7 +43,7 @@ import time;
def MID: i32 = 0;
def MDIVERGE: i32 = 1;
def MWWREJECT: i32 = 2;
def NENTEXPECT: i32 = 60;
def NENTEXPECT: i32 = 56;
type ent = struct {
fixture: str, // repo-relative .ww; "" -> probe entry
@@ -83,6 +83,17 @@ fn pri(p: str, inc: str, sentinel: str, moddir: str) ent = {
return e;
};
// Dir-mode entry: byte-id the module's COMPOSED test package (every
// *_test.ww under moddir, module-reset separators, byte-lex order —
// the coordinator's pkgcombined shape) through both driver stages.
// Needed once a package's test files share a helpers file and stop
// being standalone single-file roots (the B3 strings split).
fn dx(moddir: str) ent = {
let e: ent = fx("");
e.moddir = moddir;
return e;
};
// The 60-unit roster. Graduation history lives in git (the retired C
// carrier's table comments); cites are kept only where a non-ID pin
// would need them.
@@ -116,11 +127,9 @@ fn corpus() []ent = {
append(es, fx("lib/strconv/test/ftos_test.ww"));
append(es, fx("lib/strconv/test/stof_test.ww"));
append(es, fx("lib/strconv/test/int_test.ww"));
append(es, fx("lib/strings/strings_test.ww"));
append(es, fx("lib/strings/suffix_test.ww"));
append(es, fx("lib/strings/contains_test.ww"));
append(es, fx("lib/strings/index_test.ww"));
append(es, fx("lib/strings/compare_test.ww"));
// strings' families share helpers_test.ww (B3 split) — the
// single-file roots dissolved; the composed package is the root.
append(es, dx("lib/strings"));
append(es, fx("lib/temp/temp_test.ww"));
append(es, fx("lib/time/arithm_test.ww"));
append(es, fx("lib/time/duration_test.ww"));
@@ -271,9 +280,30 @@ fn checkone(e: *ent) void = {
testenv.writefile(strings.concat(td, "/", base),
testenv.readfile(strings.concat(testenv.repo(), "/",
e.fixture)));
} else {
} else { if (e.probe.len != 0) {
testenv.writefile(strings.concat(td, "/", base), e.probe);
};
} else {
// dir-mode: compose every *_test.ww under moddir exactly
// as pkgcombined does (external group: test sources only,
// module-reset separators; testenv.listdir sorts).
base = "combined.ww";
let srcdir: str = strings.concat(testenv.repo(), "/",
e.moddir);
let names: []str = testenv.listdir(srcdir);
let body: str = "";
let ni: i32 = 0;
for (ni < names.len) {
if (strings.hassuffix(names[ni], "_test.ww")) {
body = strings.concat(body,
"//ww:module-reset\n",
testenv.readfile(strings.concat(
srcdir, "/", names[ni])),
"\n");
};
ni += 1;
};
testenv.writefile(strings.concat(td, "/", base), body);
}; };
// dirname(fixture) leads the search path so bare same-module
// imports resolve as they do under the in-tree driver run.
@@ -281,17 +311,19 @@ fn checkone(e: *ent) void = {
if (e.fixture.len != 0) {
append(incs, strings.concat(testenv.repo(), "/",
dirnameof(e.fixture)));
};
} else { if (e.probe.len == 0 && e.moddir.len != 0) {
append(incs, strings.concat(testenv.repo(), "/", e.moddir));
}; };
if (e.inc.len != 0) {
append(incs, strings.concat(testenv.repo(), "/", e.inc));
};
// @test fixtures are main-less, so `test -S` carries -T
// (synthesizes the entry + auto-bundles lib/test); import probes
// carry their own fn main(), which -T loud-rejects (910), so they
// `build -S`.
// @test fixtures and dir-mode compositions are main-less, so
// `test -S` carries -T (synthesizes the entry + auto-bundles
// lib/test); import probes carry their own fn main(), which -T
// loud-rejects (910), so they `build -S`.
let sub: str = "test";
if (e.fixture.len == 0) { sub = "build"; };
if (e.probe.len != 0) { sub = "build"; };
let stem: str = stripext(base);
let stemc: str = strings.concat(td, "/c_", stem);
let stemw: str = strings.concat(td, "/w_", stem);