diff --git a/client/electron/test/run-all.mjs b/client/electron/test/run-all.mjs index a19cfb1..8aaf842 100644 --- a/client/electron/test/run-all.mjs +++ b/client/electron/test/run-all.mjs @@ -190,6 +190,12 @@ const reds = []; let totalTests = 0; /** 逐文件自报的**失败**条数之和(`fail=` 那一格)。`pass + fail == checks` 是恒等式 */ let totalFail = 0; +/** + * **实际跑了但没能自报条数**的文件数 —— 这个数必须显式打出来。 + * 没有它,`checks=` 会**静默少算**(跑过的文件里有多少条没被计入,读者看不出来)。 + * 我第一次量就撞上了:`checks=379` 而逐文件手算合计 386,差的 7 条正是这些文件里的。 + */ +let unreportedFiles = 0; /** 实际跑过(并解析到自报条数)的文件数 —— 与 `SUITE.length` 分开报,差额看得见 */ let ranFilesCount = 0; /* @@ -291,6 +297,7 @@ for (const [file, flags, expected] of SUITE) { ranFilesCount += 1; totalFail += marker ? Number(marker[2]) : (nodeFail ? Number(nodeFail[1]) : 0); } if (ran === null) { + unreportedFiles += 1; /* * 报错**自带修法**(pi 2026-09-14):这条契约的受众不只是读过规范的人 —— * 并发写 WebUI 的 agent 新加判据时不会打开 CRITERIA.md,看到红的第一反应 @@ -308,11 +315,18 @@ for (const [file, flags, expected] of SUITE) { console.log(\`RESULT pass=\${pass} fail=\${fail}\`); 样板:test/theme.test.mjs、test/background.test.mjs (用 node:test 写的判据不用管:runner 认 \`# pass N\`。)`); - } else if (expected > 0 && ran < expected) { - reds.push(`${file} - ↳ 自报 ${ran} 条 < 清单里登记的 ${expected} 条。常见成因:判据被删/被跳过(写在 process.exit() 之后、 + } else if (expected > 0 && ran !== expected) { + // **相等**,不是"不少于"(pi 邮件 `9fed4386`):只判下界时,**多加的条数不受保护** —— + // 下一个人删掉那条"多出来的"判据不会有任何东西变红,于是"被删会红"这个性质只覆盖前缀。 + // 两个方向的成因与处置都不同,所以分开写。 + const why = ran < expected + ? `自报 ${ran} 条 < 清单里登记的 ${expected} 条。常见成因:判据被删/被跳过(写在 process.exit() 之后、 条件里提前 return)、check() 的实现被改坏(合并冲突)、marker 打在了汇总之前但计数没接上。 - 确认确实该减少条数时,把清单里那个数字一起改掉(那是一次显式、可复核的编辑)。`); + 确认确实该减少条数时,把清单里那个数字一起改掉(那是一次显式、可复核的编辑)。` + : `自报 ${ran} 条 > 清单里登记的 ${expected} 条 —— 新加的那几条**不在"被删会红"的保护内**: + 只判下界时,删掉多出来的部分不会有任何东西变红。请把清单里这个数字改成 ${ran}(一次显式编辑), + 新判据才真正被登记保护。`; + reds.push(`${file}\n ↳ ${why}`); } } } @@ -633,7 +647,7 @@ console.log(`\n========== 判据汇总 ==========`); */ const totalsLine = (verdict) => `RESULT files=${SUITE.length} ran=${ranFilesCount} ` + `checks=${totalTests} pass=${totalTests - totalFail} fail=${totalFail} ` + - `broken=${brokens.length} verdict=${verdict}`; + `broken=${brokens.length} unreported=${unreportedFiles} verdict=${verdict}`; if (reds.length === 0 && brokens.length === 0) { // 报**本相位实际跑了**几条,不报清单长度 —— 上面刚写完"不能声称自己做过的事", // 这里如果打 SUITE.length 就是在同一行里犯同一个错(2 条构建相位判据被跳过了)。