ww test: report no tests to run

This commit is contained in:
2026-08-21 16:15:12 +09:00
parent 2387d3e2d2
commit 17b2879c3e
6 changed files with 443 additions and 24 deletions

View File

@@ -835,16 +835,21 @@ fn cwdwritedata(dir: str, label: str) void = {
runcommand(root, "nomatch", nav,
(30i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(occurrences(out.stdout, "[no matches]\n") == 1);
assert(out.stderr.len == 0);
assert(occurrences(out.stdout,
"testing: warning: no tests to run\n") == 1);
assert(occurrences(out.stdout,
"3 discovered, 0 selected, 0 started, 0 completed\n") == 1);
assert(occurrences(out.stdout, strings.concat("ok ", target,
" [routing] [no tests to run]\n")) == 1);
let lnav: []str = [driver("ww"), "test", "-list", "-run",
"no-such-*", "-I", sourceroot, target];
runcommand(root, "list-nomatch", lnav,
(30i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(occurrences(out.stdout, "[no matches]\n") == 0);
assert(!has(out.stdout, "testing: warning: no tests to run"));
assert(!has(out.stdout, " [no tests to run]"));
assert(!has(out.stdout, " discovered, "));
clean(root);
};
@@ -901,7 +906,8 @@ fn cwdwritedata(dir: str, label: str) void = {
assert(occurrences(out.stdout, "alpha-init\n") == 1);
assert(occurrences(out.stdout, "beta-init\n") == 1);
assert(occurrences(out.stdout, "ok ") == 2);
assert(!has(out.stdout, "[no matches]"));
assert(!has(out.stdout, "testing: warning: no tests to run"));
assert(!has(out.stdout, " [no tests to run]"));
assert(!has(out.stdout, " discovered, "));
assert(!has(out.stdout, "list_alpha.first"));
assert(!has(out.stdout, "list_alpha.second"));
@@ -945,7 +951,8 @@ fn cwdwritedata(dir: str, label: str) void = {
assert(out.stderr.len == 0);
assert(occurrences(out.stdout, "alpha-init\n") == 1);
assert(occurrences(out.stdout, "ok ") == 1);
assert(!has(out.stdout, "[no matches]"));
assert(!has(out.stdout, "testing: warning: no tests to run"));
assert(!has(out.stdout, " [no tests to run]"));
assert(!has(out.stdout, "list_alpha."));
assert(os.exists(retained[i]));
retainedout[i] = strings.dup(out.stdout);
@@ -973,6 +980,216 @@ fn cwdwritedata(dir: str, label: str) void = {
clean(root);
};
@test fn ordinary_no_match_uses_go_warning_and_result_suffix() void = {
let root: str = fresh();
let alpha: str = strings.concat(root, "/alpha");
let beta: str = strings.concat(root, "/beta");
let none: str = strings.concat(root, "/none");
let broken: str = strings.concat(root, "/broken");
mkdirall(alpha);
mkdirall(beta);
mkdirall(none);
mkdirall(broken);
writefile(strings.concat(alpha, "/alpha.ww"),
"package zero_alpha;\nfn value() i32 = { return 1; };\n");
writefile(strings.concat(alpha, "/alpha_test.ww"), strings.concat(
"package zero_alpha;\nimport os;\n",
"@test fn first() void = {};\n",
"@test fn marker_text() void = {\n",
" let text: str = \"not-a-marker testing: warning: no tests to run\\n\";\n",
" os.write(os.STDOUT_FILENO, text.ptr, text.len: u64);\n",
"};\n"));
writefile(strings.concat(beta, "/beta.ww"),
"package zero_beta;\nfn value() i32 = { return 2; };\n");
writefile(strings.concat(beta, "/beta_test.ww"),
"package zero_beta;\n@test fn only() void = {};\n");
writefile(strings.concat(none, "/none.ww"),
"package zero_none;\nfn value() i32 = { return 3; };\n");
writefile(strings.concat(broken, "/broken.ww"),
"package zero_broken;\nfn value() missing_type = { return 4; };\n");
writefile(strings.concat(broken, "/broken_test.ww"),
"package zero_broken;\n@test fn registered() void = {};\n");
let warning: str = "testing: warning: no tests to run\n";
let suffix: str = " [no tests to run]";
let stages: []str = ["ww", "ww_ww"];
let tags: []str = ["c", "ww"];
let works: []str = [strings.concat(root, "/work-c"),
strings.concat(root, "/work-ww")];
let retained: []str = [strings.concat(root, "/retained-c.test"),
strings.concat(root, "/retained-ww.test")];
let coldout: []str = ["", ""];
let colderror: []str = ["", ""];
let positiveout: []str = ["", ""];
let positiveerror: []str = ["", ""];
let listout: []str = ["", ""];
let listerror: []str = ["", ""];
let retainedout: []str = ["", ""];
let retainederror: []str = ["", ""];
let manualout: []str = ["", ""];
let manualerror: []str = ["", ""];
let failurediagnostic: []str = ["", ""];
let out: commandout;
let i: i32 = 0;
for (i < stages.len) {
// Reverse request order and run two products concurrently. Result bytes
// remain directory-sorted and each product owns its own marker/suffix.
let emptyav: []str = [driver(stages[i]), "test", "-j", "2",
"-w", works[i], "-run", "no-such-*", beta, alpha];
runcommand(root, strings.concat("ordinary-empty-cold-", tags[i]),
emptyav, (90i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(out.stderr.len == 0);
assert(occurrences(out.stdout, warning) == 2);
assert(!has(out.stdout, "[no matches]"));
assert(occurrences(out.stdout,
"2 discovered, 0 selected, 0 started, 0 completed\n") == 1);
assert(occurrences(out.stdout,
"1 discovered, 0 selected, 0 started, 0 completed\n") == 1);
let alphaok: str = strings.concat("ok ", alpha,
" [zero_alpha] [no tests to run]\n");
let betaok: str = strings.concat("ok ", beta,
" [zero_beta] [no tests to run]\n");
let alphacount: i32 = pos(out.stdout,
"2 discovered, 0 selected, 0 started, 0 completed\n");
let alphareport: i32 = pos(out.stdout, alphaok);
let betacount: i32 = pos(out.stdout,
"1 discovered, 0 selected, 0 started, 0 completed\n");
let betareport: i32 = pos(out.stdout, betaok);
assert(alphacount >= 0 && alphacount < alphareport
&& alphareport < betacount && betacount < betareport);
assert(occurrences(out.stdout, alphaok) == 1);
assert(occurrences(out.stdout, betaok) == 1);
coldout[i] = strings.dup(out.stdout);
colderror[i] = strings.dup(out.stderr);
runcommand(root, strings.concat("ordinary-empty-warm-", tags[i]),
emptyav, (90i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(same(out.stdout, coldout[i]));
assert(same(out.stderr, colderror[i]));
assert(!directoryhasnew(works[i]));
// The same bytes inside a running test, but not at a line boundary, are
// ordinary user output and must not annotate a successful package result.
let positiveav: []str = [driver(stages[i]), "test", "-w",
works[i], "-run", "marker_text", alpha];
runcommand(root, strings.concat("ordinary-positive-", tags[i]),
positiveav, (90i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(out.stderr.len == 0);
assert(occurrences(out.stdout, warning) == 1);
assert(has(out.stdout, strings.concat("not-a-marker ", warning)));
assert(!has(out.stdout, suffix));
assert(has(out.stdout, strings.concat("ok ", alpha,
" [zero_alpha]\n")));
positiveout[i] = strings.dup(out.stdout);
positiveerror[i] = strings.dup(out.stderr);
// The already-closed list behavior remains an early return: no warning,
// accounting, old sentinel, or package suffix.
let listav: []str = [driver(stages[i]), "test", "-w", works[i],
"-list", "-run", "no-such-*", alpha];
runcommand(root, strings.concat("ordinary-list-control-", tags[i]),
listav, (90i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(same(out.stdout, strings.concat("ok ", alpha,
" [zero_alpha]\n")));
assert(out.stderr.len == 0);
assert(!has(out.stdout, warning) && !has(out.stdout, suffix));
assert(!has(out.stdout, " discovered, "));
listout[i] = strings.dup(out.stdout);
listerror[i] = strings.dup(out.stderr);
let noneav: []str = [driver(stages[i]), "test", "-w", works[i],
none];
runcommand(root, strings.concat("ordinary-no-files-", tags[i]),
noneav, (90i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(same(out.stdout, strings.concat("? ", none,
" [no test files]\n")));
assert(out.stderr.len == 0);
assert(!has(out.stdout, warning) && !has(out.stdout, suffix));
// A successful zero-selection run may publish its retained test binary.
let retainav: []str = [driver(stages[i]), "test", "-w", works[i],
"-o", retained[i], "-run", "no-such-*", alpha];
runcommand(root, strings.concat("ordinary-retained-", tags[i]),
retainav, (90i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(out.stderr.len == 0);
assert(occurrences(out.stdout, warning) == 1);
assert(occurrences(out.stdout, alphaok) == 1);
assert(os.exists(retained[i]));
assert(!os.exists(strings.concat(retained[i], ".sepwork")));
let prior: str = strings.dup(readfile(retained[i]));
retainedout[i] = strings.dup(out.stdout);
retainederror[i] = strings.dup(out.stderr);
// Direct execution exposes the harness-owned stream boundary: accounting
// remains stdout while the exact pinned warning is stderr.
let manualav: []str = [retained[i], "-package=zero_alpha",
"no-such-*"];
runcommand(root, strings.concat("ordinary-manual-", tags[i]), manualav,
(30i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(same(out.stdout,
"2 discovered, 0 selected, 0 started, 0 completed\n"));
assert(same(out.stderr, warning));
manualout[i] = strings.dup(out.stdout);
manualerror[i] = strings.dup(out.stderr);
// A producer failure wins before runtime and preserves a prior public
// binary. Cold and repeated failure have no warning, ok line, or suffix.
let failav: []str = [driver(stages[i]), "test", "-w", works[i],
"-o", retained[i], "-run", "no-such-*", broken];
runcommand(root, strings.concat("ordinary-failure-cold-", tags[i]),
failav, (90i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 1);
assert(same(out.stdout, "FAIL\n"));
assert(out.stderr.len != 0);
assert(!has(out.stdout, warning) && !has(out.stderr, warning));
assert(!has(out.stdout, suffix) && !has(out.stderr, suffix));
assert(!has(out.stdout, "ok ") && !has(out.stderr, "ok "));
assert(same(prior, readfile(retained[i])));
failurediagnostic[i] = strings.dup(primarydiagnostic(out.stderr));
let failstderr: str = strings.dup(out.stderr);
runcommand(root, strings.concat("ordinary-failure-warm-", tags[i]),
failav, (90i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 1);
assert(same(out.stdout, "FAIL\n"));
assert(same(out.stderr, failstderr));
assert(same(prior, readfile(retained[i])));
assert(!has(out.stdout, warning) && !has(out.stderr, warning));
// Restored valid reuse still emits the success marker/suffix and never
// rewrites an already-identical retained binary.
runcommand(root, strings.concat("ordinary-restored-", tags[i]), retainav,
(90i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(same(out.stdout, retainedout[i]));
assert(same(out.stderr, retainederror[i]));
assert(same(prior, readfile(retained[i])));
assert(!directoryhasnew(works[i]));
assert(!os.exists(strings.concat(retained[i], ".sepwork")));
i += 1;
};
assert(same(coldout[0], coldout[1]));
assert(same(colderror[0], colderror[1]));
assert(same(positiveout[0], positiveout[1]));
assert(same(positiveerror[0], positiveerror[1]));
assert(same(listout[0], listout[1]));
assert(same(listerror[0], listerror[1]));
assert(same(retainedout[0], retainedout[1]));
assert(same(retainederror[0], retainederror[1]));
assert(same(manualout[0], manualout[1]));
assert(same(manualerror[0], manualerror[1]));
assert(same(failurediagnostic[0], failurediagnostic[1]));
assert(same(readfile(retained[0]), readfile(retained[1])));
clean(root);
};
// Directory-package execution context is one product-level runtime property.
// This fixture keeps every source tree disposable while covering the variant,
// dependency, environment, routing, concurrency, persistence, and failure
@@ -1317,7 +1534,9 @@ fn cwdwritedata(dir: str, label: str) void = {
cwdassertpackage(out.stdout, "dep-init", p3, "p3-data", "p3-testdata");
cwdassertpackage(out.stdout, "testdep-init", p3,
"p3-data", "p3-testdata");
assert(has(out.stdout, "[no matches]\n"));
assert(has(out.stdout, "testing: warning: no tests to run\n"));
assert(has(out.stdout, strings.concat("ok ", p3,
" [p3] [no tests to run]\n")));
assert(!has(out.stdout, "p3-internal cwd="));
assert(!has(out.stdout, "p3-external cwd="));