import { describe, expect, it } from "vitest"; import { findingSchema, governanceVerdictSchema, normalizeSeverity, normalizeViolation, suppressionDirectiveSchema, validatorResultSchema, } from "./index.js"; import { makeFinding } from "../rules/finding.js"; describe("canonical TypeStyle schemas", () => { it("validates a canonical finding with derived level", () => { const finding = findingSchema.parse({ ruleId: "tokens/require-design-tokens", ruleVersion: "1.0.0", severity: "moderate", level: "warn", code: "FUI2001", helpUrl: "https://usefragments.com/errors/FUI2001", message: "Use a design token.", fingerprint: "abc123", location: { file: "src/button.tsx", line: 4, column: 12 }, evidence: [ { factId: "fact:1", fact: { kind: "style_declaration", location: { file: "src/button.tsx", line: 4, column: 12 }, }, }, ], }); expect(finding.severity).toBe("moderate"); expect(finding.level).toBe("warn"); }); it("normalizes legacy severity levels at compatibility boundaries", () => { expect(normalizeSeverity("error")).toBe("serious"); expect(normalizeSeverity("warning")).toBe("moderate"); expect(normalizeSeverity("info")).toBe("minor"); expect( normalizeViolation({ nodeId: "node-1", nodeType: "Button", rule: "components/allow", severity: "serious", message: "Use an allowed component.", }).level ).toBe("error"); }); it("validates verdict and suppression contracts", () => { expect(() => governanceVerdictSchema.parse({ passed: true, score: 100, results: [], metadata: { runner: "cli", duration: 10, nodeCount: 1, componentTypes: ["Button"], }, }) ).not.toThrow(); expect(() => suppressionDirectiveSchema.parse({ ruleId: "tokens/require-design-tokens", reason: "Legacy file scheduled for removal.", expiresAt: "2026-08-01T00:00:00.000Z", scope: "line", code: "FUI2001", }) ).not.toThrow(); }); it("allows validator results to bridge legacy violations and canonical findings", () => { const finding = makeFinding({ ruleId: "safety/block-event-handlers", ruleVersion: "1.0.0", severity: "serious", message: "Event handlers are blocked.", location: { file: "", line: 0, column: 0 }, evidence: [ { factId: "ui-spec:safety:block-event-handlers:button-1:onClick", fact: { kind: "ui_spec_violation", location: { file: "", line: 0, column: 0 }, }, }, ], fingerprintIdentity: { nodeId: "button-1", prop: "onClick", }, }); expect(finding.code).toBe("FUI8001"); expect(finding.helpUrl).toBe("https://usefragments.com/errors/FUI8001"); expect(() => validatorResultSchema.parse({ validator: "safety", severity: "serious", passed: false, violations: [ { nodeId: "button-1", nodeType: "Button", rule: "safety/block-event-handlers", severity: "serious", code: "FUI8001", message: "Event handlers are blocked.", }, ], findings: [finding], }) ).not.toThrow(); }); });