mirror of
https://github.com/polygonhunter/searchosaurus.git
synced 2026-07-22 08:30:27 +00:00
Ranking now layers deterministic tiers over BM25: exact title/alias matches pin to the top, prefix and in-order word-prefix matches second, score third — a person's own note beats any number of mentions (covered by an acid test against a real engine). Query grammar: leading n/f/d/i/l type operators (title-focused search), #tag, -exclusion, "exact phrase" (verified verbatim on candidates), p:/path:/pfad: prefixes, and mod: recency filters in German and English. External URLs found in notes become their own link docs (searchable by text and URL, opening jumps to the line, mod-enter opens the browser). The modal gains a quiet filter-icon row with a date-sort toggle and lazily rendered highlighted snippets. Docs and fixtures use only fictional examples (Mira Holt); authorship strings follow the Linkosaurus convention (polygonhunter), and the icon joins the family style: blue tile, white raptor, coral magnifier. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
47 lines
1.2 KiB
TypeScript
47 lines
1.2 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { fold, foldedWords, processTerm } from "../src/core/normalize";
|
|
|
|
describe("fold", () => {
|
|
it("lowercases and trims", () => {
|
|
expect(fold(" Mira Holt ")).toBe("mira holt");
|
|
});
|
|
|
|
it("folds German umlauts and ß", () => {
|
|
expect(fold("Müller")).toBe("muller");
|
|
expect(fold("Straße")).toBe("strasse");
|
|
expect(fold("Ärger Öl Übung")).toBe("arger ol ubung");
|
|
});
|
|
|
|
it("folds other diacritics", () => {
|
|
expect(fold("Café Zoë")).toBe("cafe zoe");
|
|
});
|
|
|
|
it("strips punctuation but keeps digits", () => {
|
|
expect(fold("Meeting (2026-07-16)!")).toBe("meeting 2026 07 16");
|
|
});
|
|
|
|
it("collapses whitespace", () => {
|
|
expect(fold("a\t b\n c")).toBe("a b c");
|
|
});
|
|
});
|
|
|
|
describe("processTerm", () => {
|
|
it("returns folded terms", () => {
|
|
expect(processTerm("Müller")).toBe("muller");
|
|
});
|
|
|
|
it("drops terms that fold to nothing", () => {
|
|
expect(processTerm("!!!")).toBeNull();
|
|
expect(processTerm("")).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("foldedWords", () => {
|
|
it("splits folded text into words", () => {
|
|
expect(foldedWords("Mira Holt")).toEqual(["mira", "holt"]);
|
|
});
|
|
|
|
it("returns [] for empty/punctuation-only input", () => {
|
|
expect(foldedWords(" … ")).toEqual([]);
|
|
});
|
|
});
|