import { describe, expect, it } from 'vitest'; import { parseQuery, toTsQuery } from './parse.js'; describe('parseQuery', () => { it('extracts grade, year and category', () => { const q = parseQuery('1999 Charizard PSA 10'); expect(q.grader).toBe('psa'); expect(q.grade).toBe('10'); expect(q.year).toBe(1999); expect(q.text).toContain('Charizard'); expect(q.text.toLowerCase()).not.toContain('psa'); }); it('extracts price bounds', () => { expect(parseQuery('Rolex Daytona under $20,000')).toMatchObject({ priceMax: 20000, currency: 'USD', categorySlugs: ['rolex'] }); expect(parseQuery('pokemon cards between $500 and $1,000')).toMatchObject({ priceMin: 500, priceMax: 1000 }); expect(parseQuery('lego over 2k')).toMatchObject({ priceMin: 2000 }); expect(parseQuery('Rolex Daytona under $20,000').text.toLowerCase()).not.toContain('under'); }); it('detects conditions and editions', () => { const q = parseQuery('sealed Mario 64'); expect(q.conditions).toContain('sealed'); expect(q.categorySlugs).toContain('nintendo_games'); const h = parseQuery('first edition Harry Potter UK'); expect(h.editions).toContain('1st edition'); expect(h.categorySlugs).toContain('harry_potter'); expect(parseQuery('Michael Jordan rookie PSA 10').editions).toContain('rookie'); expect(parseQuery('LEGO Millennium Falcon retired').categorySlugs).toContain('lego'); }); it('does not invent filters', () => { const q = parseQuery('Charizard'); expect(q.grader).toBeNull(); expect(q.priceMax).toBeNull(); expect(q.year).toBeNull(); }); it('builds tsquery', () => { expect(toTsQuery('Charizard 4/102')).toBe('charizard:* & 4/102:*'); expect(toTsQuery('')).toBeNull(); expect(toTsQuery("o'neal")).toBe('oneal:*'); }); });