diff options
Diffstat (limited to 'src/lib/components/fuzzy-search.test.ts')
| -rw-r--r-- | src/lib/components/fuzzy-search.test.ts | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/lib/components/fuzzy-search.test.ts b/src/lib/components/fuzzy-search.test.ts new file mode 100644 index 0000000..57d0d1d --- /dev/null +++ b/src/lib/components/fuzzy-search.test.ts @@ -0,0 +1,53 @@ +import { describe, it, expect } from 'vitest'; +import { matchItems, FUZZ_LIMIT } from './fuzzy-search'; +import type { FuzzyItem } from './fuzzy-search'; + +const catalog: FuzzyItem[] = [ + { id: 1, name: 'Citron' }, + { id: 2, name: 'Citrons' }, + { id: 3, name: 'Concombre' }, + { id: 4, name: 'Tomate' }, + { id: 5, name: 'Carotte' }, + { id: 6, name: 'Lait' }, +]; + +describe('matchItems', () => { + it('returns nothing for an empty or whitespace query', () => { + expect(matchItems(catalog, '')).toHaveLength(0); + expect(matchItems(catalog, ' ')).toHaveLength(0); + }); + + it('matches a fuzzy query, ranking the best match first', () => { + const res = matchItems(catalog, 'citrn'); + expect(res.length).toBeGreaterThanOrEqual(1); + // exact-ish run should beat the pluralised variant + expect(res[0].obj.name).toBe('Citron'); + }); + + it('is case-insensitive', () => { + const res = matchItems(catalog, 'TOMA'); + expect(res[0].obj.name).toBe('Tomate'); + }); + + it('keeps matched-across-junk subsequence results', () => { + const res = matchItems(catalog, 'cb'); // C-o-n-**c**ombre → c arguments + const names = res.map((r) => r.obj.name); + expect(names).toContain('Concombre'); + }); + + it('respects the limit', () => { + const many = Array.from({ length: 40 }, (_, i) => ({ + id: i, + name: `Article ${i}`, + })); + const res = matchItems(many, 'article'); + expect(res.length).toBeLessThanOrEqual(FUZZ_LIMIT); + }); + + it('sorts best matches first by descending score', () => { + const res = matchItems(catalog, 'tomate'); + for (let i = 1; i < res.length; i++) { + expect(res[i - 1].score).toBeGreaterThanOrEqual(res[i].score); + } + }); +}); |
