test(comments review): 抽出嚴重等級解析斷言 #38

Merged
jiantw83 merged 6 commits from ai-review-resolve/20260622-163133 into develop 2026-06-22 16:36:36 +00:00
Showing only changes of commit e3890787ff - Show all commits
+19 -2
View File
@@ -6,6 +6,13 @@ import path from 'node:path';
import { saveFindings, parseLocation, postNewCriticalComments, postFindingsReview } from './comments.js'; import { saveFindings, parseLocation, postNewCriticalComments, postFindingsReview } from './comments.js';
Review

嚴重等級🔴 嚴重
審查員:Maya
問題:新增的 reviewSeverityLabel 函式,在處理輸入的 comment 物件本身為 nullundefined,或是 comment.body 屬性為 nullundefined 的邊界情況時,可能會拋出執行時期錯誤(TypeError),目前沒有對應的測試案例來驗證此失敗路徑。
建議:建議為 reviewSeverityLabel 函式新增測試案例,驗證當 commentnullundefined,以及 comment.bodynullundefined 時,函式能正確地回傳 undefined 而不拋出錯誤。同時,也請確保函式實作能妥善處理這些邊界輸入。

例如,可以在 app/comments.test.jsdescribe('postFindingsReview', ...) 區塊中,為 reviewSeverityLabel 函式新增以下測試案例:

it('handles null or undefined comment/body gracefully', () => {
  assert.equal(reviewSeverityLabel(null), undefined);
  assert.equal(reviewSeverityLabel(undefined), undefined);
  assert.equal(reviewSeverityLabel({}), undefined); // comment.body is undefined
  assert.equal(reviewSeverityLabel({ body: null }), undefined);
  assert.equal(reviewSeverityLabel({ body: undefined }), undefined);
});

並調整 reviewSeverityLabel 函式實作,例如:

function reviewSeverityLabel(comment) {
  if (!comment || !comment.body) {
    return undefined;
  }
  return comment.body.match(REVIEW_SEVERITY_PATTERN)?.[1];
}
**嚴重等級**:🔴 嚴重 **審查員**:Maya **問題**:新增的 `reviewSeverityLabel` 函式,在處理輸入的 `comment` 物件本身為 `null` 或 `undefined`,或是 `comment.body` 屬性為 `null` 或 `undefined` 的邊界情況時,可能會拋出執行時期錯誤(TypeError),目前沒有對應的測試案例來驗證此失敗路徑。 **建議**:建議為 `reviewSeverityLabel` 函式新增測試案例,驗證當 `comment` 為 `null` 或 `undefined`,以及 `comment.body` 為 `null` 或 `undefined` 時,函式能正確地回傳 `undefined` 而不拋出錯誤。同時,也請確保函式實作能妥善處理這些邊界輸入。 例如,可以在 `app/comments.test.js` 的 `describe('postFindingsReview', ...)` 區塊中,為 `reviewSeverityLabel` 函式新增以下測試案例: ```javascript it('handles null or undefined comment/body gracefully', () => { assert.equal(reviewSeverityLabel(null), undefined); assert.equal(reviewSeverityLabel(undefined), undefined); assert.equal(reviewSeverityLabel({}), undefined); // comment.body is undefined assert.equal(reviewSeverityLabel({ body: null }), undefined); assert.equal(reviewSeverityLabel({ body: undefined }), undefined); }); ``` 並調整 `reviewSeverityLabel` 函式實作,例如: ```javascript function reviewSeverityLabel(comment) { if (!comment || !comment.body) { return undefined; } return comment.body.match(REVIEW_SEVERITY_PATTERN)?.[1]; } ```
Review

嚴重等級🟡 警告
審查員:Leo
問題:在 REVIEW_SEVERITY_PATTERNREVIEW_SEVERITY_LABELS 這兩個常數中,嚴重等級的標籤(例如 '🔴 嚴重')被重複定義了。這會導致未來若要修改或新增標籤時,需要同時更新兩處,容易造成維護上的疏漏與不一致。
建議:建議將嚴重等級標籤定義為單一來源,例如只維護 REVIEW_SEVERITY_LABELS 陣列,然後動態地從這個陣列產生 REVIEW_SEVERITY_PATTERN 的正規表達式字串。這樣可以確保兩者永遠同步,降低未來的維護成本。

