修复: 反面对照的**样本表自己没人守** —— 删掉 5 个样本里的 3 个,默认跑 0 条 RED、静默缩水
我自己变异出来的(M45)。这是 `957ec5e` 新加那道防线**内部**的缺口, 而且缺口长在"**覆盖**"这件事本身上。 ## 一、缺陷:`发现规则在 N 种写法上都有对照` 当时是**散文**,不是判据 实测:把 `FORM_SAMPLES` 的 5 个样本**删掉 3 个**(只留 `function 声明` 与 `const = async`) ⇒ 默认跑 **0 条 RED**、`red` 仍是 9(与干净树逐字相同), 只是成功报文里那半句从"在 **5** 种写法上都有对照"变成"在 **2** 种写法上…"。 ⇒ 它把 N 打出来,而 **N 变小没有任何东西拦**。 而"样本齐不齐"正是这条防线**唯一的防线** —— 样本可以被悄悄删光, 防线的覆盖就静默退回到"只验我恰好留下的那一种"。 **这是"判据存在 vs 判据在路径上"的又一个变体:样本在,但"样本够不够"没有判据。** ★ 与我上一轮那条同源、但换了一层:`957ec5e` 修的是"**发现规则看不见某种写法**", 这次是"**样本表可以静默缩水**" —— 修掉前者之后,后者的存在才显出来。 **每修一层,缺口换一层**,这与 `baseline` 那条线"接缝会移动"是同一个观察。 ## 二、修法:要求清单**具名**,两个方向都判 · 列出 `REQUIRED_FORMS`(要覆盖哪些写法,**具名**); · ① 每种要求的写法都必须有样本(⇒ **删样本 = 红,并指名删的是哪一种**); · ② 每个样本都必须能被认出来(原有方向); · ③ 多出来的样本未登记进 `REQUIRED_FORMS` ⇒ 也红(加了样本却没说守哪种写法)。 ★ 为什么不用 `assert length >= 5`:那个数**自己**就是可以随手改小的常量, 改小它不会留下任何痕迹。具名清单让"我要放弃支持箭头函数写法"变成一次**看得见的声明**。 成功报文也随之带上"(要求 5 种,缺一即红)",让**要求**和**实际**同时可见。 ## 三、变异验证(都已还原) | 变异 | 结果 | |---|---| | **M45** 删掉 3 个样本 | **红**:`这些写法要求覆盖、却没有样本:箭头函数、async function、名与括号间有空格`,`red=9→10`(**修复前 0 条 RED**) | | **M46** 加一个未登记的多余样本 | **红** 2 条:`不在要求清单里` + `发现规则认不出这些写法` | | 回归:**M40/M41/M42** 箭头/async/带空格三种未接线写法 | 各 **1 条报警**(`957ec5e` 的修复未被破坏) | | 回归:**M43** 发现规则退化回窄正则 | **红**:`认不出…` | ## 四、验证与状态 · 五个自检单独跑仍全 rc=0;默认跑 `checks=459 pass=455 fail=4 skip=0 red=9 … verdict=red`、 `mutants=48 ran=47 skipped=1 on_new_criteria=35 diag=none baseline=7/7✓`; 自检段现为 `…发现规则在 5 种写法上都有对照(要求 5 种,缺一即红)`。 · 残留全清;`git status` 仅本文件;`HEAD=957ec5e`。 · 同期 pi 已把我在它插件里报的那例修好并提交 `cc8beb7`(`--self-check` 改进程内 + 默认路径先跑 + 量纲分三档)。我**复核过**它:干净树 rc=0 且自检真出现在默认路径上,变异 `findDuplicates → []` ⇒ `npm test` **rc=3** 并打出"工具坏了,不是被测代码坏了"。它的目录我一行未动。
This commit is contained in:
@ -2370,6 +2370,40 @@ let selfCheckRuns = 0;
|
||||
['名与括号间有空格', 'function fooSelfTest (a) {}\n'],
|
||||
['const = async (…', 'const fooSelfTest = async (a) => {};\n'],
|
||||
];
|
||||
/*
|
||||
* ★★ **样本表本身也必须被钉住**(我自己变异出来的 M45)。
|
||||
*
|
||||
* 实测:把 5 个样本**删掉 3 个**(只留 `function` 声明与 `const = async`)
|
||||
* ⇒ 默认跑 **0 条 RED**、`red` 仍是 9,只是成功报文里那半句从
|
||||
* "在 **5** 种写法上都有对照" 变成 "在 **2** 种写法上…"。
|
||||
* ⇒ 也就是说 **"发现规则在 N 种写法上都有对照" 当时是散文,不是判据**:
|
||||
* 它把 N 打出来,而 N 变小**没有任何东西拦**。
|
||||
* 而"样本齐不齐"正是这条防线**唯一的防线** —— 样本可以被悄悄删光,
|
||||
* 防线的覆盖就静默地退回到"只验我恰好留下的那一种"。
|
||||
* **这是"判据存在 vs 判据在路径上"的又一个变体**:样本在,但"样本够不够"没判据。
|
||||
*
|
||||
* ⇒ 修法:把**要求覆盖的写法**列成一份**具名的**清单(`REQUIRED_FORMS`),
|
||||
* 然后两个方向都判:
|
||||
* ① 每种**要求**的写法都必须有样本(⇒ 删样本 = 红,不再是静默);
|
||||
* ② 每个样本都必须能被认出来(原有方向)。
|
||||
* ⇒ 删样本现在会红,而且**指名**删的是哪一种。
|
||||
* (为什么不是"断言 `length >= 5`":那个数**自己**就是可以随手改小的常量;
|
||||
* 具名清单至少让"我要放弃支持箭头函数写法"变成一次**看得见的声明**。)
|
||||
*/
|
||||
const REQUIRED_FORMS = ['function 声明', '箭头函数', 'async function', '名与括号间有空格', 'const = async (…'];
|
||||
const sampleNames = FORM_SAMPLES.map(([w]) => w);
|
||||
const noSample = REQUIRED_FORMS.filter(w => !sampleNames.includes(w));
|
||||
if (noSample.length) {
|
||||
console.log(`RED 这些写法**要求覆盖、却没有样本**:${noSample.join('、')}`
|
||||
+ ' ⇒ 覆盖静默缩水(发现规则对那种写法可能就是瞎的)');
|
||||
reds.push(`(自检)\`FORM_SAMPLES\` 缺了要求的样本:${noSample.join('、')}`
|
||||
+ ' —— 覆盖缩水必须看得见,不能只改一个数字');
|
||||
}
|
||||
const stray = sampleNames.filter(w => !REQUIRED_FORMS.includes(w));
|
||||
if (stray.length) {
|
||||
console.log(`RED 这些样本不在要求清单里(加了样本却没说是为了守哪种写法):${stray.join('、')}`);
|
||||
reds.push(`(自检)\`FORM_SAMPLES\` 有多余样本未登记进 \`REQUIRED_FORMS\`:${stray.join('、')}`);
|
||||
}
|
||||
const missed = FORM_SAMPLES.filter(([, src]) => !declaredSelfTests(src).includes('fooSelfTest'));
|
||||
if (missed.length) {
|
||||
console.log(`RED 发现规则认不出这些写法(⇒ 那种写法写了自检也不会被接线防线看见):`
|
||||
@ -2404,7 +2438,7 @@ let selfCheckRuns = 0;
|
||||
console.log(`自检段:${SELFTESTS.length} 个自检已在**默认路径**内跑过`
|
||||
+ `(${SELFTESTS.map(([n]) => `--${n}`).join('、')});`
|
||||
+ `源码里 ${declared.length} 个 \`*SelfTest\` 函数**全部**在册(无"写了没接线");`
|
||||
+ `发现规则在 ${FORM_SAMPLES.length} 种写法上都有对照`);
|
||||
+ `发现规则在 ${FORM_SAMPLES.length} 种写法上都有对照(要求 ${REQUIRED_FORMS.length} 种,缺一即红)`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user