/*
Unit tests for mission git commit covering mission-git-commit. It also guards the documented public contract and regression-sensitive edge cases.
- Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only.
- RFC-1311: Compass header sweep — declares the mission suite's contract for test-file scaffold coverage.
*/
import { test, expect, describe } from "vitest";
import * as mod from "../mission-git-commit.ts";
describe("mission-git-commit", () => {
test("module loads successfully", () => {
expect(mod).toBeDefined();
});
test("exports runPreCommitValidation", () => {
expect(typeof mod.runPreCommitValidation).toBe("function");
});
test("exports commitWorkpieceIfDirty", () => {
expect(typeof mod.commitWorkpieceIfDirty).toBe("function");
});
test("exports VALIDATOR_MAPPINGS", () => {
expect(Array.isArray(mod.VALIDATOR_MAPPINGS)).toBe(true);
});
test("VALIDATOR_MAPPINGS includes pbp.content.validate", () => {
const mapping = mod.VALIDATOR_MAPPINGS.find((m) => m.validator === "pbp.content.validate");
expect(mapping).toBeDefined();
expect(mapping!.prefix).toBe("src/content/business-profile/");
});
test("VALIDATOR_MAPPINGS includes typography.validate with scoped: true (RFC-1068)", () => {
const mapping = mod.VALIDATOR_MAPPINGS.find((m) => m.validator === "typography.validate");
expect(mapping).toBeDefined();
expect(mapping!.prefix).toBe("src/content/");
expect(mapping!.scoped).toBe(true);
});
test("selectValidators picks typography.validate for src/content/ files", () => {
const validators = mod.selectValidators([
"src/content/pages/de/index.md",
"src/content/business-profile/uk/offerings/x.md",
]);
expect(validators).toContain("typography.validate");
});
test("selectValidators does not pick typography.validate for non-content files", () => {
const validators = mod.selectValidators(["packages/werkstatt-site/src/checks/typography.ts"]);
expect(validators).not.toContain("typography.validate");
});
test("selectValidators picks both pbp.content.validate and typography.validate for business-profile files", () => {
const validators = mod.selectValidators([
"src/content/business-profile/de/products/booking.md",
]);
expect(validators).toContain("pbp.content.validate");
expect(validators).toContain("typography.validate");
});
// RFC-1160
test("VALIDATOR_MAPPINGS maps pages+system.md to page.block.validate with mixed scope", () => {
const pages = mod.VALIDATOR_MAPPINGS.find(
(m) => m.validator === "page.block.validate" && m.prefix === "src/content/pages/",
);
const system = mod.VALIDATOR_MAPPINGS.find(
(m) => m.validator === "page.block.validate" && m.prefix === "src/content/system.md",
);
expect(pages?.scoped).toBe(true);
expect(system?.scoped).not.toBe(true);
});
test("VALIDATOR_MAPPINGS maps src/content/ to image.variants.validate scoped", () => {
const mapping = mod.VALIDATOR_MAPPINGS.find((m) => m.validator === "image.variants.validate");
expect(mapping?.prefix).toBe("src/content/");
expect(mapping?.scoped).toBe(true);
});
test("selectValidators picks page.block.validate for pages and system.md files", () => {
const validators = mod.selectValidators([
"src/content/pages/de/agb.md",
"src/content/system.md",
]);
expect(validators).toContain("page.block.validate");
});
test("selectValidators picks image.variants.validate for content asset files", () => {
const validators = mod.selectValidators(["src/content/pages/de/assets/hero.webp"]);
expect(validators).toContain("image.variants.validate");
});
// RFC-1185
test("VALIDATOR_MAPPINGS maps pages+system.md to shared.context.validate unscoped", () => {
const mappings = mod.VALIDATOR_MAPPINGS.filter(
(m) => m.validator === "shared.context.validate",
);
expect(mappings.map((m) => m.prefix).sort()).toEqual([
"src/content/pages/",
"src/content/system.md",
]);
expect(mappings.every((m) => m.scoped !== true)).toBe(true);
});
test("selectValidators picks shared.context.validate for pages and system.md files", () => {
const validators = mod.selectValidators([
"src/content/pages/de/agb.md",
"src/content/system.md",
]);
expect(validators).toContain("shared.context.validate");
});
// RFC-1204
test("VALIDATOR_MAPPINGS maps pages+prose to effects.contract.validate unscoped", () => {
const mappings = mod.VALIDATOR_MAPPINGS.filter(
(m) => m.validator === "effects.contract.validate",
);
expect(mappings.map((m) => m.prefix).sort()).toEqual([
"src/content/pages/",
"src/content/prose/",
]);
// Parity is cross-page/cross-locale — never scoped to the staged files.
expect(mappings.every((m) => m.scoped !== true)).toBe(true);
});
test("selectValidators picks effects.contract.validate for page files (AC-6)", () => {
const validators = mod.selectValidators(["src/content/pages/uk/kontakt.md"]);
expect(validators).toContain("effects.contract.validate");
});
});