aboutsummaryrefslogtreecommitdiff
path: root/src/lib/components/fuzzy-search.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/components/fuzzy-search.test.ts')
-rw-r--r--src/lib/components/fuzzy-search.test.ts53
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);
+ }
+ });
+});