73 lines
2.6 KiB
TypeScript
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');
|
|
});
|
|
});
|