test.govlab/context/core/validators/ontology.validator.test.ts
test.govlab/context/core/validators/ontology.validator.test.ts is a file in Codebase Testing. 154 lines of code and 0 definitions.
import { ARCH_FACE, LEX_FACE } from "@govlab/constants";
import { PLANTED_GATE, PLANTED_ID, plantedFaces, plantedPrinciple } from "./ontology.fixture.ts";
import { checkGapsFor, runValidation } from "@govlab/context/core/validators/ontology.validator.ts";
import type { TermCategory } from "@govlab/context/types/lexicon.types.ts";
import assert from "node:assert/strict";
import { createGovlabContext } from "@govlab/context";
import { test } from "vitest";
const ANSWERED_CHECK = {
freshness: "a verdict stands until the planted module changes",
observation: "none: the planted rule is decided on source",
population: "every planted module",
refusal: "the planted gate fails the lint run",
};
const archGapsWith = (check: object): { collection: string; id: string; missing: string[] }[] =>
checkGapsFor(
plantedFaces([plantedPrinciple(PLANTED_ID, { check, enforced_by: PLANTED_GATE })], []),
).uncheckedRecords.filter((entry) => entry.collection === ARCH_FACE);
test("every bundled record has a reachable check and every check ref resolves", () => {
const context = createGovlabContext();
const gaps = context.checkGaps();
assert.deepEqual(gaps.uncheckedRecords, []);
assert.deepEqual(gaps.unresolvedCheckRefs, []);
assert.deepEqual(gaps.secondCheckHomes, []);
assert.deepEqual(gaps.uncoveredCollections, []);
const arch = gaps.collections.find((coverage) => coverage.collection === ARCH_FACE);
assert.equal(arch?.records, context.arch.all().length);
});
test("a principle with no enforcing check and no facet is reported unchecked", () => {
const gaps = checkGapsFor(plantedFaces([plantedPrinciple(PLANTED_ID)], []));
assert.deepEqual(
gaps.uncheckedRecords.filter((entry) => entry.collection === ARCH_FACE),
[
{
collection: ARCH_FACE,
id: PLANTED_ID,
missing: ["by", "population", "freshness", "refusal", "observation", "evidence", "authority"],
},
],
);
});
test("an evidence answer with no known sign, or with nothing after its sign, is reported, and so is a missing authority", () => {
assert.deepEqual(archGapsWith({ ...ANSWERED_CHECK, evidence: "probably: it looked fine" }), [
{ collection: ARCH_FACE, id: PLANTED_ID, missing: ["evidence", "authority"] },
]);
assert.deepEqual(archGapsWith({ ...ANSWERED_CHECK, authority: "the declared rule", evidence: "fires:" }), [
{ collection: ARCH_FACE, id: PLANTED_ID, missing: ["evidence"] },
]);
for (const evidence of [
"fires: a planted violation",
"fires-and-accepts: a planted violation and a conforming case",
"contradicted: a planted violation the gate passed",
"none: nothing has watched the planted gate",
]) {
assert.deepEqual(archGapsWith({ ...ANSWERED_CHECK, authority: "the declared rule", evidence }), [], evidence);
}
});
test("a term takes its check from the edges that name it and is reported when none does", () => {
const terms: TermCategory[] = [
{
category: "planted",
records: [
{ definition: "A rule or precondition named by an edge.", kind: "constraint", name: "Named Term" },
{ definition: "A rule or precondition nothing names.", kind: "constraint", name: "Orphan Term" },
],
},
];
const gaps = checkGapsFor(
plantedFaces([plantedPrinciple(PLANTED_ID, { enforced_by: PLANTED_GATE, requires: ["Named Term"] })], terms),
);
const lexicon = gaps.uncheckedRecords.filter((entry) => entry.collection === LEX_FACE);
assert.deepEqual(lexicon, [{ collection: LEX_FACE, id: "orphan-term", missing: ["by"] }]);
assert.deepEqual(gaps.unresolvedCheckRefs, []);
});
test("a check or dependency ref that resolves to no record is reported, and a second check home too", () => {
const terms: TermCategory[] = [
{
category: "planted",
records: [
{
definition: "A rule or precondition with a dangling dependency.",
kind: "constraint",
name: "Named Term",
seeAlso: ["ghost-term"],
},
],
},
];
const principle = plantedPrinciple(PLANTED_ID, {
check: { by: ["a second home"] },
enforced_by: ["architecture:ghost-rule"],
requires: ["Named Term"],
});
const gaps = checkGapsFor(plantedFaces([principle], terms));
assert.deepEqual(gaps.unresolvedCheckRefs, [
{ collection: ARCH_FACE, field: "by", id: PLANTED_ID, ref: "architecture:ghost-rule" },
{ collection: LEX_FACE, field: "dependsOn", id: "named-term", ref: "lexicon:ghost-term" },
]);
assert.deepEqual(gaps.secondCheckHomes, [{ collection: ARCH_FACE, home: "check.by", id: PLANTED_ID }]);
});
test("a severity outside the closed levels fails at load, and mandatoryFor beside any level but contextual is reported", () => {
assert.throws(
() => plantedFaces([plantedPrinciple("loud-rule", { severity: "high" })], []),
(error: unknown) => error instanceof Error && error.message.includes('declares "high"'),
);
const issues = runValidation(
plantedFaces([plantedPrinciple("gated-rule", { mandatoryFor: "production", severity: "mandatory" })], []),
);
assert.deepEqual(
issues.invalidSeverities.map((entry) => entry.id),
["gated-rule"],
);
});
test("a required field left blank is reported, and none with a reason passes", () => {
const issues = runValidation(
plantedFaces(
[
plantedPrinciple("blank-rule", { definition: "", enforced_by: PLANTED_GATE }),
plantedPrinciple("absent-rule", {
enforced_by: PLANTED_GATE,
measured_by: ["none: nothing is counted"],
}),
],
[],
),
);
const planted = issues.emptyRequiredFields.filter((entry) => entry.collection === ARCH_FACE);
assert.deepEqual(planted, [{ collection: ARCH_FACE, field: "definition", id: "blank-rule" }]);
});
test("a principle whose definition opens as another kind is reported", () => {
const issues = runValidation(
plantedFaces([plantedPrinciple("mixed-rule", { definition: "A defect in which the rule is planted." })], []),
);
assert.deepEqual(issues.kindConsistencyViolations, [
{ declaredKind: "principle", id: "mixed-rule", opening: "a defect in which", signalsKind: "anti-pattern" },
]);
});
test("a tension between two principles no layer places is unresolved, and the bundled tensions resolve", () => {
const bundledIssues = createGovlabContext().validateResolution();
assert.deepEqual(bundledIssues.unresolvedTensions, []);
assert.deepEqual(bundledIssues.deadResolutionSeeds, []);
const issues = runValidation(
plantedFaces(
[
plantedPrinciple("speed-rule", { enforced_by: PLANTED_GATE, tensions_with: ["care-rule"] }),
plantedPrinciple("care-rule", { enforced_by: PLANTED_GATE }),
],
[],
),
);
assert.deepEqual(
issues.unresolvedTensions.map((gap) => [gap.from, gap.target]),
[["speed-rule", "care-rule"]],
);
});