import { describe, test, expect } from "vitest"; import { normalizeSearchText, matchesSearchQuery } from "./search-match"; describe("normalizeSearchText", () => { test("lowercases and transliterates umlauts to their ASCII equivalent", () => { expect(normalizeSearchText("Frühtracht")).toBe("fruehtracht"); expect(normalizeSearchText("kräftig")).toBe("kraeftig"); expect(normalizeSearchText("Altenmünster")).toBe("altenmuenster"); expect(normalizeSearchText("rußarm")).toBe("russarm"); }); test("leaves already-ASCII text unchanged apart from casing", () => { expect(normalizeSearchText("Honig")).toBe("honig"); }); }); describe("matchesSearchQuery", () => { test("matches when the query uses real umlauts and the haystack does too", () => { expect(matchesSearchQuery("Frühtracht 2026", "Früh")).toBe(true); }); test("matches when the query uses the ASCII transliteration of an umlaut", () => { expect(matchesSearchQuery("Frühtracht 2026", "fruehtracht")).toBe(true); }); test("matches when the haystack uses the ASCII transliteration and the query the real umlaut", () => { expect(matchesSearchQuery("kraeftiger Sommerhonig", "kräftig")).toBe(true); }); test("is case-insensitive", () => { expect(matchesSearchQuery("Blütenhonig", "BLUETE")).toBe(true); }); test("requires every word of a multi-word query to match", () => { expect(matchesSearchQuery("kräftiger Sommerhonig aus Altenmünster", "kraeftig honig")).toBe(true); expect(matchesSearchQuery("kräftiger Sommerhonig aus Altenmünster", "kraeftig kerze")).toBe(false); }); test("returns false when no word matches", () => { expect(matchesSearchQuery("Bienenwachskerze", "propolis")).toBe(false); }); test("returns true for an empty query (no filter applied)", () => { expect(matchesSearchQuery("Bienenwachskerze", "")).toBe(true); }); });