Files
quick-access-hono/tests/cache.test.ts
T
qwsdcvghyu89 363d894c79 Initial commit
2026-06-17 07:19:25 +10:00

102 lines
3.2 KiB
TypeScript

import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
import { mkdtempSync, rmSync } from 'fs';
import { join } from 'path';
import { tmpdir } from 'os';
import { Cache } from '../src/services/cache.ts';
import type { TextFragment } from '../src/types.ts';
let tmpDir: string;
let cache: Cache;
beforeEach(() => {
tmpDir = mkdtempSync(join(tmpdir(), 'qa-cache-test-'));
cache = new Cache(tmpDir);
});
afterEach(() => {
rmSync(tmpDir, { recursive: true, force: true });
});
describe('cache — chapters', () => {
test('returns null on a cold cache', () => {
expect(cache.tryGetChapters(1, 0, 5)).toBeNull();
});
test('returns null when a chapter in range is missing', () => {
cache.saveChapters(1, [
{ index: 0, content: 'Chapter zero content here' },
// index 1 is intentionally missing
{ index: 2, content: 'Chapter two content here' },
]);
expect(cache.tryGetChapters(1, 0, 2)).toBeNull();
});
test('returns null for invalid range (min > max)', () => {
expect(cache.tryGetChapters(1, 5, 2)).toBeNull();
});
test('saves and retrieves plain-text chapters', () => {
cache.saveChapters(1, [
{ index: 0, content: 'Line one\nLine two' },
{ index: 1, content: 'Chapter one content here' },
]);
const view = cache.tryGetChapters(1, 0, 1);
expect(view).not.toBeNull();
expect(view!.id).toBe(1);
expect(view!.min).toBe(0);
expect(view!.max).toBe(1);
expect(view!.chapters).toHaveLength(2);
expect(view!.chapters[0]!.hasStyle).toBe(false);
});
test('detects styled (JSON fragment) chapters', () => {
const fragments: TextFragment[] = [{ body: 'Hello world', style: undefined }];
cache.saveChapters(1, [{ index: 0, content: JSON.stringify(fragments) }]);
const view = cache.tryGetChapters(1, 0, 0);
expect(view).not.toBeNull();
expect(view!.chapters[0]!.hasStyle).toBe(true);
});
test('returns null when a chapter file is too short', () => {
cache.saveChapters(1, [{ index: 0, content: 'hi' }]); // < 10 bytes
expect(cache.tryGetChapters(1, 0, 0)).toBeNull();
});
test('handles single-chapter range', () => {
cache.saveChapters(42, [{ index: 7, content: 'Single chapter content ok' }]);
const view = cache.tryGetChapters(42, 7, 7);
expect(view).not.toBeNull();
expect(view!.chapters).toHaveLength(1);
});
});
describe('cache — TOC', () => {
test('returns null on a cold cache', () => {
expect(cache.tryGetToc(1)).toBeNull();
});
test('round-trips a TOC', () => {
const urls = [
'https://example.com/chapter-1',
'https://example.com/chapter-2',
'https://example.com/chapter-3',
];
cache.saveToc(1, urls);
expect(cache.tryGetToc(1)).toEqual(urls);
});
test('returns null for an empty TOC file', () => {
cache.saveToc(1, []);
expect(cache.tryGetToc(1)).toBeNull();
});
test('overwrites an existing TOC on re-save', () => {
cache.saveToc(1, ['https://example.com/old']);
cache.saveToc(1, ['https://example.com/new-1', 'https://example.com/new-2']);
expect(cache.tryGetToc(1)).toEqual([
'https://example.com/new-1',
'https://example.com/new-2',
]);
});
});