ww: keep generated test support file-scoped
This commit is contained in:
@@ -134,7 +134,6 @@ fn nooprow(label: str, src: str) void = {
|
||||
" return 0;\n",
|
||||
"};\n"));
|
||||
nooprow("free_alloc_roundtrip", strings.concat(
|
||||
"import rt;\n",
|
||||
"export fn main() i32 = {\n",
|
||||
" let p: *i64 = alloc(11i64)!;\n",
|
||||
" free(p);\n",
|
||||
|
||||
@@ -52,6 +52,7 @@ type ent = struct {
|
||||
cite: str, // task #59 entry for non-ID modes
|
||||
sentinel: str, // probe-only: proof the module body landed
|
||||
moddir: str, // probe-only: completeness key
|
||||
direct: bool, // build moddir itself; used when it exports no source name
|
||||
};
|
||||
|
||||
// Row constructors; the roster appends their results directly (#34
|
||||
@@ -59,7 +60,7 @@ type ent = struct {
|
||||
fn fx(f: str) ent = {
|
||||
let e: ent;
|
||||
e.fixture = f; e.probe = ""; e.inc = ""; e.mode = MID;
|
||||
e.cite = ""; e.sentinel = ""; e.moddir = "";
|
||||
e.cite = ""; e.sentinel = ""; e.moddir = ""; e.direct = false;
|
||||
return e;
|
||||
};
|
||||
|
||||
@@ -82,10 +83,10 @@ 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
|
||||
// Dir-mode entry: byte-id the module's composed test package (every
|
||||
// *_test.ww under moddir, module-reset separators, byte-lex order) through
|
||||
// both driver stages. The separators preserve each source file's import
|
||||
// scope. 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("");
|
||||
@@ -93,7 +94,17 @@ fn dx(moddir: str) ent = {
|
||||
return e;
|
||||
};
|
||||
|
||||
// The 60-unit roster. Graduation history lives in git (the retired C
|
||||
// Direct-directory entry for packages with no exported source name. Such a
|
||||
// package cannot have a valid nonblank import probe until blank imports exist.
|
||||
fn dr(moddir: str, sentinel: str) ent = {
|
||||
let e: ent = fx("");
|
||||
e.moddir = moddir;
|
||||
e.sentinel = sentinel;
|
||||
e.direct = true;
|
||||
return e;
|
||||
};
|
||||
|
||||
// The 56-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.
|
||||
fn corpus() []ent = {
|
||||
@@ -120,7 +131,7 @@ fn corpus() []ent = {
|
||||
append(es, fx("lib/math/random/random_test.ww"));
|
||||
append(es, fx("lib/memio/memio_test.ww"));
|
||||
append(es, fx("lib/os/os_test.ww"));
|
||||
append(es, pr("package main;\nimport os.exec;\nfn main() i32 = { return 0; };\n",
|
||||
append(es, pr("package main;\nimport os.exec;\nfn main() i32 = { return exec.termination.EXIT as i32; };\n",
|
||||
"package exec;", "lib/os/exec"));
|
||||
append(es, fx("lib/regex/regex_test.ww"));
|
||||
append(es, fx("lib/strconv/ftos_test.ww"));
|
||||
@@ -136,26 +147,25 @@ fn corpus() []ent = {
|
||||
append(es, fx("lib/bufio/stream_test.ww"));
|
||||
append(es, fx("lib/bufio/scanner_test.ww"));
|
||||
append(es, fx("lib/fmt/fmt_test.ww"));
|
||||
append(es, pr("package main;\nimport sort;\nfn main() i32 = { return 0; };\n",
|
||||
append(es, pr("package main;\nimport sort;\nfn use(v: sort.cmpfunc) void = {};\nfn main() i32 = { return 0; };\n",
|
||||
"package sort;", "lib/sort"));
|
||||
append(es, pr("package main;\nimport path;\nfn main() i32 = { return 0; };\n",
|
||||
append(es, pr("package main;\nimport path;\nfn use(v: path.buffer) void = {};\nfn main() i32 = { return 0; };\n",
|
||||
"package path;", "lib/path"));
|
||||
append(es, pr("package main;\nimport endian;\nfn main() i32 = { return 0; };\n",
|
||||
append(es, pr("package main;\nimport endian;\nfn main() i32 = { let b: [2]u8; return endian.begetu16(b[0:2]): i32; };\n",
|
||||
"package endian;", "lib/endian"));
|
||||
append(es, pr("package main;\nimport net;\nfn main() i32 = { return 0; };\n",
|
||||
append(es, pr("package main;\nimport net;\nfn use(v: net.sockaddrin) void = {};\nfn main() i32 = { return 0; };\n",
|
||||
"package net;", "lib/net"));
|
||||
append(es, pr("package main;\nimport hash;\nfn main() i32 = { return 0; };\n",
|
||||
append(es, pr("package main;\nimport hash;\nfn use(v: hash.hash) void = {};\nfn main() i32 = { return 0; };\n",
|
||||
"package hash;", "lib/hash"));
|
||||
// fnv lives below the driver's default root, so its canonical
|
||||
// directory is found from the explicit parent import root.
|
||||
append(es, pri("package main;\nimport fnv;\nfn main() i32 = { return 0; };\n",
|
||||
append(es, pri("package main;\nimport fnv;\nfn main() i32 = { let b: []u8; let _ = fnv.fnv1a(b); return 0; };\n",
|
||||
"lib/hash", "package fnv;", "lib/hash/fnv"));
|
||||
// Sentinel is a fn, not `package math;` — lib/math is also package
|
||||
// math, so the package clause alone would not prove the right body.
|
||||
append(es, pr("package main;\nimport crypto.math;\nfn main() i32 = { return 0; };\n",
|
||||
append(es, pr("package main;\nimport crypto.math;\nfn main() i32 = { return math.rotl32(0u32, 0): i32; };\n",
|
||||
"fn rotl32", "lib/crypto/math"));
|
||||
append(es, pr("package main;\nimport c.libc;\nfn main() i32 = { return 0; };\n",
|
||||
"package libc;", "lib/c/libc"));
|
||||
append(es, dr("lib/c/libc", "package libc;"));
|
||||
// root-only, ZERO-dep build -S: the one driver-leg edge every
|
||||
// import probe misses (dep-count-0 unit composition). Folded in
|
||||
// from the retired 815/940/951 driver-parity carriers. No
|
||||
@@ -245,6 +255,28 @@ fn catasm(sepdir: str) str = {
|
||||
return out;
|
||||
};
|
||||
|
||||
fn hasunit(sepdir: str) bool = {
|
||||
if (!testenv.isdir(sepdir)) { return false; };
|
||||
let names: []str = testenv.listdir(sepdir);
|
||||
let i: i32 = 0;
|
||||
for (i < names.len) {
|
||||
if (strings.hassuffix(names[i], ".unit.ww")) { return true; };
|
||||
i += 1;
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
fn hasasm(sepdir: str) bool = {
|
||||
if (!testenv.isdir(sepdir)) { return false; };
|
||||
let names: []str = testenv.listdir(sepdir);
|
||||
let i: i32 = 0;
|
||||
for (i < names.len) {
|
||||
if (strings.hassuffix(names[i], ".s")) { return true; };
|
||||
i += 1;
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
fn buildstage(td: str, name: str, drv: str, sub: str, incs: []str,
|
||||
stem: str, base: str) bool = {
|
||||
let av: []str = [];
|
||||
@@ -280,10 +312,10 @@ fn checkone(e: *ent) void = {
|
||||
e.fixture)));
|
||||
} else { if (e.probe.len != 0) {
|
||||
testenv.writefile(strings.concat(td, "/", base), e.probe);
|
||||
} else { if (e.direct) {
|
||||
base = strings.concat(testenv.repo(), "/", e.moddir);
|
||||
} else {
|
||||
// dir-mode: compose every *_test.ww under moddir exactly
|
||||
// as pkgcombined does (external group: test sources only,
|
||||
// module-reset separators; testenv.listdir sorts).
|
||||
// Dir-mode keeps every source in its own module-reset section.
|
||||
base = "combined.ww";
|
||||
let srcdir: str = strings.concat(testenv.repo(), "/",
|
||||
e.moddir);
|
||||
@@ -301,7 +333,7 @@ fn checkone(e: *ent) void = {
|
||||
ni += 1;
|
||||
};
|
||||
testenv.writefile(strings.concat(td, "/", base), body);
|
||||
}; };
|
||||
}; }; };
|
||||
|
||||
// Most packages resolve from the driver's canonical lib/ root.
|
||||
// Nested packages whose tests use a bare leaf import carry an
|
||||
@@ -317,8 +349,9 @@ fn checkone(e: *ent) void = {
|
||||
// lib/test); import probes carry their own fn main(), which -T
|
||||
// loud-rejects (910), so they `build -S`.
|
||||
let sub: str = "test";
|
||||
if (e.probe.len != 0) { sub = "build"; };
|
||||
let stem: str = stripext(base);
|
||||
if (e.probe.len != 0 || e.direct) { sub = "build"; };
|
||||
let stem: str = "direct";
|
||||
if (!e.direct) { stem = stripext(base); };
|
||||
let stemc: str = strings.concat(td, "/c_", stem);
|
||||
let stemw: str = strings.concat(td, "/w_", stem);
|
||||
|
||||
@@ -327,10 +360,14 @@ fn checkone(e: *ent) void = {
|
||||
let we: bool = buildstage(td, "wwstage", testenv.driver("ww_ww"), sub,
|
||||
incs, stemw, base);
|
||||
|
||||
// the cstage build resolves the units; its __root.unit.ww proves
|
||||
// resolution ran. WWREJECT still requires cstage to compile.
|
||||
if (!ce || !testenv.exists(strings.concat(stemc,
|
||||
".sepwork/__root.unit.ww"))) {
|
||||
// The cstage build resolves the units. A source probe owns __root; a
|
||||
// directly selected package retains its canonical import identity.
|
||||
// WWREJECT still requires cstage to compile.
|
||||
let resolvedunit: str = strings.concat(stemc,
|
||||
".sepwork/__root.unit.ww");
|
||||
let resolved: bool = testenv.exists(resolvedunit);
|
||||
if (e.direct) { resolved = hasunit(strings.concat(stemc, ".sepwork")); };
|
||||
if (!ce || !resolved) {
|
||||
fail(label, "cstage produced no resolved unit");
|
||||
};
|
||||
|
||||
@@ -367,10 +404,15 @@ fn checkone(e: *ent) void = {
|
||||
};
|
||||
if (!we) { fail(label, "wwstage rejected"); };
|
||||
|
||||
let cs: str = catasm(strings.concat(stemc, ".sepwork"));
|
||||
let ws: str = catasm(strings.concat(stemw, ".sepwork"));
|
||||
// two empty concats compare equal — that green covers nothing
|
||||
if (cs.len == 0 || ws.len == 0) {
|
||||
let csep: str = strings.concat(stemc, ".sepwork");
|
||||
let wsep: str = strings.concat(stemw, ".sepwork");
|
||||
let cs: str = catasm(csep);
|
||||
let ws: str = catasm(wsep);
|
||||
// Two missing assembly sets compare equal and cover nothing. A directly
|
||||
// selected declaration-only package legitimately emits an empty .s file;
|
||||
// its resolved owner unit and sentinel above prove the source was compiled.
|
||||
if (!hasasm(csep) || !hasasm(wsep)
|
||||
|| (!e.direct && (cs.len == 0 || ws.len == 0))) {
|
||||
fail(label, "empty .s concat");
|
||||
};
|
||||
let idsame: bool = testenv.same(cs, ws);
|
||||
|
||||
Reference in New Issue
Block a user