test.build/core/converters/search.index.converter.test.ts
test.build/core/converters/search.index.converter.test.ts is a file in Codebase Testing. 96 lines of code and 0 definitions.
import { describe, expect, it } from "vitest";
import type { Identity } from "@banes-lab/build-scripts/types/catalog.types.ts";
import { createLinker } from "@banes-lab/build-scripts/core/resolvers/link.resolver.ts";
import { searchLeaves } from "@banes-lab/build-scripts/core/converters/search.index.converter.ts";
import { sectionEntries } from "@banes-lab/build-scripts/core/converters/search.converter.ts";
const SITE = "https://example.test";
const ROW_COUNT = 6000;
const LONG = 80;
const RULES = {
americanWords: {},
fuzzyMinimum: 4,
izeStems: [],
izeSuffixes: {},
pluralIes: ["ies", "y"] as const,
pluralKeptAfter: ["i", "s", "u"],
pluralMinimum: 4,
pluralSuffix: "s",
spellingPrefixes: [],
wordCharacters: "abc",
};
const section = function section(id: string): Identity {
return {
address: { json: `/json/method/${id}`, markdown: `/method/${id}.md` },
href: `/method#${id}`,
kind: "section",
ref: `chapter:/method#${id}`,
summary: null,
title: id,
};
};
const LINKER = createLinker([section("late"), section("early")], SITE, (href) => href);
describe("searchLeaves", () => {
it("names one index per kind, and shards each kind's weighted postings by prefix", () => {
const entries = sectionEntries(
[
{ href: "/method#late", position: 9, words: ["gate", "check"] },
{ href: "/method#early", position: 2, words: ["gate", "gate"] },
],
LINKER,
);
const [head, kind, ...shards] = searchLeaves([{ entries, kind: "sections" }], RULES, LINKER);
expect(head?.identity.address.json).toBe("/json/api/search");
expect(Reflect.get(head?.data ?? {}, "kinds")).toStrictEqual({
sections: { count: 2, json: `${SITE}/json/api/search/sections` },
});
expect(Reflect.get(kind?.data ?? {}, "columns")).toStrictEqual(["ref", "title", "position"]);
expect(Reflect.get(kind?.data ?? {}, "rows")).toStrictEqual([
["chapter:/method#early", "early", 2],
["chapter:/method#late", "late", 9],
]);
expect(Reflect.get(kind?.data ?? {}, "shards")).toStrictEqual({
c: `${SITE}/json/api/search/sections/c`,
g: `${SITE}/json/api/search/sections/g`,
});
const postings = shards.map((shard): readonly unknown[] => {
const held: unknown = Reflect.get(shard.data, "postings");
return [shard.identity.address.json, held];
});
expect(postings).toStrictEqual([
["/json/api/search/sections/c", { check: [[1, 1]] }],
[
"/json/api/search/sections/g",
{
gate: [
[0, 2],
[1, 1],
],
},
],
]);
});
it("moves a kind's rows into numbered parts when its index passes the file budget", () => {
const entries = Array.from({ length: ROW_COUNT }, (_unused, at) => ({
identity: {
address: { json: `/json/x/${String(at)}`, markdown: null },
href: null,
kind: "file",
ref: `anatomy:file-${"x".repeat(LONG)}-${String(at)}`,
summary: null,
title: `${"y".repeat(LONG)}-${String(at)}`,
},
position: null,
words: [`w${String(at)}`],
}));
const [, kind, ...rest] = searchLeaves([{ entries, kind: "files" }], RULES, LINKER);
const parts: unknown = Reflect.get(kind?.data ?? {}, "parts");
expect(Reflect.get(kind?.data ?? {}, "rows")).toStrictEqual([]);
expect(Array.isArray(parts) && parts.length > 1).toBe(true);
const partLeaves = rest.filter((leaf) => leaf.identity.address.json.includes("/files/_"));
const rows = partLeaves.flatMap((leaf): unknown[] => {
const held: unknown = Reflect.get(leaf.data, "rows");
return Array.isArray(held) ? held : [];
});
expect(rows).toHaveLength(ROW_COUNT);
});
});