import { parseQuery, QueryAST } from '@/lib/query-parser' describe('query-parser', () => { describe('basic text queries', () => { it('returns text with no filters for simple text', () => { const result = parseQuery('docker') expect(result.text).toBe('docker') expect(result.filters).toEqual({}) }) it('preserves multi-word text', () => { const result = parseQuery('hello world') expect(result.text).toBe('hello world') expect(result.filters).toEqual({}) }) }) describe('type filter', () => { it('extracts type filter from beginning of query', () => { const result = parseQuery('type:command docker') expect(result.text).toBe('docker') expect(result.filters).toEqual({ type: 'command' }) }) it('handles query with only type filter', () => { const result = parseQuery('type:snippet') expect(result.text).toBe('') expect(result.filters).toEqual({ type: 'snippet' }) }) it('extracts type filter from end of query', () => { const result = parseQuery('docker type:command') expect(result.text).toBe('docker') expect(result.filters).toEqual({ type: 'command' }) }) }) describe('tag filter', () => { it('extracts tag filter with text', () => { const result = parseQuery('tag:api error') expect(result.text).toBe('error') expect(result.filters).toEqual({ tag: 'api' }) }) it('handles query with only tag filter', () => { const result = parseQuery('tag:backend') expect(result.text).toBe('') expect(result.filters).toEqual({ tag: 'backend' }) }) }) describe('combined filters', () => { it('parses multiple filters together', () => { const result = parseQuery('docker tag:backend type:command') expect(result.text).toBe('docker') expect(result.filters).toEqual({ type: 'command', tag: 'backend' }) }) it('handles type, tag, and isFavorite combined', () => { const result = parseQuery('type:snippet tag:python is:favorite') expect(result.text).toBe('') expect(result.filters).toEqual({ type: 'snippet', tag: 'python', isFavorite: true }) }) }) describe('boolean filters', () => { it('extracts is:favorite filter', () => { const result = parseQuery('is:favorite docker') expect(result.text).toBe('docker') expect(result.filters).toEqual({ isFavorite: true }) }) it('handles is:pinned filter alone', () => { const result = parseQuery('is:pinned') expect(result.text).toBe('') expect(result.filters).toEqual({ isPinned: true }) }) it('handles both boolean filters with text', () => { const result = parseQuery('is:favorite is:pinned docker') expect(result.text).toBe('docker') expect(result.filters).toEqual({ isFavorite: true, isPinned: true }) }) }) describe('edge cases', () => { it('handles empty string', () => { const result = parseQuery('') expect(result.text).toBe('') expect(result.filters).toEqual({}) }) it('handles whitespace only', () => { const result = parseQuery(' ') expect(result.text).toBe('') expect(result.filters).toEqual({}) }) it('ignores empty type value', () => { const result = parseQuery('type:') expect(result.text).toBe('') expect(result.filters).toEqual({}) }) it('ignores empty tag value', () => { const result = parseQuery('tag:') expect(result.text).toBe('') expect(result.filters).toEqual({}) }) it('last duplicate filter wins for type', () => { const result = parseQuery('type:command type:snippet docker') expect(result.text).toBe('docker') expect(result.filters).toEqual({ type: 'snippet' }) }) it('last duplicate filter wins for tag', () => { const result = parseQuery('tag:python tag:javascript code') expect(result.text).toBe('code') expect(result.filters).toEqual({ tag: 'javascript' }) }) }) describe('case sensitivity', () => { it('filter name is case insensitive', () => { const result = parseQuery('TYPE:command') expect(result.filters).toEqual({ type: 'command' }) }) it('filter value is case sensitive', () => { const result = parseQuery('type:Command') expect(result.filters).toEqual({ type: 'Command' }) }) it('is:favorite is case insensitive', () => { const result = parseQuery('IS:FAVORITE docker') expect(result.filters).toEqual({ isFavorite: true }) }) it('is:pinned is case insensitive', () => { const result = parseQuery('IS:PINNED') expect(result.filters).toEqual({ isPinned: true }) }) }) })