Files
ObsiViewer/src/core/search/search-parser.spec.ts
T
2025-10-03 14:24:16 -04:00

73 lines
2.6 KiB
TypeScript

import { detectQueryType, parseSearchQuery, queryToPredicate } from './search-parser';
import { SearchContext } from './search-parser.types';
const createContext = (overrides: Partial<SearchContext> = {}): SearchContext => ({
filePath: 'notes/example.md',
fileName: 'example',
fileNameWithExt: 'example.md',
content: 'Hello world with #tag in section heading',
tags: ['#tag'],
properties: { author: 'Ada', status: 'draft' },
lines: ['Hello world with #tag', 'Another line'],
blocks: ['Hello world with #tag in section heading'],
sections: [{ heading: 'Section', content: 'Hello world', level: 1 }],
tasks: [
{ text: 'Call Bob', completed: false, line: 3 },
{ text: 'Review PR', completed: true, line: 5 }
],
...overrides
});
describe('Search Parser', () => {
it('parseSearchQuery marks empty query as empty', () => {
const parsed = parseSearchQuery('');
expect(parsed.isEmpty).toBeTrue();
expect(parsed.ast.type).toBe('group');
});
it('parseSearchQuery handles basic text queries', () => {
const parsed = parseSearchQuery('hello world');
expect(parsed.isEmpty).toBeFalse();
expect(parsed.ast.type).toBe('group');
});
it('parseSearchQuery handles operators', () => {
const parsed = parseSearchQuery('path:notes/ tag:#tag file:example');
expect(parsed.isEmpty).toBeFalse();
});
it('queryToPredicate matches simple text', () => {
const predicate = queryToPredicate(parseSearchQuery('hello'));
expect(predicate(createContext())).toBeTrue();
});
it('queryToPredicate respects negation', () => {
const predicate = queryToPredicate(parseSearchQuery('-deprecated'));
expect(predicate(createContext())).toBeTrue();
expect(predicate(createContext({ content: 'deprecated feature' }))).toBeFalse();
});
it('queryToPredicate matches task scopes', () => {
const todoPredicate = queryToPredicate(parseSearchQuery('task-todo:Call'));
const donePredicate = queryToPredicate(parseSearchQuery('task-done:Review'));
expect(todoPredicate(createContext())).toBeTrue();
expect(donePredicate(createContext())).toBeTrue();
});
it('detectQueryType recognises path prefix', () => {
const info = detectQueryType('path:notes');
expect(info.type).toBe('path');
expect(info.value).toBe('notes');
});
it('detectQueryType recognises property bracket', () => {
const info = detectQueryType('[status:');
expect(info.type).toBe('property');
});
it('detectQueryType falls back to general type', () => {
const info = detectQueryType('plain text');
expect(info.type).toBe('general');
});
});