Files

78 lines
2.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { fuzzy, pieces, rank } from "../src/lib/fuzzy";
describe("fuzzy", () => {
it("matches a subsequence, not just a substring", () => {
expect(fuzzy("wsr", "website redesign")).not.toBeNull();
expect(fuzzy("zzz", "website redesign")).toBeNull();
});
it("is case insensitive and ignores surrounding space in the query", () => {
expect(fuzzy(" WEB ", "website")).not.toBeNull();
});
it("returns every match for an empty query", () => {
expect(fuzzy("", "anything")).toEqual({ score: 0, ranges: [] });
});
it("merges adjacent letters into one range", () => {
expect(fuzzy("web", "website")?.ranges).toEqual([[0, 3]]);
});
it("keeps separate runs apart", () => {
expect(fuzzy("wr", "website redesign")?.ranges).toEqual([
[0, 1],
[8, 9],
]);
});
it("scores a word start above a letter buried mid-word", () => {
const start = fuzzy("r", "website redesign")?.score ?? 0;
const buried = fuzzy("b", "website redesign")?.score ?? 0;
expect(start).toBeGreaterThan(buried);
});
});
describe("rank", () => {
const items = ["web", "website redesign", "errands", "someday"];
const label = (item: string): string => item;
it("keeps the given order when nothing is typed", () => {
expect(rank("", items, label).map((hit) => hit.item)).toEqual(items);
});
it("puts the shorter exact head first", () => {
expect(rank("web", items, label)[0].item).toBe("web");
});
it("drops what does not match at all", () => {
expect(rank("qq", items, label)).toEqual([]);
});
it("breaks ties by the incoming order", () => {
expect(rank("e", ["ea", "eb"], label).map((hit) => hit.item)).toEqual([
"ea",
"eb",
]);
});
});
describe("pieces", () => {
it("splits a label into matched and unmatched runs", () => {
expect(pieces("website", [[0, 3]])).toEqual([
{ text: "web", hit: true },
{ text: "site", hit: false },
]);
});
it("returns the whole label when nothing matched", () => {
expect(pieces("website", [])).toEqual([{ text: "website", hit: false }]);
});
it("rebuilds the original text exactly", () => {
const hit = fuzzy("wr", "website redesign");
const parts = pieces("website redesign", hit?.ranges ?? []);
expect(parts.map((part) => part.text).join("")).toBe("website redesign");
});
});