例如:

const REVIEW_SEVERITY_LABELS = ['🔴 嚴重', '🟡 警告', '🔵 建議'];
const REVIEW_SEVERITY_PATTERN = new RegExp(`\\*\\*嚴重等級\\*\\*:(${REVIEW_SEVERITY_LABELS.join('|')})(?:\\n|$)`);
**嚴重等級**:🟡 警告 **審查員**:Leo **問題**:在 `REVIEW_SEVERITY_PATTERN` 和 `REVIEW_SEVERITY_LABELS` 這兩個常數中,嚴重等級的標籤(例如 '🔴 嚴重')被重複定義了。這會導致未來若要修改或新增標籤時,需要同時更新兩處,容易造成維護上的疏漏與不一致。 **建議**:建議將嚴重等級標籤定義為單一來源,例如只維護 `REVIEW_SEVERITY_LABELS` 陣列,然後動態地從這個陣列產生 `REVIEW_SEVERITY_PATTERN` 的正規表達式字串。這樣可以確保兩者永遠同步,降低未來的維護成本。 例如: ```javascript const REVIEW_SEVERITY_LABELS = ['🔴 嚴重', '🟡 警告', '🔵 建議']; const REVIEW_SEVERITY_PATTERN = new RegExp(`\\*\\*嚴重等級\\*\\*:(${REVIEW_SEVERITY_LABELS.join('|')})(?:\\n|$)`); ```
import { FINDINGS_PATH } from './config.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];
Outdated
Review

嚴重等級🔵 建議
審查員:Bard
問題:reviewSeverityLabel 函式是專為 postFindingsReview 測試區塊服務的輔助函式。將其定義在檔案頂層,而非其所屬的 describe 區塊內,可能讓程式碼的組織結構顯得不夠緊密,降低了相關程式碼的局部性。
建議:建議將 reviewSeverityLabel 函式及其相關的 REVIEW_SEVERITY_PATTERN 與 REVIEW_SEVERITY_LABELS 常數,一併移至 describe('postFindingsReview', ...) 區塊內部,以提升程式碼的內聚性與可讀性,讓相關的旋律能集中演奏。

**嚴重等級**:🔵 建議 **審查員**:Bard **問題**:reviewSeverityLabel 函式是專為 `postFindingsReview` 測試區塊服務的輔助函式。將其定義在檔案頂層,而非其所屬的 `describe` 區塊內,可能讓程式碼的組織結構顯得不夠緊密,降低了相關程式碼的局部性。 **建議**:建議將 reviewSeverityLabel 函式及其相關的 REVIEW_SEVERITY_PATTERN 與 REVIEW_SEVERITY_LABELS 常數,一併移至 `describe('postFindingsReview', ...)` 區塊內部,以提升程式碼的內聚性與可讀性,讓相關的旋律能集中演奏。
}
describe('saveFindings', () => { describe('saveFindings', () => {
const tempDirs = []; const tempDirs = [];
const makeTempDir = prefix => { const makeTempDir = prefix => {
2
@@ -187,6 +194,16 @@ describe('postNewCriticalComments', () => {
}); });
describe('postFindingsReview', () => { 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 () => { it('posts one review with statistics and sorted line comments', async () => {
const reviewCalls = []; const reviewCalls = [];
const findings = [ const findings = [
@@ -209,8 +226,8 @@ describe('postFindingsReview', () => {
['app/a.js', 'app/b.js', 'app/c.js'], ['app/a.js', 'app/b.js', 'app/c.js'],
); );
assert.deepEqual( assert.deepEqual(
reviewCalls[0].comments.map(c => c.body.match(/嚴重等級\*\*(.+)/)?.[1]), reviewCalls[0].comments.map(reviewSeverityLabel),
['🔴 嚴重', '🟡 警告', '🔵 建議'], REVIEW_SEVERITY_LABELS,
); );
assert.deepEqual( assert.deepEqual(
reviewCalls[0].comments.map(c => c.new_position), reviewCalls[0].comments.map(c => c.new_position),