test.govlab/quality/core/converters/canon.converter.test.ts
test.govlab/quality/core/converters/canon.converter.test.ts is a file in Codebase Testing. 86 lines of code and 0 definitions.
import {
canonicalizeId,
canonicalizeKind,
isCanonicalId,
isCanonicalKind,
} from "@govlab/quality/core/converters/canon.converter.ts";
import { describe, expect, it } from "vitest";
import { KIND_SET } from "@govlab/quality/configuration/constants/canon.constants.ts";
import { loadKindMap } from "@govlab/quality/core/loaders/kind.loader.ts";
const KIND_COUNT = 14;
const ARCH_TYPE_COUNT = 165;
describe("canonicalizeId — SOLID/DRY family + de-abbreviation", () => {
it("folds every SRP spelling to one id", () => {
expect(canonicalizeId("SRP")).toBe("single-responsibility");
expect(canonicalizeId("Single Responsibility Principle (SRP)")).toBe("single-responsibility");
expect(canonicalizeId("Single Responsibility")).toBe("single-responsibility");
});
it("maps the rest of the SOLID set", () => {
expect(canonicalizeId("Open/Closed Principle (OCP)")).toBe("open-closed");
expect(canonicalizeId("OCP")).toBe("open-closed");
expect(canonicalizeId("Interface Segregation Principle (ISP)")).toBe("interface-segregation");
expect(canonicalizeId("Dependency Inversion Principle (DIP)")).toBe("dependency-inversion");
});
it("merges Behavioral Subtyping into liskov-substitution", () => {
expect(canonicalizeId("Liskov Substitution Principle (LSP)")).toBe("liskov-substitution");
expect(canonicalizeId("Behavioral Subtyping")).toBe("liskov-substitution");
});
it("maps DRY to the quality concept duplicate-code", () => {
expect(canonicalizeId("Do Not Repeat Yourself (DRY)")).toBe("duplicate-code");
expect(canonicalizeId("DRY")).toBe("duplicate-code");
});
it("keeps SRP and SoC distinct", () => {
expect(canonicalizeId("Separation of Concerns")).toBe("separation-of-concerns");
expect(canonicalizeId("SRP")).not.toBe(canonicalizeId("SoC"));
});
it("de-abbreviates non-SOLID parentheticals to the descriptive name", () => {
expect(canonicalizeId("Architecture Decision Records (ADR)")).toBe("architecture-decision-records");
expect(canonicalizeId("Domain-Driven Design (DDD)")).toBe("domain-driven-design");
expect(canonicalizeId("RBAC")).toBe("role-based-access-control");
});
});
describe("canonicalizeId — default slugify + idempotency", () => {
it("leaves an existing kebab concept id unchanged", () => {
expect(canonicalizeId("type-safety")).toBe("type-safety");
expect(canonicalizeId("separation-of-concerns")).toBe("separation-of-concerns");
});
it("slugifies a plain arch Title-Case name", () => {
expect(canonicalizeId("Self-Describing Architecture")).toBe("self-describing-architecture");
expect(canonicalizeId("Ports and Adapters Architecture")).toBe("ports-and-adapters-architecture");
});
it("is idempotent", () => {
for (const term of ["SRP", "Do Not Repeat Yourself (DRY)", "type-safety", "Contract-First Design"]) {
const once = canonicalizeId(term);
expect(canonicalizeId(once)).toBe(once);
}
});
it("treats the canonical form as a no-op", () => {
expect(isCanonicalId("single-responsibility")).toBe(true);
expect(isCanonicalId("SRP")).toBe(false);
expect(isCanonicalId("Single Responsibility Principle (SRP)")).toBe(false);
});
});
describe("canonicalizeKind — every arch type to one kind", () => {
it("collapses the principle spellings", () => {
expect(canonicalizeKind("Principle")).toBe("principle");
expect(canonicalizeKind("Architecture Principle")).toBe("principle");
expect(canonicalizeKind("Security Principle")).toBe("principle");
});
it("applies the ratified overrides", () => {
expect(canonicalizeKind("Transaction Property")).toBe("constraint");
expect(canonicalizeKind("Analysis Tool")).toBe("technique");
expect(canonicalizeKind("Language Property")).toBe("quality-attribute");
});
it("returns null for an unknown type", () => {
expect(canonicalizeKind("Totally Made Up Type")).toBeNull();
});
it("has a closed kind set and every mapped kind is in it", () => {
expect(KIND_SET).toHaveLength(KIND_COUNT);
for (const kind of loadKindMap().values()) {
expect(isCanonicalKind(kind)).toBe(true);
}
});
it("covers every distinct arch type value", () => {
expect(loadKindMap().size).toBe(ARCH_TYPE_COUNT);
});
});