diff --git a/src/review/review-effort.ts b/src/review/review-effort.ts index 8c2a1b3a94..64ab8b2dbd 100644 --- a/src/review/review-effort.ts +++ b/src/review/review-effort.ts @@ -46,9 +46,10 @@ function bandForEffort(effort: number): 1 | 2 | 3 | 4 | 5 { return 5; } -/** Map a persisted minutes estimate back to its complexity band (inverse of `estimateReviewEffort`'s minutes step). */ +/** Map a persisted rounded minutes estimate to the highest complexity band it could represent. */ export function bandFromMinutes(minutes: number): 1 | 2 | 3 | 4 | 5 { - return bandForEffort(Math.max(0, minutes) / MINUTES_PER_EFFORT); + const maxRepresentedEffort = (Math.max(0, minutes) + 0.5) / MINUTES_PER_EFFORT; + return bandForEffort(maxRepresentedEffort); } /** Estimate the review effort of a change set. Pure and deterministic. */ diff --git a/test/unit/review-effort.test.ts b/test/unit/review-effort.test.ts index 8f336435e9..cc686cb530 100644 --- a/test/unit/review-effort.test.ts +++ b/test/unit/review-effort.test.ts @@ -69,4 +69,11 @@ describe("bandFromMinutes (#2155)", () => { expect(bandFromMinutes(sample.minutes)).toBe(sample.band); } }); + + it("keeps rounded boundary minutes in the higher possible band (regression for #2155)", () => { + expect(bandFromMinutes(5)).toBe(2); + expect(bandFromMinutes(20)).toBe(3); + expect(bandFromMinutes(60)).toBe(4); + expect(bandFromMinutes(150)).toBe(5); + }); }); diff --git a/test/unit/stats.test.ts b/test/unit/stats.test.ts index 30b1a70f7a..20460576ee 100644 --- a/test/unit/stats.test.ts +++ b/test/unit/stats.test.ts @@ -152,6 +152,10 @@ describe("aggregateReviewEffort — maintainer complexity fold (#2155)", () => { // minutes 4 -> band 1; minutes 96 -> band 4 -> rounded avg 3; total 100. expect(aggregateReviewEffort([4, 96])).toEqual({ avgBand: 3, totalEstimatedMinutes: 100 }); }); + + it("keeps boundary-rounded minutes in the higher possible avgBand (regression for #2155)", () => { + expect(aggregateReviewEffort([5, 20, 60, 150])).toEqual({ avgBand: 4, totalEstimatedMinutes: 235 }); + }); }); describe("computeStats — review-effort read is fail-safe", () => {