Files
Codeman/test/document-preview-cache-eviction.test.ts
T

55 lines
2.1 KiB
TypeScript
Raw Normal View History

import { describe, it, expect, beforeEach, vi } from 'vitest';
import fs from 'node:fs/promises';
import { pruneDocumentPreviewCache } from '../src/document-preview-cache.js';
vi.mock('node:fs/promises', () => ({
default: {
readdir: vi.fn(),
stat: vi.fn(),
rm: vi.fn(async () => undefined),
},
}));
const mockedReaddir = vi.mocked(fs.readdir);
const mockedStat = vi.mocked(fs.stat);
const mockedRm = vi.mocked(fs.rm);
describe('pruneDocumentPreviewCache', () => {
beforeEach(() => {
vi.clearAllMocks();
// mtime encoded in the filename (f0 oldest ... f101 newest)
mockedStat.mockImplementation(async (p) => {
const m = /f(\d+)\.pdf$/.exec(String(p));
return { mtimeMs: m ? Number(m[1]) : 0, isFile: () => true } as never;
});
});
it('evicts the oldest *.pdf files once the cache exceeds the cap (default 100)', async () => {
const names = Array.from({ length: 102 }, (_, i) => `f${i}.pdf`);
mockedReaddir.mockResolvedValue(names as never);
await pruneDocumentPreviewCache('/tmp/codeman-document-preview-cache');
// 102 - 100 = 2 oldest removed
expect(mockedRm).toHaveBeenCalledTimes(2);
const removed = mockedRm.mock.calls.map((c) => String(c[0]));
expect(removed.some((p) => p.endsWith('f0.pdf'))).toBe(true);
expect(removed.some((p) => p.endsWith('f1.pdf'))).toBe(true);
expect(removed.some((p) => p.endsWith('f101.pdf'))).toBe(false); // newest kept
});
it('ignores non-pdf entries (e.g. transient work-* dirs) when counting', async () => {
const names = [...Array.from({ length: 50 }, (_, i) => `f${i}.pdf`), 'work-abc', 'work-def'];
mockedReaddir.mockResolvedValue(names as never);
await pruneDocumentPreviewCache('/tmp/codeman-document-preview-cache');
expect(mockedRm).not.toHaveBeenCalled(); // 50 pdfs <= cap
});
it('never throws when the cache dir cannot be read', async () => {
mockedReaddir.mockRejectedValue(new Error('ENOENT'));
await expect(pruneDocumentPreviewCache('/tmp/missing')).resolves.toBeUndefined();
expect(mockedRm).not.toHaveBeenCalled();
});
});