lib: split path_test into buffer/stack/posix tests per ref/hare/path
Mirror ref/hare/path's impl layout in the test siblings: abs/isroot/string/local rows -> buffer_test.ww (ref/hare/path/ buffer.ha:28-77); push/parent/pop-split rows -> stack_test.ww (ref/hare/path/stack.ha:9-180); dirname/basename rows -> posix_test.ww (ref/hare/path/posix.ha:17-71). Pure move: every @test block is byte-identical; only the section banner lines are deleted (file names now carry them) and each section's ref-cite WHY comment rides with its @test. The suite header's Hare-vector/parallel-array WHY paragraphs ride with stack_test.ww (push is their subject); the stale `ww run lib/path/path_test.ww` sentence is dropped, not relocated. Consumers: Makefile LIBRARY_TESTS entry replaced in place. The byteid roster is untouched: lib/path is enrolled there as an import-probe, not a fixture.
This commit is contained in:
128
lib/path/stack_test.ww
Normal file
128
lib/path/stack_test.ww
Normal file
@@ -0,0 +1,128 @@
|
||||
// Vectors mirror Hare's @test fns in ref/hare/path/stack.ha:77-119
|
||||
// and buffer.ha. The absolute rows (Hare's `local("/")`-seeded) DEFER
|
||||
// to c3 (abs/local unimplemented); only the relative rows run here.
|
||||
//
|
||||
// Parallel `[N]str` row arrays (rather than `[N]struct{...}`) sidestep
|
||||
// the cstage cgen chained `arr[i].field` store gap (getopt_test.ww:6).
|
||||
// push is stateful, so each row is applied in sequence to one buffer;
|
||||
// the table holds {segment, expected-string} pairs (stack.ha:36-42 is
|
||||
// the normalization spec these rows encode).
|
||||
|
||||
package path_test;
|
||||
|
||||
import path;
|
||||
|
||||
|
||||
// ref/hare/path/stack.ha:77-119 (relative rows only; absolute local()
|
||||
// rows defer to c3). The dot/dotdot handling exercised here IS the
|
||||
// appendnorm normalization spec (stack.ha:36-42), so no separate
|
||||
// appendnorm @test is needed.
|
||||
|
||||
@test fn push_cases() void = {
|
||||
let buf = buffer { ... };
|
||||
assert(!(string(&buf) != "."));
|
||||
|
||||
// current-dir + parent-dir invariants (stack.ha:82-88). Single
|
||||
// segment per row → table-driven sequential apply.
|
||||
let segs: [5]str;
|
||||
let wants: [5]str;
|
||||
segs[0]=""; wants[0]=".";
|
||||
segs[1]="."; wants[1]=".";
|
||||
segs[2]=".."; wants[2]="..";
|
||||
segs[3]=""; wants[3]="..";
|
||||
segs[4]="."; wants[4]="..";
|
||||
let i: i32 = 0;
|
||||
for (i < 5) {
|
||||
assert(!(push(&buf, segs[i])! != wants[i]));
|
||||
i += 1;
|
||||
};
|
||||
|
||||
// set(&buf) resets to "." (stack.ha:91). set forwards an EMPTY
|
||||
// variadic into push (KEN-oracle flag 1: zero-arg gather+forward).
|
||||
assert(!(set(&buf)! != "."));
|
||||
|
||||
// regular path + parent (stack.ha:101-104, minus the local() row).
|
||||
let segs2: [3]str;
|
||||
let wants2: [3]str;
|
||||
segs2[0]="foo"; wants2[0]="foo";
|
||||
segs2[1]="."; wants2[1]="foo";
|
||||
segs2[2]=".."; wants2[2]=".";
|
||||
let k: i32 = 0;
|
||||
for (k < 3) {
|
||||
assert(!(push(&buf, segs2[k])! != wants2[k]));
|
||||
k += 1;
|
||||
};
|
||||
|
||||
// multi-segment (stack.ha:107-111). Variadic arity varies (1 or 2)
|
||||
// → inline.
|
||||
assert(!(push(&buf, "a", "b")! != "a/b"));
|
||||
assert(!(push(&buf, "..", "c")! != "a/c"));
|
||||
assert(!(push(&buf, "..")! != "a"));
|
||||
// stack.ha:110; local()→literal, SEP='/' on Linux, proper local() rides c3
|
||||
assert(!(push(&buf, "/d")! != "a/d"));
|
||||
assert(!(push(&buf, "..", "..")! != ".")); // stack.ha:111
|
||||
|
||||
// leading-SEP segment into an EMPTY buffer exercises push's
|
||||
// `j==0 && buf.end==0` root-seed arm (stack.ha:18-20), unreached
|
||||
// by the relative rows above. Hare covers it via local("/")-seeded
|
||||
// rows that defer to c3; literal "/foo" stands in (SEP='/' on Linux).
|
||||
assert(!(set(&buf)! != "."));
|
||||
assert(!(push(&buf, "/foo")! != "/foo"));
|
||||
};
|
||||
|
||||
// ref/hare/path/stack.ha:172-180. Parent dir; root → root; empty → "..".
|
||||
// Each row reseeds a reset buffer (parent goes through appendnorm). push's
|
||||
// normalized echo is dropped so the empty-buffer row ("" pushes to ".",
|
||||
// not "") can share the table.
|
||||
|
||||
@test fn parent_cases() void = {
|
||||
let buf = buffer { ... };
|
||||
let ins: [5]str;
|
||||
let want: [5]str;
|
||||
ins[0]="/usr/lib"; want[0]="/usr";
|
||||
ins[1]="foo"; want[1]=".";
|
||||
ins[2]="/"; want[2]="/";
|
||||
ins[3]="a/b/c"; want[3]="a/b";
|
||||
ins[4]=""; want[4]=".."; // empty buffer: appendnorm(dotdot) → ".."
|
||||
let i: i32 = 0;
|
||||
for (i < 5) {
|
||||
buf.end = 0;
|
||||
push(&buf, ins[i])!;
|
||||
assert(!(parent(&buf)! != want[i]));
|
||||
i += 1;
|
||||
};
|
||||
};
|
||||
|
||||
// ref/hare/path/stack.ha:147-170 (@test pop). split is the helper, covered
|
||||
// through pop/peek. Sequential off ONE buffer, reset buf.end=0 per case.
|
||||
// The peek-then-string-unchanged assert is load-bearing: it pins that the
|
||||
// #48 respelling didn't smuggle in pop's buf.end mutation.
|
||||
|
||||
@test fn popsplit_cases() void = {
|
||||
let buf = buffer { ... };
|
||||
|
||||
// empty
|
||||
assert(!(!(pop(&buf) is void)));
|
||||
assert(!(string(&buf) != "."));
|
||||
|
||||
// root dir
|
||||
buf.end = 0;
|
||||
assert(!(push(&buf, "/")! != "/"));
|
||||
assert(!(!(pop(&buf) is void)));
|
||||
assert(!(string(&buf) != "/"));
|
||||
|
||||
// relative file — peek is NON-mutating
|
||||
buf.end = 0;
|
||||
assert(!(push(&buf, "foo")! != "foo"));
|
||||
assert(!(peek(&buf) as str != "foo"));
|
||||
assert(!(string(&buf) != "foo"));
|
||||
assert(!(pop(&buf) as str != "foo"));
|
||||
assert(!(string(&buf) != "."));
|
||||
|
||||
// absolute file
|
||||
buf.end = 0;
|
||||
assert(!(push(&buf, "/foo")! != "/foo"));
|
||||
assert(!(peek(&buf) as str != "foo"));
|
||||
assert(!(pop(&buf) as str != "foo"));
|
||||
assert(!(string(&buf) != "/"));
|
||||
};
|
||||
Reference in New Issue
Block a user