From 15da38a4601c61fc2e0412a2a81e7d62a1616853 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Thu, 17 Sep 2026 06:06:11 +0000 Subject: [PATCH] =?UTF-8?q?test(issue-update):=20=E5=B0=81=E4=BD=8F?= =?UTF-8?q?=E4=BC=B0=E7=AE=97=E9=82=A3=E4=B8=80=E8=A1=8C=E7=9A=84=E4=B8=89?= =?UTF-8?q?=E7=A8=AE=E6=B1=A1=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 三條測試都先確認過會在舊版實作上失敗。第一版寫出來時有兩條其實是陪跑的—— 情境裡沒有後續段落,正確與錯誤的結果剛好都落在 body 結尾,分不出來。加上一個 真正的後續段落之後才有鑑別力。 Co-Authored-By: Claude Opus 5 (1M context) --- test/issue-update.test.js | 60 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/test/issue-update.test.js b/test/issue-update.test.js index ddc6021..bd4819d 100644 --- a/test/issue-update.test.js +++ b/test/issue-update.test.js @@ -189,3 +189,63 @@ test('--dry-run 列出將送出的 PATCH,且不寫入', async (t) => { assert.equal(json.data.requests[0].body.milestone, 3, '預覽要看得出 Milestone 已解析成 id'); assert.equal(stub.requests.some((r) => r.method !== 'GET'), false); }); + +// ── 估算那一行只能動目標段落(以下三條皆為實際重現過的污染情境)────── + +test('圍欄裡的假標題不算段落,估算不會被塞進圍欄之後的位置', async (t) => { + // 後面放一個真的段落,才分得出「當成段落處理」與「找不到段落」兩種結果 + const stub = await withStub(t, {}, { + body: '## 描述\n\n說明\n\n```\n## 關聯\n```\n\n## 整體驗收\n\n- 一條\n', + }); + + await run(['--estimate-days', '3'], stub); + + const updated = patchOf(stub).body.body; + assert.match(updated, /```\n## 關聯\n```/, '圍欄內容一字不動'); + assert.ok( + updated.indexOf('估算人天:3') > updated.indexOf('## 整體驗收'), + '沒有真正的關聯段落,估算該補在 body 結尾,而不是插在假標題那一段裡', + ); +}); + +test('段落名稱是子字串時不誤認:## 關聯度說明 不是 ## 關聯', async (t) => { + const stub = await withStub(t, {}, { + body: '## 關聯度說明\n\n這不是關聯段落\n\n## 整體驗收\n\n- 一條\n', + }); + + await run(['--estimate-days', '3'], stub); + + const updated = patchOf(stub).body.body; + assert.match(updated, /## 關聯度說明\n\n這不是關聯段落/, '別人的段落不得被動到'); + assert.ok( + updated.indexOf('估算人天:3') > updated.indexOf('## 整體驗收'), + '名稱只是相像不算命中,該落到 body 結尾', + ); +}); + +test('別的段落剛好有同前綴的一行時,改的仍是關聯段落那一行', async (t) => { + const stub = await withStub(t, {}, { + body: '## 總覽\n\n估算人天:99\n\n## 關聯\n\n需求議題:#1\n', + }); + + await run(['--estimate-days', '3'], stub); + + const updated = patchOf(stub).body.body; + assert.match(updated, /## 總覽\n\n估算人天:99/, '總覽那一行不得被改掉'); + const relation = updated.slice(updated.indexOf('## 關聯')); + assert.match(relation, /估算人天:3/); +}); + +test('估算插在段落內容結尾,不會掉到下一個段落裡', async (t) => { + const stub = await withStub(t, {}, { + body: '## 關聯\n\n需求議題:#1\n\n## 整體驗收\n\n- 一條\n', + }); + + await run(['--estimate-days', '2'], stub); + + const updated = patchOf(stub).body.body; + assert.ok( + updated.indexOf('估算人天:2') < updated.indexOf('## 整體驗收'), + '估算要留在關聯段落內', + ); +});