left4me/l4d2web/scripts/editor-src/vocab-rank.test.js
mwiegand 9ff93164d7
feat(editor): extract pure rankVocab module + tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 17:33:26 +02:00

78 lines
2.3 KiB
JavaScript

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");
});