import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
import { FileCache } from '@/spider/cache.js';
import { promises as fs } from 'fs';
describe('cache integration', () => {
const testCacheDir = './test-cache-integration';
let cache: FileCache;
beforeEach(async () => {
// clean test cache
try {
await fs.rm(testCacheDir, { recursive: true, force: true });
} catch {
// ignore if doesn't exist
}
cache = new FileCache(testCacheDir, 60000); // 1 minute ttl for tests
});
afterEach(async () => {
// cleanup test cache
try {
await fs.rm(testCacheDir, { recursive: true, force: true });
} catch {
// ignore if doesn't exist
}
});
describe('file persistence', () => {
it('should persist cache entries to disk', async () => {
const testResult = {
url: 'https://example.com/test',
title: 'Test Page',
content: 'Test content',
metadata: {
wordCount: 2,
links: [],
},
timestamp: Date.now(),
depth: 0,
};
await cache.set(testResult.url, testResult);
// create new cache instance to test persistence
const newCache = new FileCache(testCacheDir, 60000);
const retrieved = await newCache.get(testResult.url);
expect(retrieved).toEqual(testResult);
});
it('should handle cache miss', async () => {
const result = await cache.get('https://nonexistent.com');
expect(result).toBeNull();
});
it('should clear cache files', async () => {
const testResult = {
url: 'https://example.com/test',
title: 'Test Page',
content: 'Test content',
metadata: {
wordCount: 2,
links: [],
},
timestamp: Date.now(),
depth: 0,
};
await cache.set(testResult.url, testResult);
const cleared = await cache.clear();
expect(cleared).toBeGreaterThanOrEqual(0);
const retrieved = await cache.get(testResult.url);
expect(retrieved).toBeNull();
});
});
describe('cache statistics', () => {
it('should provide cache stats', async () => {
const stats = await cache.getStats();
expect(stats).toHaveProperty('totalEntries');
expect(stats).toHaveProperty('totalSize');
expect(stats).toHaveProperty('hitRate');
expect(typeof stats.totalEntries).toBe('number');
expect(typeof stats.totalSize).toBe('number');
expect(typeof stats.hitRate).toBe('number');
});
});
describe('cache cleanup', () => {
it('should cleanup expired entries', async () => {
const shortTtlCache = new FileCache(testCacheDir, 1); // 1ms ttl
const testResult = {
url: 'https://example.com/expire',
title: 'Expire Test',
content: 'Test content',
metadata: {
wordCount: 2,
links: [],
},
timestamp: Date.now(),
depth: 0,
};
await shortTtlCache.set(testResult.url, testResult);
// wait for expiration
await new Promise(resolve => setTimeout(resolve, 10));
const cleaned = await shortTtlCache.cleanup();
expect(cleaned).toBeGreaterThanOrEqual(0);
});
});
});