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).
171 lines
5.5 KiB
Plaintext
171 lines
5.5 KiB
Plaintext
// Vectors mirror ref/hare/strings/trim.ha where ww can express them.
|
||
// External strings_test package per the Go foo_test idiom (rule-5/9
|
||
// carve-out, task #16); the shared streq helper lives in
|
||
// helpers_test.ww — same-package test files compose in dir-mode
|
||
// (the package, not the file, is the unit of testing).
|
||
package strings_test;
|
||
|
||
import strings;
|
||
|
||
// ref/hare/strings/trim.ha:99-107.
|
||
|
||
@test fn trimprefix_cases() void = {
|
||
assert(!(!streq(strings.trimprefix("", ""), "")));
|
||
assert(!(!streq(strings.trimprefix("", "blablabla"), "")));
|
||
assert(!(!streq(strings.trimprefix("hello, world", "hello"), ", world")));
|
||
assert(!(!streq(strings.trimprefix("blablabla", "bla"), "blabla")));
|
||
// equal-length match strips to empty.
|
||
assert(!(!streq(strings.trimprefix("hello", "hello"), "")));
|
||
};
|
||
|
||
@test fn trimsuffix_cases() void = {
|
||
assert(!(!streq(strings.trimsuffix("", ""), "")));
|
||
assert(!(!streq(strings.trimsuffix("", "blablabla"), "")));
|
||
assert(!(!streq(strings.trimsuffix("hello, world", "world"), "hello, ")));
|
||
assert(!(!streq(strings.trimsuffix("blablabla", "bla"), "blabla")));
|
||
assert(!(!streq(strings.trimsuffix("hello", "hello"), "")));
|
||
};
|
||
|
||
// ---- ltrim / rtrim / trim ---------------------------------------------
|
||
// ref/hare/strings/trim.ha:75-97. 0-arg rows (#9) pin the ASCII
|
||
// whitespace set (' ', '\t', '\n', '\r' — ref/hare/strings/trim.ha:6).
|
||
|
||
@test fn ltrim_cases() void = {
|
||
let runes: [9]rune;
|
||
runes[0] = 'x';
|
||
runes[1] = 'a';
|
||
runes[2] = 0x1D68Au32: rune;
|
||
runes[3] = '(';
|
||
runes[4] = ')';
|
||
runes[5] = 'a';
|
||
runes[6] = 'b';
|
||
runes[7] = 'c';
|
||
runes[8] = 'd';
|
||
|
||
// 0-arg rows (8..10) strip ASCII whitespace per Hare (#9):
|
||
// only the leading side is stripped for ltrim.
|
||
let inputs: [11]str;
|
||
let argo: [11]i32;
|
||
let argn: [11]i32;
|
||
let want: [11]str;
|
||
inputs[0]=""; argo[0]=0; argn[0]=1; want[0]="";
|
||
inputs[1]="aaabc"; argo[1]=1; argn[1]=1; want[1]="bc";
|
||
inputs[2]="xyz"; argo[2]=1; argn[2]=1; want[2]="xyz";
|
||
inputs[3]="aaaa"; argo[3]=1; argn[3]=1; want[3]="";
|
||
inputs[4]="𝚊𝚊hi"; argo[4]=2; argn[4]=1; want[4]="hi";
|
||
inputs[5]="((()(())))())"; argo[5]=3; argn[5]=2; want[5]="";
|
||
inputs[6]="abacadabra"; argo[6]=5; argn[6]=4; want[6]="ra";
|
||
inputs[7]="hello"; argo[7]=0; argn[7]=0; want[7]="hello";
|
||
inputs[8]=" hello "; argo[8]=0; argn[8]=0; want[8]="hello ";
|
||
inputs[9]="\t\r\n hello"; argo[9]=0; argn[9]=0; want[9]="hello";
|
||
inputs[10]=" "; argo[10]=0; argn[10]=0; want[10]="";
|
||
|
||
let i: i32 = 0;
|
||
for (i < 11) {
|
||
let argv: []rune;
|
||
argv.ptr = &runes[argo[i]];
|
||
argv.len = argn[i];
|
||
argv.cap = argn[i];
|
||
let got: str = strings.ltrim(inputs[i], argv...);
|
||
assert(!(!streq(got, want[i])));
|
||
i += 1;
|
||
};
|
||
};
|
||
|
||
@test fn rtrim_cases() void = {
|
||
let runes: [19]rune;
|
||
runes[0] = 'x';
|
||
runes[1] = 'a';
|
||
runes[2] = 0x1D68Au32: rune;
|
||
runes[3] = 'w';
|
||
runes[4] = 'd';
|
||
runes[5] = 'o';
|
||
runes[6] = 'r';
|
||
runes[7] = ' ';
|
||
runes[8] = 's';
|
||
runes[9] = 'i';
|
||
runes[10] = 'l';
|
||
runes[11] = 'z';
|
||
runes[12] = 't';
|
||
runes[13] = 'm';
|
||
runes[14] = 'n';
|
||
runes[15] = 'o';
|
||
runes[16] = 'e';
|
||
runes[17] = 'a';
|
||
runes[18] = 'd';
|
||
|
||
// 0-arg rows (8..10) strip ASCII whitespace per Hare (#9):
|
||
// only the trailing side is stripped for rtrim.
|
||
let inputs: [11]str;
|
||
let argo: [11]i32;
|
||
let argn: [11]i32;
|
||
let want: [11]str;
|
||
inputs[0]=""; argo[0]=0; argn[0]=1; want[0]="";
|
||
inputs[1]="bcaaa"; argo[1]=1; argn[1]=1; want[1]="bc";
|
||
inputs[2]="xyz"; argo[2]=1; argn[2]=1; want[2]="xyz";
|
||
inputs[3]="aaaa"; argo[3]=1; argn[3]=1; want[3]="";
|
||
inputs[4]="hi𝚊𝚊"; argo[4]=2; argn[4]=1; want[4]="hi";
|
||
inputs[5]="yellowwooddoor";
|
||
argo[5]=3; argn[5]=4; want[5]="yell";
|
||
inputs[6]="Sentimentalized sensationalism sensationalized sentimentalisms";
|
||
argo[6]=7; argn[6]=12; want[6]="S";
|
||
inputs[7]="hello"; argo[7]=0; argn[7]=0; want[7]="hello";
|
||
inputs[8]=" hello "; argo[8]=0; argn[8]=0; want[8]=" hello";
|
||
inputs[9]="hello, world\r\n\r\n";
|
||
argo[9]=0; argn[9]=0; want[9]="hello, world";
|
||
inputs[10]=" "; argo[10]=0; argn[10]=0; want[10]="";
|
||
|
||
let i: i32 = 0;
|
||
for (i < 11) {
|
||
let argv: []rune;
|
||
argv.ptr = &runes[argo[i]];
|
||
argv.len = argn[i];
|
||
argv.cap = argn[i];
|
||
let got: str = strings.rtrim(inputs[i], argv...);
|
||
assert(!(!streq(got, want[i])));
|
||
i += 1;
|
||
};
|
||
};
|
||
|
||
@test fn trim_cases() void = {
|
||
let runes: [8]rune;
|
||
runes[0] = 'x';
|
||
runes[1] = 'a';
|
||
runes[2] = 'm';
|
||
runes[3] = 'i';
|
||
runes[4] = 'p';
|
||
runes[5] = 's';
|
||
runes[6] = '[';
|
||
runes[7] = ']';
|
||
|
||
// 0-arg rows (7..9) strip ASCII whitespace per Hare (#9) from
|
||
// both ends.
|
||
let inputs: [10]str;
|
||
let argo: [10]i32;
|
||
let argn: [10]i32;
|
||
let want: [10]str;
|
||
inputs[0]=""; argo[0]=0; argn[0]=1; want[0]="";
|
||
inputs[1]="aaabcaaa"; argo[1]=1; argn[1]=1; want[1]="bc";
|
||
inputs[2]="xyz"; argo[2]=1; argn[2]=1; want[2]="xyz";
|
||
inputs[3]="aaaa"; argo[3]=1; argn[3]=1; want[3]="";
|
||
inputs[4]="mississippi"; argo[4]=2; argn[4]=4; want[4]="";
|
||
inputs[5]="[[][[[]]][][].[[]][]]][]]]";
|
||
argo[5]=6; argn[5]=2; want[5]=".";
|
||
inputs[6]="hello"; argo[6]=0; argn[6]=0; want[6]="hello";
|
||
inputs[7]=" hello "; argo[7]=0; argn[7]=0; want[7]="hello";
|
||
inputs[8]="\r\thello\n\r"; argo[8]=0; argn[8]=0; want[8]="hello";
|
||
inputs[9]=" "; argo[9]=0; argn[9]=0; want[9]="";
|
||
|
||
let i: i32 = 0;
|
||
for (i < 10) {
|
||
let argv: []rune;
|
||
argv.ptr = &runes[argo[i]];
|
||
argv.len = argn[i];
|
||
argv.cap = argn[i];
|
||
let got: str = strings.trim(inputs[i], argv...);
|
||
assert(!(!streq(got, want[i])));
|
||
i += 1;
|
||
};
|
||
};
|
||
|