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