Pure move: log_test.ww dissolves along its banner seams into funcs_test.ww (the six logger-arg rows — lprintlnbasic/single/empty, lprintflnbasic/indexed/mods — plus the fatal-family subprocess TODO; ref/hare/log/funcs.ha owns lprintln/lprintfln and the fatal/lfatal forms) and global_test.ww (defaultwiredtoglobal, setloggerswap, printflnglobal; ref/hare/log/global.ha owns default/global/setlogger). Moved blocks are byte-identical; the 9 banner lines are deleted. Imports minimized per file (log + memio; the stale fmt/io imports drop). Helper inventory: streq spans both halves (all six funcs rows; setloggerswap + printflnglobal on the global side), so it is duplicated under per-file names per the sanctioned strconv streq/fstreq precedent — fstreq in funcs_test.ww (decl + 6 call sites), gstreq in global_test.ww (decl + 6 call sites); bodies byte-identical apart from the name. Line-multiset diff old-vs-concat (heads/banners excluded, names normalized): the only residue is the 9-line streq helper counted twice. Order-safety, proven on the composed run: dir-mode executes declaration order per file, files byte-lexicographic (funcs_test < global_test < silent_test). Observed order: lprintlnbasic, lprintlnsingle, lprintlnempty, lprintflnbasic, lprintflnindexed, lprintflnmods, defaultwiredtoglobal, setloggerswap, printflnglobal, silentwritesnothing, silentignoresprintfln — defaultwiredtoglobal still precedes every log.setlogger caller (setloggerswap and printflnglobal, both later in its own file; funcs and silent rows never call setlogger). Consumers: Makefile LIBRARY_TESTS replaces the log_test.ww entry with the two new entries in place; test/byteid/libbyteid_test.ww roster row becomes two fx rows, NENTEXPECT 59->60. Validation: standalone ww test lib/log/funcs_test.ww (6 passed) and lib/log/global_test.ww (3 passed); dir mode ww test lib/log (11 passed, no duplicate symbols); byteid compile-only build exit 0, 60 roster appends == NENTEXPECT.
96 lines
3.0 KiB
Plaintext
96 lines
3.0 KiB
Plaintext
// globaltest — exercises the global-logger wiring (default / global /
|
|
// setlogger) per ref/hare/log/global.ha ownership. Each scenario
|
|
// constructs stdloggers over memio.streams and asserts the bytes the
|
|
// global dispatch produced. defaultwiredtoglobal must stay the first
|
|
// @test row: it pins the pristine global == default wiring that every
|
|
// later setlogger caller mutates. Composed dir-mode execution is
|
|
// declaration order per file, files in byte-lexicographic order
|
|
// (funcs_test < global_test < silent_test), and no funcs/silent row
|
|
// calls setlogger.
|
|
|
|
package log_test;
|
|
|
|
import log;
|
|
import memio;
|
|
|
|
fn gstreq(a: str, b: str) bool = {
|
|
if (a.len != b.len) { return false; };
|
|
let i: i32 = 0;
|
|
for (i < a.len) {
|
|
if (a[i] != b[i]) { return false; };
|
|
i += 1;
|
|
};
|
|
return true;
|
|
};
|
|
|
|
// log.default writes to stderr through the private stderrsink — we
|
|
// can't easily capture stderr from inside the test, so this scenario
|
|
// verifies the initial wiring only: after lazy [[ensureinit]] runs,
|
|
// [[log.default]] / [[log.silent]] are non-nil and [[log.global]]
|
|
// equals [[log.default]]. The check is order-sensitive: any later
|
|
// scenario that calls [[log.setlogger]] mutates the global, so this
|
|
// scenario must run before [[setloggerswap]].
|
|
@test fn defaultwiredtoglobal() void = {
|
|
let buf: [4]u8;
|
|
let mem = memio.fixed(buf[0:4]);
|
|
let s = &mem.vt;
|
|
let sl = log.new(s); // triggers ensureinit
|
|
|
|
assert(!(log.silent == nil));
|
|
assert(!(log.default == nil));
|
|
assert(!(log.global == nil));
|
|
assert(!(log.global != log.default));
|
|
};
|
|
|
|
// Three-phase: install sl1 as global, println writes there; swap to
|
|
// sl2, println writes there only; swap to silent, println discards.
|
|
// Each memio sink starts empty and is asserted at each phase to pin
|
|
// the swap semantics.
|
|
@test fn setloggerswap() void = {
|
|
let buf1: [32]u8;
|
|
let mem1 = memio.fixed(buf1[0:32]);
|
|
let s1 = &mem1.vt;
|
|
let sl1 = log.new(s1);
|
|
|
|
let buf2: [32]u8;
|
|
let mem2 = memio.fixed(buf2[0:32]);
|
|
let s2 = &mem2.vt;
|
|
let sl2 = log.new(s2);
|
|
|
|
log.setlogger(&sl1.logger);
|
|
log.println("first");
|
|
assert(!(!gstreq(memio.string(&mem1), "first\n")));
|
|
assert(!(mem2.pos != 0));
|
|
|
|
log.setlogger(&sl2.logger);
|
|
log.println("second");
|
|
assert(!(!gstreq(memio.string(&mem2), "second\n")));
|
|
// mem1 must be unchanged.
|
|
assert(!(!gstreq(memio.string(&mem1), "first\n")));
|
|
|
|
log.setlogger(log.silent);
|
|
log.println("dropped");
|
|
// Both sinks unchanged.
|
|
assert(!(!gstreq(memio.string(&mem1), "first\n")));
|
|
assert(!(!gstreq(memio.string(&mem2), "second\n")));
|
|
};
|
|
|
|
// Mirrors [[setloggerswap]] but exercises the format-string path:
|
|
// install sl1 as global, printfln writes there; mem2 stays empty.
|
|
@test fn printflnglobal() void = {
|
|
let buf1: [32]u8;
|
|
let mem1 = memio.fixed(buf1[0:32]);
|
|
let s1 = &mem1.vt;
|
|
let sl1 = log.new(s1);
|
|
|
|
let buf2: [32]u8;
|
|
let mem2 = memio.fixed(buf2[0:32]);
|
|
let s2 = &mem2.vt;
|
|
let sl2 = log.new(s2);
|
|
|
|
log.setlogger(&sl1.logger);
|
|
log.printfln("v={}", 7i64);
|
|
assert(!(!gstreq(memio.string(&mem1), "v=7\n")));
|
|
assert(!(mem2.pos != 0));
|
|
};
|