A suite run in which no test passed exits non-zero and names its skips (issue 693)
mesh/merge-gate head 8635560993aa merged into trunk f9be71b9ad44 — pass: the change touches no module of the mesh's graph
mesh/repo-check head 8635560993aa merged into trunk f9be71b9ad44 — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (typescript)…
mesh/delivery-group group fix/693-a-run-that-proved-nothing-is-not-passed ready: every member ready, and composed together they pass
mesh/delivery superseded: a newer head of the same pull request

The runner exits 0 when every test skipped, so a bed that stopped before its
subject and skipped its only test as NOT REACHED was recorded as passed, "0
passed, 0 failed". The suite now collects each skip and its reason through a
reporter of its own, prints NOT PASSED and a skipped line per skip after its
recorded line, keeps them in the receipt, and exits 1 when no test passed or a
test was not reached. A skip for a declared reason beside passes stays passed.
This commit is contained in:
jochen
2026-10-14 03:14:05 +02:00
parent f9be71b9ad
commit 8635560993
5 changed files with 345 additions and 21 deletions
+7 -6
View File
@@ -5,7 +5,7 @@ import { counted, reportOn } from "../src/suite.ts";
// The totals come from the runner's own summary, and from nothing else.
test("the runner's totals are read from its summary", () => {
const said = counted("✔ something (1ms)\nℹ tests 22\nℹ pass 22\nℹ fail 0\n");
assert.deepEqual(said, { passed: 22, failed: 0 });
assert.deepEqual(said, { passed: 22, failed: 0, skipped: null });
});
// A test *named* like a total must not be mistaken for one. The summary is a line of its own, and
@@ -18,7 +18,7 @@ test("a test named like a total is not a total", () => {
// A failing run is read as a failing run.
test("failures are read", () => {
const said = counted("ℹ pass 21\nℹ fail 1\n");
assert.deepEqual(said, { passed: 21, failed: 1 });
assert.deepEqual(said, { passed: 21, failed: 1, skipped: null });
});
// **No totals is not zero failures.** A run whose result could not be read is a run nobody can say
@@ -36,7 +36,7 @@ test("output with no summary yields no totals rather than a clean bill", () => {
// check it — 04-ISSUES/005 in miniature, inside the fix for it.
test("a run whose result could not be read writes nothing", () => {
let wrote = false;
const said = reportOn({ passed: null, failed: null }, () => {
const said = reportOn({ passed: null, failed: null }, [], () => {
wrote = true;
return { against: {}, ran: [] };
});
@@ -46,12 +46,13 @@ test("a run whose result could not be read writes nothing", () => {
test("a run that was read is recorded, with what it was read against", () => {
let got: [number, number] | null = null;
const said = reportOn({ passed: 22, failed: 0 }, (p, f) => {
const said = reportOn({ passed: 22, failed: 0 }, [], (p, f) => {
got = [p, f];
return { against: { "mesh-lab": "abc1234" }, ran: ["test/integration/mesh.test.ts"] };
});
assert.deepEqual(got, [22, 0]);
assert.match(said, /mesh\.test\.ts — 22 passed, 0 failed, against mesh-lab abc1234/);
assert.match(said, /mesh\.test\.ts — 22 passed, 0 failed, 0 skipped, against mesh-lab abc1234/);
assert.doesNotMatch(said, /NOT PASSED/);
});
// The runner's real output, colours and all.
@@ -64,5 +65,5 @@ test("the runner's totals are read from output as it actually arrives", () => {
"\u001b[34m\u2139 pass 22\u001b[39m\n" +
"\u001b[34m\u2139 fail 0\u001b[39m\n" +
"\u001b[34m\u2139 duration_ms 98.9\u001b[39m\n";
assert.deepEqual(counted(real), { passed: 22, failed: 0 });
assert.deepEqual(counted(real), { passed: 22, failed: 0, skipped: null });
});