test(逐項實作): 覆蓋勾選的五種危險、兩份規則正本與正本第二段
勾選的測試全部繞著「會不會改錯行」打轉,五種都是 code review 抓出來的實際缺陷: 圍欄裡長得像 checkbox 的那一行不會被改到、不同段落的同一句話靠 --section 分得開、 大寫 [X] 重跑是 no-op、方框後沒有空白照樣勾得到、沒有方框的項目給的是指路的錯誤 而不是謊報已勾過。 另外釘住抽取端與勾選端的一致性:wp-extract 交得出來的每一種 raw,--tick 都要收得下。 patchOf 收進 helpers——它先前在三個測試檔裡各有一份一模一樣的定義。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,8 +9,9 @@ import assert from 'node:assert/strict';
|
||||
import { assertNeutralPrompt, readPrompt } from './helpers/prompt-doc.js';
|
||||
|
||||
const prompt = readPrompt('sdlc-feat');
|
||||
/** 第一段的內容,避免把邊界段的字樣誤認成這一段的規則 */
|
||||
const phase1 = prompt.slice(prompt.indexOf('## 第一段'), prompt.indexOf('## 邊界'));
|
||||
/** 各段的內容分開切,避免把別段的字樣誤認成這一段的規則 */
|
||||
const phase1 = prompt.slice(prompt.indexOf('## 第一段'), prompt.indexOf('## 第二段'));
|
||||
const phase2 = prompt.slice(prompt.indexOf('## 第二段'), prompt.indexOf('## 邊界'));
|
||||
|
||||
test('正本平台中立,description 前綴正確', () => {
|
||||
assertNeutralPrompt(prompt, 'sdlc-feat');
|
||||
@@ -95,3 +96,87 @@ test('邊界把第一段不做的事分開列,且明講不寫本機狀態檔',
|
||||
assert.match(boundary, /不寫任何本機狀態檔/);
|
||||
assert.match(boundary, /換一台機器或換一個 agent/, '要說明為什麼不留狀態檔');
|
||||
});
|
||||
|
||||
// ── 第二段:逐項實作 ───────────────────────────────────────────────
|
||||
|
||||
test('第二段指名兩份規則正本,且在改檔之前就要讀', () => {
|
||||
assert.match(phase2, /references\/coding-standards\.md/);
|
||||
assert.match(phase2, /references\/comment-styles\.md/);
|
||||
const readAt = phase2.indexOf('coding-standards.md');
|
||||
const implementAt = phase2.indexOf('### 8.');
|
||||
assert.ok(readAt < implementAt, '讀規則要排在動手實作之前');
|
||||
});
|
||||
|
||||
test('認不出語言就停下來問,不自行假設', () => {
|
||||
assert.match(phase2, /認不出語言就停下來問/);
|
||||
assert.match(phase2, /不要猜/);
|
||||
});
|
||||
|
||||
test('不把規範寫進目標專案的檔案', () => {
|
||||
assert.match(phase2, /不寫進目標專案的任何檔案/);
|
||||
});
|
||||
|
||||
test('規則不在正本裡複述,只指名去哪裡讀', () => {
|
||||
assert.match(phase2, /這裡不複述/);
|
||||
assert.match(phase2, /兩份各自演化/, '要說出複述的代價,否則下一個人還是會抄過來');
|
||||
});
|
||||
|
||||
test('資料範例優先取自 MCP,取不到要註明未經驗證', () => {
|
||||
assert.match(phase2, /優先從 MCP 取得/);
|
||||
assert.match(phase2, /由邏輯推理、未經驗證/);
|
||||
});
|
||||
|
||||
test('回報要點出哪些範例是推理來的', () => {
|
||||
const report = phase2.slice(phase2.indexOf('### 11.'));
|
||||
assert.match(report, /哪些資料範例是推理來的/);
|
||||
});
|
||||
|
||||
test('--section 一定要給,並說明不給會怎樣', () => {
|
||||
assert.match(phase2, /--section/);
|
||||
assert.match(phase2, /一定要給/);
|
||||
assert.match(phase2, /分不出要勾哪一個/);
|
||||
});
|
||||
|
||||
test('過程不打斷:不逐項徵求同意,只印進度', () => {
|
||||
assert.match(phase2, /過程不打斷/);
|
||||
assert.match(phase2, /不該按二十次同意/);
|
||||
assert.match(phase2, /只印進度/);
|
||||
assert.match(phase2, /\[3\/12\]/, '要給一個看得出長相的進度格式,不要只說「印進度」');
|
||||
});
|
||||
|
||||
test('真正該停下來問的情況有列舉,不是一律不問', () => {
|
||||
assert.match(phase2, /真正需要停下來問的只有三種/);
|
||||
assert.match(phase2, /範圍邊界/);
|
||||
});
|
||||
|
||||
test('勾選用 issue-update --tick,且明講要用抽取契約給的 raw', () => {
|
||||
assert.match(phase2, /--tick/);
|
||||
assert.match(phase2, /不要自己拼那一行/);
|
||||
assert.match(phase2, /raw/);
|
||||
});
|
||||
|
||||
test('四種勾不動的錯誤各自交代了下一步', () => {
|
||||
for (const code of ['RAW_NOT_FOUND', 'RAW_AMBIGUOUS', 'NOT_A_CHECKBOX', 'SECTION_NOT_FOUND']) {
|
||||
assert.match(phase2, new RegExp(code), `${code} 要出現在錯誤表裡`);
|
||||
}
|
||||
assert.match(phase2, /重跑 `wp-extract`/);
|
||||
assert.match(phase2, /不要自己改寫議題/, '議題內容是使用者的,agent 不該代為修改');
|
||||
});
|
||||
|
||||
test('不為了勾選留留言,並說明為什麼', () => {
|
||||
assert.match(phase2, /不要為了勾選在議題上留留言/);
|
||||
assert.match(phase2, /洗版/);
|
||||
});
|
||||
|
||||
test('中斷後重跑從 Gitea 的勾選狀態接續,且不看本機檔案', () => {
|
||||
assert.match(phase2, /不看任何本機檔案/);
|
||||
assert.match(phase2, /done` 已經是 `true`|done.*true/);
|
||||
assert.match(phase2, /no-op/, '要說明重複勾選是安全的,否則會有人先查再勾');
|
||||
});
|
||||
|
||||
test('邊界把第二段不做的事也列出來', () => {
|
||||
const boundary = prompt.slice(prompt.indexOf('## 邊界'));
|
||||
assert.match(boundary, /第二段只實作與勾選/);
|
||||
assert.match(boundary, /不提交、不開 PR、不停錶/);
|
||||
assert.match(boundary, /不改與待辦無關的程式碼/);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user