Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/tools/trend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ export function computeTrend(
recentCommits: import('../lib/git-utils').Commit[],
olderCommits: import('../lib/git-utils').Commit[],
windowDays: number,
top: number
top: number,
now: Date = new Date()
): { worsening: TrendResult[]; improving: TrendResult[]; insufficientHistory: boolean } {
// Check for insufficient history
if (olderCommits.length === 0) {
Expand All @@ -77,8 +78,8 @@ export function computeTrend(

// Compute curse scores for each window — get ALL files, not just top N
// Use the end of each window as the reference date for curse score calculation
const recentRefDate = new Date(); // now
const olderRefDate = new Date(Date.now() - windowDays * 24 * 60 * 60 * 1000); // end of older window
const recentRefDate = now;
const olderRefDate = new Date(now.getTime() - windowDays * 24 * 60 * 60 * 1000); // end of older window

const recentScores = computeCurseScoresAll(recentCommits, recentRefDate);
const olderScores = computeCurseScoresAll(olderCommits, olderRefDate);
Expand Down
19 changes: 12 additions & 7 deletions tests/trend.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ function makeCommit(
}

describe('computeTrend', () => {
// Fixed reference clock so tests stay deterministic regardless of wall time
// (recent commits Jun 2026 must be <90d before NOW; older Jan-Mar 2026 commits
// must be <90d before NOW - 90d = 2026-03-17).
const NOW = new Date('2026-06-15T00:00:00Z');

it('detects files with increasing curse score (positive trend)', () => {
const recentCommits: Commit[] = [
makeCommit('a'.repeat(40), 'Alice', '2026-06-10T00:00:00Z', [
Expand All @@ -39,7 +44,7 @@ describe('computeTrend', () => {
]),
];

const result = computeTrend(recentCommits, olderCommits, 90, 10);
const result = computeTrend(recentCommits, olderCommits, 90, 10, NOW);

expect(result.insufficientHistory).toBe(false);
expect(result.worsening.length).toBeGreaterThan(0);
Expand Down Expand Up @@ -69,7 +74,7 @@ describe('computeTrend', () => {
]),
];

const result = computeTrend(recentCommits, olderCommits, 90, 10);
const result = computeTrend(recentCommits, olderCommits, 90, 10, NOW);

expect(result.improving.length).toBeGreaterThan(0);
const calmFile = result.improving.find((r) => r.file === 'src/calming.ts');
Expand Down Expand Up @@ -101,7 +106,7 @@ describe('computeTrend', () => {
);
}

const result = computeTrend(recentCommits, olderCommits, 90, 5);
const result = computeTrend(recentCommits, olderCommits, 90, 5, NOW);
expect(result.worsening.length).toBeLessThanOrEqual(5);
});

Expand All @@ -112,7 +117,7 @@ describe('computeTrend', () => {
]),
];

const result = computeTrend(recentCommits, [], 90, 10);
const result = computeTrend(recentCommits, [], 90, 10, NOW);
expect(result.insufficientHistory).toBe(true);
expect(result.worsening).toHaveLength(0);
});
Expand All @@ -130,7 +135,7 @@ describe('computeTrend', () => {
]),
];

const result = computeTrend(recentCommits, olderCommits, 90, 10);
const result = computeTrend(recentCommits, olderCommits, 90, 10, NOW);
const newFile = result.worsening.find((r) => r.file === 'src/new.ts');
expect(newFile).toBeDefined();
expect(newFile!.note).toBe('new file, no older score');
Expand All @@ -150,7 +155,7 @@ describe('computeTrend', () => {
]),
];

const result = computeTrend(recentCommits, olderCommits, 90, 10);
const result = computeTrend(recentCommits, olderCommits, 90, 10, NOW);
const deletedFile = result.improving.find((r) => r.file === 'src/deleted.ts');
expect(deletedFile).toBeDefined();
expect(deletedFile!.note).toBe('deleted');
Expand All @@ -159,7 +164,7 @@ describe('computeTrend', () => {
});

it('returns empty when no commits at all', () => {
const result = computeTrend([], [], 90, 10);
const result = computeTrend([], [], 90, 10, NOW);
expect(result.worsening).toHaveLength(0);
expect(result.improving).toHaveLength(0);
expect(result.insufficientHistory).toBe(false);
Expand Down
Loading