From 297e75cdd577fd4c7cdef99ff4b2d48503a2dd1e Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 22 Jun 2026 16:24:55 +0000 Subject: [PATCH 1/2] =?UTF-8?q?fix(comments=20review):=20=E9=80=81?= =?UTF-8?q?=E5=87=BA=E5=89=8D=E6=8E=92=E5=BA=8F=20Review=20comments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/comments.js | 10 +++++++--- app/comments.test.js | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/app/comments.js b/app/comments.js index c597c6d..63a5d19 100644 --- a/app/comments.js +++ b/app/comments.js @@ -94,11 +94,15 @@ export async function postFindingsReview(findings, deps = {}) { summaryFindings = findings, commentFindings = findings, } = deps; - const sortedComments = [...commentFindings].sort(bySeverity); - const comments = sortedComments.map(toReviewComment).filter(Boolean); + const commentItems = commentFindings + .map(finding => ({ finding, comment: toReviewComment(finding) })) + .filter(item => item.comment); + const comments = commentItems + .sort((a, b) => bySeverity(a.finding, b.finding)) + .map(item => item.comment); const body = buildReviewSummary(summaryFindings); await postReview({ body, comments }); - ok(`review 發布: summary=${summaryFindings.length} total=${sortedComments.length} commentable=${comments.length}`); + ok(`review 發布: summary=${summaryFindings.length} total=${commentFindings.length} commentable=${comments.length}`); } /** diff --git a/app/comments.test.js b/app/comments.test.js index f413765..8dabaa3 100644 --- a/app/comments.test.js +++ b/app/comments.test.js @@ -238,6 +238,22 @@ describe('postFindingsReview', () => { assert.equal(reviewCalls[0].comments[0].path, 'app/b.js'); }); + it('sorts the final review comment payload after filtering non-commentable findings', async () => { + const reviewCalls = []; + await postFindingsReview([ + { level: 'info', role: 'Maya', location: 'app/c.js:30', suggestion: 'I' }, + { level: 'critical', role: 'Rex', location: 'app/a.js', suggestion: 'missing line' }, + { level: 'warning', role: 'Leo', location: 'app/b.js:20', suggestion: 'W' }, + ], { + postReview: async (args) => { reviewCalls.push(args); }, + }); + + assert.deepEqual( + reviewCalls[0].comments.map(c => c.body.match(/嚴重等級\*\*:(.+)/)?.[1]), + ['🟡 警告', '🔵 建議'], + ); + }); + it('uses an explicit problem field when present', async () => { const reviewCalls = []; await postFindingsReview([ -- 2.53.0 From 48aa8e00f3bb70e4c70b24bcd1fad6e447e11294 Mon Sep 17 00:00:00 2001 From: AI Review Bot Date: Mon, 22 Jun 2026 16:27:57 +0000 Subject: [PATCH 2/2] chore: update ai-review findings [ai-review-bot][failure] --- .gitea/ai-review/findings.json | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/.gitea/ai-review/findings.json b/.gitea/ai-review/findings.json index fe51488..9754b61 100644 --- a/.gitea/ai-review/findings.json +++ b/.gitea/ai-review/findings.json @@ -1 +1,18 @@ -[] +[ + { + "level": "critical", + "role": "Maya", + "location": "app/comments.test.js:240", + "problem": "新增的測試案例 `sorts the final review comment payload after filtering non-commentable findings`,其預期結果 `['🟡 警告', '🔵 建議']` 似乎有誤。輸入的 `critical` 等級的 finding 帶有 `suggestion` 欄位,照理來說應該會被轉換成評論,並依嚴重性排在最前面。目前測試結果卻將其排除,這可能代表 `toReviewComment` 函數有未預期的行為,或是測試的預期結果不正確,導致未能完整驗證排序邏輯。", + "suggestion": "請確認 `toReviewComment` 函數對於 `critical` 等級且帶有 `suggestion` 的 finding 是否會回傳 `null`。\n1. 如果不會,則測試的預期結果應修正為 `['🔴 嚴重', '🟡 警告', '🔵 建議']`,以確保所有應轉換的評論都被包含且排序正確。\n2. 如果 `toReviewComment` 確實會過濾掉某些 `critical` finding,則應新增一個獨立的測試案例,明確驗證 `critical` finding 在何種情況下會被過濾,並解釋其原因。\n3. 同時,這個測試案例也應該明確斷言最終評論的數量,以確保過濾行為符合預期。", + "is_new": true + }, + { + "level": "info", + "role": "Bard", + "location": "app/comments.test.js:252", + "problem": "測試中用於提取評論嚴重等級的正規表達式 `c.body.match(/嚴重等級\\*\\*:(.+)/)?.[1]` 雖然有效,但其寫法較為冗長且直接依賴於評論內文的特定格式。這使得測試在評論格式微調時可能變得脆弱,且降低了可讀性,如同樂章中突兀的音符。", + "suggestion": "若評論內文的格式是固定的,可考慮將此正規表達式提取為一個具名常數或輔助函式,以提升可讀性與維護性。若 `toReviewComment` 函式能回傳一個包含結構化資訊(如 `level`)的物件,則測試可直接斷言該物件屬性,避免解析字串,讓測試更為優雅。", + "is_new": true + } +] -- 2.53.0