From e3890787ff1914216469fec2a7c98bc2eb6feb06 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 22 Jun 2026 16:32:23 +0000 Subject: [PATCH 1/6] =?UTF-8?q?test(comments=20review):=20=E6=8A=BD?= =?UTF-8?q?=E5=87=BA=E5=9A=B4=E9=87=8D=E7=AD=89=E7=B4=9A=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E6=96=B7=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/comments.test.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/app/comments.test.js b/app/comments.test.js index f413765..ddcc817 100644 --- a/app/comments.test.js +++ b/app/comments.test.js @@ -6,6 +6,13 @@ import path from 'node:path'; import { saveFindings, parseLocation, postNewCriticalComments, postFindingsReview } from './comments.js'; import { FINDINGS_PATH } from './config.js'; +const REVIEW_SEVERITY_PATTERN = /\*\*嚴重等級\*\*:(🔴 嚴重|🟡 警告|🔵 建議)(?:\n|$)/; +const REVIEW_SEVERITY_LABELS = ['🔴 嚴重', '🟡 警告', '🔵 建議']; + +function reviewSeverityLabel(comment) { + return comment.body.match(REVIEW_SEVERITY_PATTERN)?.[1]; +} + describe('saveFindings', () => { const tempDirs = []; const makeTempDir = prefix => { @@ -187,6 +194,16 @@ describe('postNewCriticalComments', () => { }); describe('postFindingsReview', () => { + it('extracts review severity labels only when the format is valid', () => { + assert.equal( + reviewSeverityLabel({ body: '**嚴重等級**:🔴 嚴重\n**審查員**:Rex' }), + '🔴 嚴重', + ); + assert.equal(reviewSeverityLabel({ body: '**審查員**:Rex' }), undefined); + assert.equal(reviewSeverityLabel({ body: '**嚴重等級**:' }), undefined); + assert.equal(reviewSeverityLabel({ body: '**嚴重等級**:高風險' }), undefined); + }); + it('posts one review with statistics and sorted line comments', async () => { const reviewCalls = []; const findings = [ @@ -209,8 +226,8 @@ describe('postFindingsReview', () => { ['app/a.js', 'app/b.js', 'app/c.js'], ); assert.deepEqual( - reviewCalls[0].comments.map(c => c.body.match(/嚴重等級\*\*:(.+)/)?.[1]), - ['🔴 嚴重', '🟡 警告', '🔵 建議'], + reviewCalls[0].comments.map(reviewSeverityLabel), + REVIEW_SEVERITY_LABELS, ); assert.deepEqual( reviewCalls[0].comments.map(c => c.new_position), From 1ba322e7a6b92af5cfb1c8eb78a03bd907b7c6d9 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 22 Jun 2026 16:32:23 +0000 Subject: [PATCH 2/6] =?UTF-8?q?chore(ai-review=20=E7=8B=80=E6=85=8B):=20?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=B7=B2=E8=A7=A3=E6=B1=BA=20findings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/ai-review/findings.json | 43 +--------------------------------- 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/.gitea/ai-review/findings.json b/.gitea/ai-review/findings.json index 86036ff..fe51488 100644 --- a/.gitea/ai-review/findings.json +++ b/.gitea/ai-review/findings.json @@ -1,42 +1 @@ -[ - { - "level": "warning", - "role": "Bard", - "location": "app/comments.test.js:211", - "problem": "程式碼中直接嵌入了正規表達式 `/嚴重等級\\*\\*:(.+)/`,這是一個「魔術值」。它讓程式碼的意圖不夠清晰,且若未來需要修改此模式,會增加維護的困難度,也使得該行程式碼過於冗長,影響閱讀流暢性。", - "suggestion": "建議將此正規表達式提取為一個具名常數,以提升可讀性與可維護性。例如:\n```javascript\nconst SEVERITY_PATTERN = /嚴重等級\\*\\*:(.+)/;\n// ...\nreviewCalls[0].comments.map(c => c.body.match(SEVERITY_PATTERN)?.[1]),\n```", - "is_new": true - }, - { - "level": "warning", - "role": "Leo", - "location": "app/comments.test.js:212", - "problem": "測試中直接硬編碼了嚴重等級的顯示文字 `['🔴 嚴重', '🟡 警告', '🔵 建議']`。這些字串很可能是應用程式中定義的常數,直接複製貼上會導致未來當這些等級的顯示文字需要調整時,必須同時修改應用程式程式碼和測試程式碼,增加維護負擔,也容易造成不一致。", - "suggestion": "如果這些嚴重等級的顯示文字在應用程式中已有定義(例如:`SEVERITY_LEVELS.CRITICAL.DISPLAY_TEXT`),建議在測試中引入並使用這些常數,確保測試與實際邏輯保持同步,避免重複定義的技術債。", - "is_new": true - }, - { - "level": "warning", - "role": "Leo", - "location": "app/comments.test.js:211", - "problem": "測試中用來解析 `c.body` 的正規表達式 `(/嚴重等級\\*\\*:(.+)/)` 過於依賴特定的字串格式「嚴重等級**:」。如果未來這個前綴文字有任何微小的變動(例如:多一個空格、換個標點符號、或改用其他詞彙),即使語義不變,測試也會立刻失效,導致不必要的維護工作,增加了測試的脆弱性。", - "suggestion": "考慮讓正規表達式更具彈性,例如使用 `\\s*` 匹配空白,或將這個字串格式的解析邏輯封裝成一個輔助函式,並在該函式中處理可能存在的格式變動彈性。如果 `c.body` 的內容是從結構化資料組裝而來,更理想的做法是測試該結構化資料本身,而非其最終的字串呈現。", - "is_new": true - }, - { - "level": "warning", - "role": "Mage", - "location": "app/comments.test.js:211", - "problem": "此處的正規表達式 `嚴重等級\\*\\*:(.+)` 使用了貪婪匹配 `.+`。這可能導致它捕獲到「嚴重等級**:」後方,直到字串結尾的所有內容,而非僅僅是預期的嚴重等級文字。若 `c.body` 中在嚴重等級後方還有其他文字(例如:「嚴重等級**:🔴 嚴重。請注意此問題。」),此測試將會因為提取到錯誤的內容而失敗,或在實際情況與預期不符時,無法正確驗證。", - "suggestion": "為了確保只捕獲到預期的嚴重等級文字,應使用更精確的正規表達式。考量到測試的預期值是固定的 `['🔴 嚴重', '🟡 警告', '🔵 建議']`,最穩健的作法是直接匹配這些值,例如:\n`c.body.match(/嚴重等級\\*\\*:(🔴 嚴重|🟡 警告|🔵 建議)/)?.[1]`\n或者,如果嚴重等級後方可能跟隨其他文字但有明確分隔符(如句點、換行符或字串結尾),可以使用非貪婪匹配並指定邊界,例如:\n`c.body.match(/嚴重等級\\*\\*:(.+?)(?:\\s|$|\\.|\\n)/)?.[1]`", - "is_new": true - }, - { - "level": "warning", - "role": "Maya", - "location": "app/comments.test.js:211", - "problem": "這個新增的斷言只驗證了評論內文(`c.body`)中存在且格式正確的嚴重等級資訊。然而,它沒有涵蓋到評論內文可能沒有嚴重等級資訊,或是嚴重等級格式不符預期的情境,這讓程式碼的行為在這些邊界條件下缺乏驗證。", - "suggestion": "建議新增測試案例,或擴充現有案例的測試資料,以涵蓋以下情境:\n1. 評論內文完全沒有「嚴重等級**:」這個模式時,應驗證程式碼的行為(例如,是否正確提取到 `undefined` 或預設值)。\n2. 評論內文有「嚴重等級**:」但後面沒有內容,或內容格式不符預期時,應驗證程式碼的行為(例如,是否正確處理為 `undefined` 或拋出錯誤)。", - "is_new": true - } -] +[] From 185655f9ae8918c02cb9643ec0c5e8b99fe10988 Mon Sep 17 00:00:00 2001 From: AI Review Bot Date: Mon, 22 Jun 2026 16:33:31 +0000 Subject: [PATCH 3/6] chore: update ai-review findings [ai-review-bot][failure] --- .gitea/ai-review/findings.json | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/.gitea/ai-review/findings.json b/.gitea/ai-review/findings.json index fe51488..93b5698 100644 --- a/.gitea/ai-review/findings.json +++ b/.gitea/ai-review/findings.json @@ -1 +1,26 @@ -[] +[ + { + "level": "critical", + "role": "Maya", + "location": "app/comments.test.js:6", + "problem": "新增的 `reviewSeverityLabel` 函式,在處理輸入的 `comment` 物件本身為 `null` 或 `undefined`,或是 `comment.body` 屬性為 `null` 或 `undefined` 的邊界情況時,可能會拋出執行時期錯誤(TypeError),目前沒有對應的測試案例來驗證此失敗路徑。", + "suggestion": "建議為 `reviewSeverityLabel` 函式新增測試案例,驗證當 `comment` 為 `null` 或 `undefined`,以及 `comment.body` 為 `null` 或 `undefined` 時,函式能正確地回傳 `undefined` 而不拋出錯誤。同時,也請確保函式實作能妥善處理這些邊界輸入。\n\n例如,可以在 `app/comments.test.js` 的 `describe('postFindingsReview', ...)` 區塊中,為 `reviewSeverityLabel` 函式新增以下測試案例:\n```javascript\nit('handles null or undefined comment/body gracefully', () => {\n assert.equal(reviewSeverityLabel(null), undefined);\n assert.equal(reviewSeverityLabel(undefined), undefined);\n assert.equal(reviewSeverityLabel({}), undefined); // comment.body is undefined\n assert.equal(reviewSeverityLabel({ body: null }), undefined);\n assert.equal(reviewSeverityLabel({ body: undefined }), undefined);\n});\n```\n並調整 `reviewSeverityLabel` 函式實作,例如:\n```javascript\nfunction reviewSeverityLabel(comment) {\n if (!comment || !comment.body) {\n return undefined;\n }\n return comment.body.match(REVIEW_SEVERITY_PATTERN)?.[1];\n}\n```", + "is_new": true + }, + { + "level": "warning", + "role": "Leo", + "location": "app/comments.test.js:6", + "problem": "在 `REVIEW_SEVERITY_PATTERN` 和 `REVIEW_SEVERITY_LABELS` 這兩個常數中,嚴重等級的標籤(例如 '🔴 嚴重')被重複定義了。這會導致未來若要修改或新增標籤時,需要同時更新兩處,容易造成維護上的疏漏與不一致。", + "suggestion": "建議將嚴重等級標籤定義為單一來源,例如只維護 `REVIEW_SEVERITY_LABELS` 陣列,然後動態地從這個陣列產生 `REVIEW_SEVERITY_PATTERN` 的正規表達式字串。這樣可以確保兩者永遠同步,降低未來的維護成本。\n\n例如:\n```javascript\nconst REVIEW_SEVERITY_LABELS = ['🔴 嚴重', '🟡 警告', '🔵 建議'];\nconst REVIEW_SEVERITY_PATTERN = new RegExp(`\\\\*\\\\*嚴重等級\\\\*\\\\*:(${REVIEW_SEVERITY_LABELS.join('|')})(?:\\\\n|$)`);\n```", + "is_new": true + }, + { + "level": "info", + "role": "Bard", + "location": "app/comments.test.js:13", + "problem": "reviewSeverityLabel 函式是專為 `postFindingsReview` 測試區塊服務的輔助函式。將其定義在檔案頂層,而非其所屬的 `describe` 區塊內,可能讓程式碼的組織結構顯得不夠緊密,降低了相關程式碼的局部性。", + "suggestion": "建議將 reviewSeverityLabel 函式及其相關的 REVIEW_SEVERITY_PATTERN 與 REVIEW_SEVERITY_LABELS 常數,一併移至 `describe('postFindingsReview', ...)` 區塊內部,以提升程式碼的內聚性與可讀性,讓相關的旋律能集中演奏。", + "is_new": true + } +] From 3527a06244db695a151d9551a7e7712908338cf5 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 22 Jun 2026 16:35:37 +0000 Subject: [PATCH 4/6] =?UTF-8?q?test(comments=20review):=20=E5=BC=B7?= =?UTF-8?q?=E5=8C=96=E5=9A=B4=E9=87=8D=E7=AD=89=E7=B4=9A=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=20helper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/comments.test.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/app/comments.test.js b/app/comments.test.js index ddcc817..319c55e 100644 --- a/app/comments.test.js +++ b/app/comments.test.js @@ -6,13 +6,6 @@ import path from 'node:path'; import { saveFindings, parseLocation, postNewCriticalComments, postFindingsReview } from './comments.js'; import { FINDINGS_PATH } from './config.js'; -const REVIEW_SEVERITY_PATTERN = /\*\*嚴重等級\*\*:(🔴 嚴重|🟡 警告|🔵 建議)(?:\n|$)/; -const REVIEW_SEVERITY_LABELS = ['🔴 嚴重', '🟡 警告', '🔵 建議']; - -function reviewSeverityLabel(comment) { - return comment.body.match(REVIEW_SEVERITY_PATTERN)?.[1]; -} - describe('saveFindings', () => { const tempDirs = []; const makeTempDir = prefix => { @@ -194,6 +187,21 @@ describe('postNewCriticalComments', () => { }); describe('postFindingsReview', () => { + const REVIEW_SEVERITY_LABELS = ['🔴 嚴重', '🟡 警告', '🔵 建議']; + const REVIEW_SEVERITY_PATTERN = new RegExp(`\\*\\*嚴重等級\\*\\*:(${REVIEW_SEVERITY_LABELS.join('|')})(?:\\n|$)`); + + function reviewSeverityLabel(comment) { + return comment?.body?.match(REVIEW_SEVERITY_PATTERN)?.[1]; + } + + it('handles missing review severity bodies gracefully', () => { + assert.equal(reviewSeverityLabel(null), undefined); + assert.equal(reviewSeverityLabel(undefined), undefined); + assert.equal(reviewSeverityLabel({}), undefined); + assert.equal(reviewSeverityLabel({ body: null }), undefined); + assert.equal(reviewSeverityLabel({ body: undefined }), undefined); + }); + it('extracts review severity labels only when the format is valid', () => { assert.equal( reviewSeverityLabel({ body: '**嚴重等級**:🔴 嚴重\n**審查員**:Rex' }), From f8e1b61fc470caefea20522e68ec5f0afe9cc992 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 22 Jun 2026 16:35:37 +0000 Subject: [PATCH 5/6] =?UTF-8?q?chore(ai-review=20=E7=8B=80=E6=85=8B):=20?= =?UTF-8?q?=E6=B8=85=E9=99=A4=E5=B7=B2=E8=A7=A3=E6=B1=BA=20helper=20findin?= =?UTF-8?q?gs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/ai-review/findings.json | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/.gitea/ai-review/findings.json b/.gitea/ai-review/findings.json index 93b5698..fe51488 100644 --- a/.gitea/ai-review/findings.json +++ b/.gitea/ai-review/findings.json @@ -1,26 +1 @@ -[ - { - "level": "critical", - "role": "Maya", - "location": "app/comments.test.js:6", - "problem": "新增的 `reviewSeverityLabel` 函式,在處理輸入的 `comment` 物件本身為 `null` 或 `undefined`,或是 `comment.body` 屬性為 `null` 或 `undefined` 的邊界情況時,可能會拋出執行時期錯誤(TypeError),目前沒有對應的測試案例來驗證此失敗路徑。", - "suggestion": "建議為 `reviewSeverityLabel` 函式新增測試案例,驗證當 `comment` 為 `null` 或 `undefined`,以及 `comment.body` 為 `null` 或 `undefined` 時,函式能正確地回傳 `undefined` 而不拋出錯誤。同時,也請確保函式實作能妥善處理這些邊界輸入。\n\n例如,可以在 `app/comments.test.js` 的 `describe('postFindingsReview', ...)` 區塊中,為 `reviewSeverityLabel` 函式新增以下測試案例:\n```javascript\nit('handles null or undefined comment/body gracefully', () => {\n assert.equal(reviewSeverityLabel(null), undefined);\n assert.equal(reviewSeverityLabel(undefined), undefined);\n assert.equal(reviewSeverityLabel({}), undefined); // comment.body is undefined\n assert.equal(reviewSeverityLabel({ body: null }), undefined);\n assert.equal(reviewSeverityLabel({ body: undefined }), undefined);\n});\n```\n並調整 `reviewSeverityLabel` 函式實作,例如:\n```javascript\nfunction reviewSeverityLabel(comment) {\n if (!comment || !comment.body) {\n return undefined;\n }\n return comment.body.match(REVIEW_SEVERITY_PATTERN)?.[1];\n}\n```", - "is_new": true - }, - { - "level": "warning", - "role": "Leo", - "location": "app/comments.test.js:6", - "problem": "在 `REVIEW_SEVERITY_PATTERN` 和 `REVIEW_SEVERITY_LABELS` 這兩個常數中,嚴重等級的標籤(例如 '🔴 嚴重')被重複定義了。這會導致未來若要修改或新增標籤時,需要同時更新兩處,容易造成維護上的疏漏與不一致。", - "suggestion": "建議將嚴重等級標籤定義為單一來源,例如只維護 `REVIEW_SEVERITY_LABELS` 陣列,然後動態地從這個陣列產生 `REVIEW_SEVERITY_PATTERN` 的正規表達式字串。這樣可以確保兩者永遠同步,降低未來的維護成本。\n\n例如:\n```javascript\nconst REVIEW_SEVERITY_LABELS = ['🔴 嚴重', '🟡 警告', '🔵 建議'];\nconst REVIEW_SEVERITY_PATTERN = new RegExp(`\\\\*\\\\*嚴重等級\\\\*\\\\*:(${REVIEW_SEVERITY_LABELS.join('|')})(?:\\\\n|$)`);\n```", - "is_new": true - }, - { - "level": "info", - "role": "Bard", - "location": "app/comments.test.js:13", - "problem": "reviewSeverityLabel 函式是專為 `postFindingsReview` 測試區塊服務的輔助函式。將其定義在檔案頂層,而非其所屬的 `describe` 區塊內,可能讓程式碼的組織結構顯得不夠緊密,降低了相關程式碼的局部性。", - "suggestion": "建議將 reviewSeverityLabel 函式及其相關的 REVIEW_SEVERITY_PATTERN 與 REVIEW_SEVERITY_LABELS 常數,一併移至 `describe('postFindingsReview', ...)` 區塊內部,以提升程式碼的內聚性與可讀性,讓相關的旋律能集中演奏。", - "is_new": true - } -] +[] From fe865823f1d5d53e5a355a470b37536fbf1ec3db Mon Sep 17 00:00:00 2001 From: AI Review Bot Date: Mon, 22 Jun 2026 16:36:22 +0000 Subject: [PATCH 6/6] chore: update ai-review findings [ai-review-bot][success] --- .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..ef85255 100644 --- a/.gitea/ai-review/findings.json +++ b/.gitea/ai-review/findings.json @@ -1 +1,18 @@ -[] +[ + { + "level": "warning", + "role": "Leo", + "location": "app/comments.test.js:30", + "problem": "常數 `REVIEW_SEVERITY_LABELS`、`REVIEW_SEVERITY_PATTERN` 以及輔助函式 `reviewSeverityLabel` 被定義在測試檔案的 `describe` 區塊內。如果實際的應用程式邏輯(例如產生或處理這些評論的程式碼)也需要用到這些資訊,那麼這會造成邏輯重複或知識分散。未來若評論格式或嚴重等級標籤有變動,將需要同時修改多處,增加維護成本與出錯風險。", + "suggestion": "將 `REVIEW_SEVERITY_LABELS`、`REVIEW_SEVERITY_PATTERN` 和 `reviewSeverityLabel` 這些與評論格式相關的常數與函式,提取到一個獨立的共用模組中(例如 `app/utils/reviewComments.js`),並讓測試檔案和任何需要用到它們的應用程式邏輯都從該模組匯入。這樣能確保「評論格式」的定義只有一個來源,提升可維護性。", + "is_new": true + }, + { + "level": "info", + "role": "Bard", + "location": "app/comments.test.js:192", + "problem": "此處新增的 `reviewSeverityLabel` 函式,雖其意圖在上下文脈絡中尚稱清晰,但若能為其添上一筆簡潔的 JSDoc 註解,闡明其參數與回傳值的語義,將使這段樂章更臻完善,即便在測試檔案中,亦能提升未來維護者的閱讀體驗,使程式碼的旋律更加和諧。", + "suggestion": "建議為 `reviewSeverityLabel` 函式加上 JSDoc 註解,例如:\n```javascript\n /**\n * 從評論物件中提取嚴重等級標籤。\n * @param {object | null | undefined} comment - 評論物件,預期包含 `body` 屬性。\n * @returns {string | undefined} 嚴重等級標籤字串(如 '🔴 嚴重'),若無匹配或輸入無效則回傳 undefined。\n */\n function reviewSeverityLabel(comment) {\n return comment?.body?.match(REVIEW_SEVERITY_PATTERN)?.[1];\n }\n```", + "is_new": true + } +]