mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-30 06:12:06 -07:00
Factor out mock date helper in tracker tests
- reuse a shared `withMockDate` helper for date-sensitive query tests - make monthly rollup assertions key off `videoId` instead of row order
This commit is contained in:
@@ -81,6 +81,34 @@ function cleanupDbPath(dbPath: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
function withMockDate<T>(fixedDate: Date, run: (realDate: typeof Date) => T): T {
|
||||
const realDate = Date;
|
||||
const fixedDateMs = fixedDate.getTime();
|
||||
|
||||
type MockDateArgs = [any, any, any, any, any, any, any];
|
||||
|
||||
class MockDate extends Date {
|
||||
constructor(...args: MockDateArgs) {
|
||||
if (args.length === 0) {
|
||||
super(fixedDateMs);
|
||||
} else {
|
||||
super(...args);
|
||||
}
|
||||
}
|
||||
|
||||
static override now(): number {
|
||||
return fixedDateMs;
|
||||
}
|
||||
}
|
||||
|
||||
globalThis.Date = MockDate as DateConstructor;
|
||||
try {
|
||||
return run(realDate);
|
||||
} finally {
|
||||
globalThis.Date = realDate;
|
||||
}
|
||||
}
|
||||
|
||||
test('getSessionSummaries returns sessionId and canonicalTitle', () => {
|
||||
const dbPath = makeDbPath();
|
||||
const db = new Database(dbPath);
|
||||
@@ -790,25 +818,8 @@ test('getTrendsDashboard keeps local-midnight session buckets separate', () => {
|
||||
test('getTrendsDashboard month grouping spans every touched calendar month and keeps progress monthly', () => {
|
||||
const dbPath = makeDbPath();
|
||||
const db = new Database(dbPath);
|
||||
const RealDate = Date;
|
||||
|
||||
class MockDate extends Date {
|
||||
constructor(...args: any[]) {
|
||||
type MockDateArgs = [any, any, any, any, any, any, any];
|
||||
if (args.length === 0) {
|
||||
super(new RealDate(2026, 2, 1, 12, 0, 0).getTime());
|
||||
} else {
|
||||
super(...(args as MockDateArgs));
|
||||
}
|
||||
}
|
||||
|
||||
static override now(): number {
|
||||
return new RealDate(2026, 2, 1, 12, 0, 0).getTime();
|
||||
}
|
||||
}
|
||||
|
||||
withMockDate(new Date(2026, 2, 1, 12, 0, 0), (RealDate) => {
|
||||
try {
|
||||
globalThis.Date = MockDate as DateConstructor;
|
||||
ensureSchema(db);
|
||||
const stmts = createTrackerPreparedStatements(db);
|
||||
const febVideoId = getOrCreateVideoRecord(db, 'local:/tmp/feb-trends.mkv', {
|
||||
@@ -988,10 +999,10 @@ test('getTrendsDashboard month grouping spans every touched calendar month and k
|
||||
dashboard.activity.watchTime.map((point) => point.label),
|
||||
);
|
||||
} finally {
|
||||
globalThis.Date = RealDate;
|
||||
db.close();
|
||||
cleanupDbPath(dbPath);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('getQueryHints reads all-time totals from lifetime summary', () => {
|
||||
@@ -1067,25 +1078,9 @@ test('getQueryHints reads all-time totals from lifetime summary', () => {
|
||||
test('getQueryHints computes weekly new-word cutoff from calendar midnights', () => {
|
||||
const dbPath = makeDbPath();
|
||||
const db = new Database(dbPath);
|
||||
const RealDate = Date;
|
||||
|
||||
class MockDate extends Date {
|
||||
constructor(...args: any[]) {
|
||||
type MockDateArgs = [any, any, any, any, any, any, any];
|
||||
if (args.length === 0) {
|
||||
super(new RealDate(2026, 2, 15, 12, 0, 0).getTime());
|
||||
} else {
|
||||
super(...(args as MockDateArgs));
|
||||
}
|
||||
}
|
||||
|
||||
static override now(): number {
|
||||
return new RealDate(2026, 2, 15, 12, 0, 0).getTime();
|
||||
}
|
||||
}
|
||||
|
||||
withMockDate(new Date(2026, 2, 15, 12, 0, 0), (RealDate) => {
|
||||
try {
|
||||
globalThis.Date = MockDate as DateConstructor;
|
||||
ensureSchema(db);
|
||||
|
||||
const insertWord = db.prepare(
|
||||
@@ -1129,10 +1124,10 @@ test('getQueryHints computes weekly new-word cutoff from calendar midnights', ()
|
||||
const hints = getQueryHints(db);
|
||||
assert.equal(hints.newWordsThisWeek, 1);
|
||||
} finally {
|
||||
globalThis.Date = RealDate;
|
||||
db.close();
|
||||
cleanupDbPath(dbPath);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('getQueryHints counts new words by distinct headword first-seen time', () => {
|
||||
@@ -1522,11 +1517,12 @@ test('getMonthlyRollups derives rate metrics from stored monthly totals', () =>
|
||||
|
||||
const rows = getMonthlyRollups(db, 1);
|
||||
assert.equal(rows.length, 2);
|
||||
assert.equal(rows[1]?.cardsPerHour, 30);
|
||||
assert.equal(rows[1]?.tokensPerMin, 3);
|
||||
assert.equal(rows[1]?.lookupHitRate ?? null, null);
|
||||
assert.equal(rows[0]?.cardsPerHour ?? null, null);
|
||||
assert.equal(rows[0]?.tokensPerMin ?? null, null);
|
||||
const rowsByVideoId = new Map(rows.map((row) => [row.videoId, row]));
|
||||
assert.equal(rowsByVideoId.get(2)?.cardsPerHour, 30);
|
||||
assert.equal(rowsByVideoId.get(2)?.tokensPerMin, 3);
|
||||
assert.equal(rowsByVideoId.get(2)?.lookupHitRate ?? null, null);
|
||||
assert.equal(rowsByVideoId.get(1)?.cardsPerHour ?? null, null);
|
||||
assert.equal(rowsByVideoId.get(1)?.tokensPerMin ?? null, null);
|
||||
} finally {
|
||||
db.close();
|
||||
cleanupDbPath(dbPath);
|
||||
|
||||
Reference in New Issue
Block a user