test.web/configuration/constants/graph.constants.test.ts

test.web/configuration/constants/graph.constants.test.ts is a file in Codebase Testing. 92 lines of code and 0 definitions.

import {
    BUILDS_ON_RELATION,
    CALLS_RELATION_ID,
    CONCEPT_RELATION,
    CONCERN_LAYER_RELATION,
    CONCERN_RELATION,
    CONTAINED_IN_RELATION,
    CONTAINS_RELATION,
    DETECTED_BY_RELATION,
    ENFORCED_BY_RELATION,
    EVIDENCE_FOR_RELATION,
    GOVERNED_BY_RELATION,
    LEAF_RELATIONS,
    LINKS_TO_RELATION,
    REFERENCES_RELATION,
    RELATIONS,
    RELATION_PAIRS,
    ROLLED_UP_RELATIONS,
    TOOLTIP_RELATIONS,
    USES_RELATION,
    isListingRef,
    relationId,
    reverseOf,
} from "@banes-lab/web/configuration/constants/graph.constants.ts";
import { describe, expect, it } from "vitest";

const KEBAB = "abcdefghijklmnopqrstuvwxyz-";
const CONFLICTS_WITH = "conflicts-with";

const isKebab = function isKebab(name: string): boolean {
    for (const character of name) {
        if (!KEBAB.includes(character)) {
            return false;
        }
    }
    return true;
};

describe("the relation vocabulary", () => {
    it("declares each forward relation once, so every forward has exactly one reverse", () => {
        const forwards = RELATION_PAIRS.map((pair) => pair.forward);
        expect(new Set(forwards).size).toBe(forwards.length);
    });

    it("spells every relation in kebab case", () => {
        const names = RELATION_PAIRS.flatMap((pair) => [pair.forward, pair.reverse]);
        expect(names.filter((name) => !isKebab(name))).toStrictEqual([]);
    });

    it("reads the snake and camel spellings govlab uses as the declared kebab id", () => {
        expect(relationId("conflicts_with")).toBe(CONFLICTS_WITH);
        expect(relationId("conflictsWith")).toBe(CONFLICTS_WITH);
        expect(relationId(CONFLICTS_WITH)).toBe(CONFLICTS_WITH);
        expect(reverseOf(relationId("tensionsWith"))).toBe("tensions-with");
    });

    it("gives no reverse to a relation the vocabulary does not declare", () => {
        expect(reverseOf("undeclared")).toBeNull();
    });

    it("pairs the site relations the graph builder emits with their own reverses", () => {
        expect(reverseOf(LINKS_TO_RELATION)).toBe("linked-from");
        expect(reverseOf(CALLS_RELATION_ID)).toBe("called-by");
        expect(reverseOf(CONTAINS_RELATION)).toBe(CONTAINED_IN_RELATION);
        expect(reverseOf(BUILDS_ON_RELATION)).toBe("prerequisite-of");
    });

    it("gives each principle relation a reverse of its own rather than one shared name", () => {
        expect(reverseOf("requires")).toBe("required-by");
        expect(reverseOf("reinforces")).toBe("reinforced-by");
        expect(reverseOf("enables")).toBe("enabled-by");
        expect(reverseOf(CONFLICTS_WITH)).toBe("negated-by");
    });

    it("derives the pairs, the tooltip set, the roll-ups and the leaf relations from one relation record", () => {
        expect(RELATION_PAIRS).toHaveLength(RELATIONS.length);
        expect(TOOLTIP_RELATIONS.has(LINKS_TO_RELATION) && TOOLTIP_RELATIONS.has(EVIDENCE_FOR_RELATION)).toBe(true);
        expect([...ROLLED_UP_RELATIONS]).toStrictEqual([
            EVIDENCE_FOR_RELATION,
            "referenced-from",
            "governs",
            "concern-of",
            "concern-layer-of",
        ]);
        expect(LEAF_RELATIONS.map((relation) => relation.forward)).toContain(USES_RELATION);
    });

    it("pairs the relations the graph producers emit with their reverses", () => {
        expect(reverseOf(REFERENCES_RELATION)).toBe("referenced-from");
        expect(reverseOf(ENFORCED_BY_RELATION)).toBe("enforces");
        expect(reverseOf(DETECTED_BY_RELATION)).toBe("detects");
        expect(reverseOf(GOVERNED_BY_RELATION)).toBe("governs");
        expect(reverseOf(CONCEPT_RELATION)).toBe("concept-of");
        expect(reverseOf(CONCERN_RELATION)).toBe("concern-of");
        expect(reverseOf(CONCERN_LAYER_RELATION)).toBe("concern-layer-of");
    });

    it("treats only the listing page's sections as listing sources", () => {
        expect(isListingRef("chapter:/ontology#principles")).toBe(true);
        expect(isListingRef("chapter:/pag#setup")).toBe(false);
        expect(isListingRef("architecture:x")).toBe(false);
    });
});