spb/khaelor Public
KHAELOR — a terminal-native autonomous engineering agent powered by Anthropic.
TypeScript 82.9%
HTML 14.9%
CSS 1.1%
JavaScript 0.7%
1/**2 * KHAELOR3 * File: tests/tui/fuzzy.test.ts4 * Description: Fuzzy matcher tests — subsequence matching, ranking bonuses, stability, matched indices.5 *6 * Author: Simon-Pierre Boucher7 * Contact: contact@spboucher.ai8 */910import { describe, expect, it } from "vitest";11import { fuzzyFilter, fuzzyMatch } from "../../src/tui/composer/fuzzy.js";1213describe("fuzzyMatch", () => {14 it("matches subsequences case-insensitively", () => {15 expect(fuzzyMatch("agt", "src/kernel/Agent.ts")).not.toBeNull();16 expect(fuzzyMatch("zzz", "src/kernel/agent.ts")).toBeNull();17 });1819 it("returns matched indices for underlining", () => {20 const m = fuzzyMatch("se", "sessions");21 expect(m?.indices).toEqual([0, 1]);22 });2324 it("empty query matches everything with score 0", () => {25 expect(fuzzyMatch("", "anything")).toEqual({ score: 0, indices: [] });26 });2728 it("exact prefix outranks a scattered match", () => {29 const prefix = fuzzyMatch("diff", "diff viewer") as { score: number };30 const scattered = fuzzyMatch("diff", "docs/if_frame.ts") as { score: number };31 expect(prefix.score).toBeGreaterThan(scattered.score);32 });3334 it("boundary matches outrank mid-word matches", () => {35 const boundary = fuzzyMatch("ag", "src/agent.ts") as { score: number };36 const midWord = fuzzyMatch("ag", "src/flagpole.ts") as { score: number };37 expect(boundary.score).toBeGreaterThan(midWord.score);38 });39});4041describe("fuzzyFilter", () => {42 const items = ["src/kernel/agent.ts", "src/agents/agent-runtime.ts", "tests/agent.test.ts"];4344 it("excludes non-matches and ranks by score", () => {45 const ranked = fuzzyFilter("agent", items, (s) => s);46 expect(ranked.length).toBe(3);47 expect(ranked.every((r) => r.score > 0)).toBe(true);48 });4950 it("shorter target wins ties (length penalty)", () => {51 const ranked = fuzzyFilter("cost", ["/cost-explorer", "/cost"], (s) => s);52 expect(ranked[0]?.item).toBe("/cost");53 });5455 it("keeps provider order for equal scores (stable)", () => {56 const ranked = fuzzyFilter("", items, (s) => s);57 expect(ranked.map((r) => r.item)).toEqual(items);58 });5960 it("filters slash commands by fragment", () => {61 const cmds = ["/sessions", "/new", "/resume", "/cost"];62 const ranked = fuzzyFilter("se", cmds, (s) => s);63 expect(ranked.map((r) => r.item)).toContain("/sessions");64 expect(ranked.map((r) => r.item)).not.toContain("/cost");65 });66});67