test.content/core/converters/invariant.converter.test.ts

test.content/core/converters/invariant.converter.test.ts is a file in Codebase Testing. 65 lines of code and 0 definitions.

import { describe, expect, it } from "vitest";
import { invariantsOf, modelSeeds, slotWordsOf } from "@banes-lab/content/core/converters/invariant.converter.ts";

const TEMPLATE = [
    "**THE SLOTS, AND OMITTING ANY ONE LEAVES IT UNSTATED:** the PROPERTY in a form that could be false, since",
    "a statement nothing could contradict states nothing; the SET it quantifies over; and the PARTIES it binds.",
    "",
    "## Gate",
    "",
    "- An invariant stated with no objector fails unless it declares itself unheld.",
].join("\n");

const PARAGRAPH_MODEL = [
    "## The invariants",
    "",
    "### A declared lifetime is READ",
    "",
    "**PROPERTY** — every decision resolves from the declared lifetime, and never from",
    "the shape of its path. **SET** — every mechanism that scans. **PARTIES** — every author. **OBJECTOR** — a check comparing each",
    "operand against the declaration.",
    "",
    "### Prose only",
    "",
    "A section with no slots.",
].join("\n");

const BULLET_MODEL = [
    "## Invariant — the count is derived",
    "",
    "- **Property.** The count follows from the partition.",
    "- **Set.** Every allocation decision.",
    "- **Parties.** Whoever proposes a count.",
    "- **Its objector, named because the template forbids a statement nothing can contradict.** The partition is derived from a relation.",
].join("\n");

const WORDS = { objector: "objector", parties: "parties", property: "property", set: "set" };

describe("slotWordsOf", () => {
    it("takes three slot words from the slots sentence and the objector from the gate bullet", () => {
        expect(slotWordsOf(TEMPLATE)).toStrictEqual(WORDS);
    });

    it("returns null when the template names no slots", () => {
        expect(slotWordsOf("## Gate\n- nothing here")).toBeNull();
    });
});

describe("invariantsOf", () => {
    it("reads the bold-paragraph shape across wrapped lines and skips a block with no slots", () => {
        const found = invariantsOf(PARAGRAPH_MODEL, WORDS);
        expect(found).toHaveLength(1);
        expect(found[0]?.heading).toBe("A declared lifetime is READ");
        expect(found[0]?.property).toBe(
            "every decision resolves from the declared lifetime, and never from the shape of its path.",
        );
        expect(found[0]?.objector).toBe("a check comparing each operand against the declaration.");
    });

    it("reads the bulleted shape with a long objector label", () => {
        const found = invariantsOf(BULLET_MODEL, WORDS);
        expect(found).toHaveLength(1);
        expect(found[0]?.property).toBe("The count follows from the partition.");
        expect(found[0]?.objector).toBe("The partition is derived from a relation.");
    });
});

describe("modelSeeds", () => {
    it("names each seed by the model stem and the heading slug", () => {
        const seeds = modelSeeds([{ path: "surface/models/coupling.model.md", text: BULLET_MODEL }], WORDS);
        expect(seeds).toHaveLength(1);
        expect(seeds[0]?.id).toBe("coupling.invariant-the-count-is-derived");
        expect(seeds[0]?.source).toBe("model");
    });
});