test(ai-review): 補使用量統計 NaN 安全測試並排除微優化誤報 #46

Merged
jiantw83 merged 14 commits from ai-review-resolve/20260623-163642 into develop 2026-06-23 09:35:21 +00:00
Showing only changes of commit 791449161f - Show all commits
+36
View File
@@ -196,6 +196,25 @@ describe('resolveRemainingPercent', () => {
assert.match(pct.reason, /無上限/);
});
it('returns null percent for non-finite or non-positive quota limits', () => {
for (const limit of [0, -5, Infinity, NaN, undefined]) {
admin marked this conversation as resolved
Review

嚴重等級🟡 警告
審查員:Bard
問題:測試迴圈中的陣列 [0, -5, Infinity, NaN, undefined] 直接混用了不同型別與邊界值,雖然測試目的明確,但在測試碼中,將邏輯測試與邊界測試分開撰寫會更具可讀性。
建議:建議將測試案例拆分,例如分開測試「非數字類型」、「負數」與「邊界值(Infinity/NaN)」,這樣在測試失敗時能更快速釐清是哪種輸入類型導致的問題。

**嚴重等級**:🟡 警告 **審查員**:Bard **問題**:測試迴圈中的陣列 `[0, -5, Infinity, NaN, undefined]` 直接混用了不同型別與邊界值,雖然測試目的明確,但在測試碼中,將邏輯測試與邊界測試分開撰寫會更具可讀性。 **建議**:建議將測試案例拆分,例如分開測試「非數字類型」、「負數」與「邊界值(Infinity/NaN)」,這樣在測試失敗時能更快速釐清是哪種輸入類型導致的問題。
const pct = resolveRemainingPercent({ available: true, used: 0, limit, remaining: limit, currency: 'USD' }, null);
assert.equal(pct.percent, null, `quota.limit=${limit} 應算不出百分比`);
}
});
it('returns null percent for non-finite or non-positive rate limits', () => {
for (const limit of [0, -1, Infinity, NaN]) {
const pct = resolveRemainingPercent({ available: false, reason: 'x' }, { hasData: true, remaining: limit, limit, kind: 'tokens' });
assert.equal(pct.percent, null, `rate.limit=${limit} 應算不出百分比`);
}
});
it('returns null percent when limit is finite but remaining is non-finite', () => {
const pct = resolveRemainingPercent({ available: true, used: 0, limit: 100, remaining: Infinity, currency: 'USD' }, null);
assert.equal(pct.percent, null);
});
Review

嚴重等級🔵 建議
審查員:Maya
問題:測試案例 returns null percent when rate.remaining is null/undefined 僅驗證了 remaining 為 null/undefined,但未驗證當 rate.limit 為 null/undefined 時的情況。雖然這可能由 calculatePercent 內部處理,但針對 resolveRemainingPercent 這一層級的整合測試仍不完整。
建議:建議補上一個測試案例,明確測試當 rate.limit 為 null/undefined 時,resolveRemainingPercent 的行為是否符合預期。

**嚴重等級**:🔵 建議 **審查員**:Maya **問題**:測試案例 `returns null percent when rate.remaining is null/undefined` 僅驗證了 remaining 為 null/undefined,但未驗證當 rate.limit 為 null/undefined 時的情況。雖然這可能由 `calculatePercent` 內部處理,但針對 `resolveRemainingPercent` 這一層級的整合測試仍不完整。 **建議**:建議補上一個測試案例,明確測試當 `rate.limit` 為 null/undefined 時,`resolveRemainingPercent` 的行為是否符合預期。
it('does not divide by zero when quota.limit is 0', () => {
const pct = resolveRemainingPercent({ available: true, used: 5, limit: 0, currency: 'USD' }, { hasData: false });
assert.equal(pct.percent, null); // limit > 0 守衛擋掉除以零
4
@@ -253,4 +272,21 @@ describe('formatUsageStatsLine', () => {
assert.doesNotMatch(line, /NaN/);
assert.match(line, /剩餘可用: 無法計算/);
});
it('does not output Infinity/NaN/negative percent for invalid quota numbers', () => {
const ownUsage = { calls: 1, promptTokens: 1, completionTokens: 1, totalTokens: 2 };
for (const limit of [Infinity, 0, -5, NaN]) {
const line = formatUsageStatsLine('openai', 'm', ownUsage, { available: true, used: 0, limit, remaining: limit, currency: 'USD' }, null);
assert.doesNotMatch(line, /NaN|Infinity|-\d+%/);
assert.match(line, /剩餘可用: 無法計算/);
}
});
it('falls back to a valid rate percent when only the quota limit is invalid', () => {
const ownUsage = { calls: 1, promptTokens: 1, completionTokens: 1, totalTokens: 2 };
const line = formatUsageStatsLine('openai', 'm', ownUsage,
{ available: true, used: 0, limit: Infinity, currency: 'USD' }, // quota 無效
{ hasData: true, remaining: 150000, limit: 200000, kind: 'tokens' }); // rate 有效 → 75%
assert.match(line, /剩餘可用: 75%(速率配額/);
});
});