feat/commit-split-and-pr/main #45
@@ -11,7 +11,8 @@ import { assertNeutralPrompt, readPrompt } from './helpers/prompt-doc.js';
|
||||
const prompt = readPrompt('sdlc-feat');
|
||||
/** 各段的內容分開切,避免把別段的字樣誤認成這一段的規則 */
|
||||
const phase1 = prompt.slice(prompt.indexOf('## 第一段'), prompt.indexOf('## 第二段'));
|
||||
const phase2 = prompt.slice(prompt.indexOf('## 第二段'), prompt.indexOf('## 邊界'));
|
||||
const phase2 = prompt.slice(prompt.indexOf('## 第二段'), prompt.indexOf('## 第三段'));
|
||||
const phase3 = prompt.slice(prompt.indexOf('## 第三段'), prompt.indexOf('## 邊界'));
|
||||
|
||||
test('正本平台中立,description 前綴正確', () => {
|
||||
assertNeutralPrompt(prompt, 'sdlc-feat');
|
||||
@@ -180,3 +181,77 @@ test('邊界把第二段不做的事也列出來', () => {
|
||||
assert.match(boundary, /不提交、不開 PR、不停錶/);
|
||||
assert.match(boundary, /不改與待辦無關的程式碼/);
|
||||
});
|
||||
|
||||
// ── 第三段:提交與開立 PR ─────────────────────────────────────────
|
||||
|
||||
test('第三段指名兩支腳本,順序為先提交再開 PR', () => {
|
||||
const order = ['commit-split.js', 'pr-create.js'];
|
||||
const positions = order.map((name) => phase3.indexOf(name));
|
||||
assert.equal(positions.every((p) => p >= 0), true, '兩支腳本都要被指名');
|
||||
assert.deepEqual([...positions].sort((a, b) => a - b), positions);
|
||||
});
|
||||
|
||||
test('要等待辦全部勾完才進第三段', () => {
|
||||
assert.match(phase3, /全部待辦都勾完之後才進這一段/);
|
||||
});
|
||||
|
||||
test('--type 是程式碼那一批的類型,其餘由腳本自己認', () => {
|
||||
assert.match(phase3, /測試、文件與設定檔\s*\n?由腳本自己認出來|由腳本自己認出來/);
|
||||
assert.match(phase3, /不必也不能指定/);
|
||||
});
|
||||
|
||||
test('--scope 什麼時候要給寫清楚了', () => {
|
||||
assert.match(phase3, /只在某一批有多個檔案時才需要/);
|
||||
assert.match(phase3, /單檔那批的 scope 就是檔名/);
|
||||
});
|
||||
|
||||
test('commit 描述要用繁體中文,並交代夾雜英文的處理', () => {
|
||||
assert.match(phase3, /描述用繁體中文/);
|
||||
assert.match(phase3, /保留原文/);
|
||||
});
|
||||
|
||||
test('跨兩個功能時要分兩次跑,且指名用哪個旗標做得到', () => {
|
||||
assert.match(phase3, /分兩次跑/);
|
||||
assert.match(phase3, /--files/, '光說「分兩次跑」而不說怎麼分,等於沒說');
|
||||
assert.match(phase3, /失去了分批的意義/);
|
||||
});
|
||||
|
||||
test('PR 描述的八個段落都列出來,且標明順序不能換', () => {
|
||||
for (const section of [
|
||||
'摘要', '需求議題', '工作包議題', '變更內容',
|
||||
'設計重點', '解決的問題', '影響的功能', '測試結果',
|
||||
]) {
|
||||
assert.match(phase3, new RegExp(`\\*\\*${section}\\*\\*`), `缺少段落說明:${section}`);
|
||||
}
|
||||
assert.match(phase3, /順序不能換/);
|
||||
});
|
||||
|
||||
test('測試結果要放實際輸出,並交代沒有自動化測試時怎麼辦', () => {
|
||||
assert.match(phase3, /放實際跑過的輸出/);
|
||||
assert.match(phase3, /已測試通過/, '要指名這句被禁止的寫法');
|
||||
assert.match(phase3, /手動\s*\n?驗證步驟|手動驗證步驟/);
|
||||
assert.match(phase3, /補真的內容/);
|
||||
});
|
||||
|
||||
test('標題由腳本設為分支名,不另外指定', () => {
|
||||
assert.match(phase3, /標題由腳本設為分支名/);
|
||||
assert.match(phase3, /不必也不能另外指定/);
|
||||
});
|
||||
|
||||
test('先開 PR 再停錶,且 PR 沒開成就不停錶', () => {
|
||||
assert.match(phase3, /先開 PR 再停錶/);
|
||||
assert.match(phase3, /沒開成就不停錶/);
|
||||
assert.match(phase3, /工時要記在真的有做事的那段時間上/);
|
||||
});
|
||||
|
||||
test('兩支腳本都要求先試跑', () => {
|
||||
const dryRuns = phase3.match(/--dry-run/g) ?? [];
|
||||
assert.ok(dryRuns.length >= 2, `兩支寫入型腳本各要先試跑,只找到 ${dryRuns.length} 處`);
|
||||
});
|
||||
|
||||
test('邊界把第三段不做的事也列出來', () => {
|
||||
const boundary = prompt.slice(prompt.indexOf('## 邊界'));
|
||||
assert.match(boundary, /第三段不改任何一行程式碼/);
|
||||
assert.match(boundary, /不把「已測試通過」這種空話/);
|
||||
assert.match(boundary, /不代替使用者決定 commit 的類型與描述/);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user