Adds the audit's optional strengthen: the re-serialized escape text is pinned per producer branch and wr.wwi is byte-id across stages.
105 lines
3.6 KiB
Plaintext
105 lines
3.6 KiB
Plaintext
package wwirune_test;
|
|
|
|
// .wwi round-trip observer for \u / \U Unicode escapes in exported
|
|
// rune defs. Port of the retired native carrier
|
|
// test/wcc/110_uniesc_run.c; every assertion preserved, the .wwi
|
|
// inspection added (the audit's optional strengthen).
|
|
//
|
|
// An exported wide-rune `def` re-serialized by the .wwi producer must
|
|
// re-parse into the same codepoint on the importer side (the
|
|
// write-twin of the lexer read-fix — cmd/w6c/wwi.c wwi_rune /
|
|
// selfhost/cmd/wcc/wwi.ww wwirune emit \u/\U above 0xFF). One def per
|
|
// serializer branch: \x (<= 0xFF), \u (<= 0xFFFF), \U. The claim
|
|
// REQUIRES a real multi-file module tree: a single-file two-package
|
|
// fixture builds through __root.unit.ww and never produces a wr.wwi
|
|
// (probed in residual-carrier-audit.json, 110 entry), so no corpus
|
|
// fixture can exercise the serializer.
|
|
//
|
|
// Both driver stages run and their wr.wwi must be byte-identical
|
|
// (rule 10); the serialized escape text itself is pinned per branch.
|
|
// Dropped C machinery, not assertions: the ww_ww-absent skip gate
|
|
// (the Make target declares both drivers) and the unlink/rmdir
|
|
// accounting (testenv.clean asserts the removal).
|
|
|
|
import os;
|
|
import os.exec;
|
|
import strings;
|
|
import testenv;
|
|
import time;
|
|
|
|
fn fail(label: str, why: str) void = {
|
|
let m: str = strings.concat("wwirune FAIL: ", label, " -- ", why,
|
|
"\n");
|
|
os.write(2, m.ptr, m.len: u64);
|
|
assert(false);
|
|
};
|
|
|
|
fn tmo() time.duration = {
|
|
return (240i64 * (time.second: i64)): time.duration;
|
|
};
|
|
|
|
fn runcode(dir: str, name: str, argv: []str) i32 = {
|
|
let co: testenv.commandout;
|
|
testenv.runcommand(dir, dir, name, argv, tmo(), &co);
|
|
if (co.termination != exec.termination.EXIT) { return -1; };
|
|
return co.code;
|
|
};
|
|
|
|
@test fn roundtrip() void = {
|
|
let drvs: []str = ["ww", "ww_ww"];
|
|
let wwis: []str = ["", ""];
|
|
let d: i32 = 0;
|
|
for (d < 2) {
|
|
let td: str = testenv.fresh();
|
|
assert(os.mkdir(strings.concat(td, "/wr"), 493) == 0);
|
|
testenv.writefile(strings.concat(td, "/wr/wr.ww"), strings.concat(
|
|
"package wr;\n",
|
|
"export def EACUTE: rune = '\\u00e9';\n",
|
|
"export def EURO: rune = '\\u20ac';\n",
|
|
"export def SMILEY: rune = '\\U0001F600';\n"));
|
|
testenv.writefile(strings.concat(td, "/main.ww"), strings.concat(
|
|
"package main;\n",
|
|
"import wr;\n",
|
|
"fn main() i32 = {\n",
|
|
" let a: rune = wr.EACUTE;\n",
|
|
" let b: rune = wr.EURO;\n",
|
|
" let c: rune = wr.SMILEY;\n",
|
|
" if ((a: u32) != 233u32) { return 1; };\n",
|
|
" if ((b: u32) != 8364u32) { return 2; };\n",
|
|
" if ((c: u32) != 128512u32) { return 3; };\n",
|
|
" return 42;\n",
|
|
"};\n"));
|
|
let av: []str = [testenv.driver(drvs[d]), "build", "main.ww"];
|
|
if (runcode(td, strings.concat("build_", drvs[d]), av) != 0) {
|
|
fail("roundtrip", strings.concat("build via ", drvs[d],
|
|
" failed"));
|
|
};
|
|
let rav: []str = [strings.concat(td, "/main")];
|
|
if (runcode(td, strings.concat("run_", drvs[d]), rav) != 42) {
|
|
fail("roundtrip", strings.concat(drvs[d], " built program ",
|
|
"exit != 42 (a wide-rune def re-parsed wrong)"));
|
|
};
|
|
wwis[d] = testenv.readfile(strings.concat(td,
|
|
"/main.sepwork/wr.wwi"));
|
|
testenv.clean(td);
|
|
d += 1;
|
|
};
|
|
|
|
// one needle per serializer branch, exact re-serialized text
|
|
let needles: []str = [
|
|
"export def EACUTE: rune = '\\xe9';\n",
|
|
"export def EURO: rune = '\\u20ac';\n",
|
|
"export def SMILEY: rune = '\\U0001f600';\n"];
|
|
let i: i32 = 0;
|
|
for (i < needles.len) {
|
|
if (!testenv.has(wwis[0], needles[i])) {
|
|
fail("roundtrip", strings.concat("wr.wwi lacks `", needles[i],
|
|
"` (serializer branch drifted)"));
|
|
};
|
|
i += 1;
|
|
};
|
|
if (!testenv.same(wwis[0], wwis[1])) {
|
|
fail("roundtrip", "cs wr.wwi != ww wr.wwi (rule 10)");
|
|
};
|
|
};
|