Files
MyNote/tests/unit/search-service.test.ts
T

59 lines
2.4 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import nodePath from 'node:path';
import os from 'node:os';
import { promises as fs } from 'node:fs';
import { FileService } from '../../apps/desktop/src/main/services/file-service';
import { SearchService } from '../../apps/desktop/src/main/services/search-service';
const tmp = nodePath.join(os.tmpdir(), 'dsh-search-test');
beforeEach(async () => { await fs.rm(tmp, { recursive: true, force: true }); await fs.mkdir(tmp, { recursive: true }); });
afterEach(async () => { await fs.rm(tmp, { recursive: true, force: true }); });
async function mk(root: string) {
const fs2 = new FileService(root);
const ss = new SearchService(root, fs2);
return { fs2, ss };
}
describe('M4 SearchService (FR-R)', () => {
it('全文搜索命中标题与正文,返回摘要', async () => {
const { fs2, ss } = await mk(tmp);
await fs2.writeDoc({ path: 'a.md', meta: { title: 'Markdown 指南' }, body: '介绍 Markdown 的用法\n关键字段落' });
const hits = await ss.search('关键字');
expect(hits.length).toBe(1);
expect(hits[0].title).toBe('Markdown 指南');
expect(hits[0].snippet).toContain('关键字');
});
it('大小写不敏感', async () => {
const { fs2, ss } = await mk(tmp);
await fs2.writeDoc({ path: 'b.md', meta: {}, body: 'Hello World' });
expect((await ss.search('hello')).length).toBe(1);
expect((await ss.search('HELLO')).length).toBe(1);
});
it('空查询返回空', async () => {
const { fs2, ss } = await mk(tmp);
await fs2.writeDoc({ path: 'c.md', meta: {}, body: 'x' });
expect(await ss.search('')).toEqual([]);
expect(await ss.search(' ')).toEqual([]);
});
it('标签汇总:按字母排序、计数', async () => {
const { fs2, ss } = await mk(tmp);
await fs2.writeDoc({ path: 'a.md', meta: { tags: ['z', 'a'] }, body: '1' });
await fs2.writeDoc({ path: 'b.md', meta: { tags: ['a'] }, body: '2' });
const stats = await ss.tagStats();
expect(stats.map(s => s.tag)).toEqual(['a', 'z']);
expect(stats.find(s => s.tag === 'a')?.count).toBe(2);
expect(stats.find(s => s.tag === 'z')?.count).toBe(1);
});
it('搜索结果上限 100', async () => {
const { fs2, ss } = await mk(tmp);
for (let i = 0; i < 120; i++) await fs2.writeDoc({ path: `d${i}.md`, meta: {}, body: 'common' });
const hits = await ss.search('common');
expect(hits.length).toBeLessThanOrEqual(100);
});
});