import { test } from "node:test"; import assert from "node:assert/strict"; import { rankVocab } from "./vocab-rank.js"; const vocab = { cvars: [ { name: "sv_cheats", desc: "Allow cheats" }, { name: "sv_gravity" }, { name: "mp_friendlyfire", desc: "Toggle FF" }, ], commands: [ { name: "kick", desc: "Kick a player" }, { name: "kickall", desc: "Kick everyone" }, { name: "changelevel", desc: "Change map" }, ], }; test("exact match comes first", () => { const out = rankVocab("kick", vocab); assert.equal(out[0].name, "kick"); assert.equal(out[1].name, "kickall"); }); test("prefix matches beat substring matches", () => { const out = rankVocab("sv_", vocab); assert.equal(out[0].name, "sv_cheats"); assert.equal(out[1].name, "sv_gravity"); // mp_friendlyfire contains no "sv_" → should not appear assert.ok(!out.some(e => e.name === "mp_friendlyfire")); }); test("substring matches included after prefix matches", () => { // "iendly" is a substring of mp_friendlyfire but a prefix of nothing const out = rankVocab("iendly", vocab); assert.equal(out.length, 1); assert.equal(out[0].name, "mp_friendlyfire"); }); test("kind is preserved on each result", () => { const out = rankVocab("kick", vocab); assert.equal(out[0].kind, "command"); const sv = rankVocab("sv_cheats", vocab); assert.equal(sv[0].kind, "cvar"); }); test("desc is preserved when present", () => { const out = rankVocab("kick", vocab); assert.equal(out[0].desc, "Kick a player"); }); test("desc is undefined when source had no desc", () => { const out = rankVocab("sv_gravity", vocab); assert.equal(out[0].desc, undefined); }); test("results are capped at the configured limit", () => { const big = { cvars: [], commands: [] }; for (let i = 0; i < 200; i++) big.commands.push({ name: `cmd${i}` }); const out = rankVocab("cmd", big, { limit: 50 }); assert.equal(out.length, 50); }); test("default limit is 50", () => { const big = { cvars: [], commands: [] }; for (let i = 0; i < 200; i++) big.commands.push({ name: `cmd${i}` }); const out = rankVocab("cmd", big); assert.equal(out.length, 50); }); test("empty query returns no results", () => { const out = rankVocab("", vocab); assert.equal(out.length, 0); }); test("case-insensitive match", () => { const out = rankVocab("KICK", vocab); assert.equal(out[0].name, "kick"); });