import { detectQueryType, parseSearchQuery, queryToPredicate } from './search-parser'; import { SearchContext } from './search-parser.types'; const createContext = (overrides: Partial = {}): 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'); }); });