103 lines
2.8 KiB
TypeScript
103 lines
2.8 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import {
|
|
canonicalRegistryJson,
|
|
diffRegistrySnapshots,
|
|
registrySnapshotDigest,
|
|
validateBreakingEvidence,
|
|
verifyRegistryBaselineApproval,
|
|
} from "../../scripts/lib/registry-compatibility.mjs";
|
|
|
|
function snapshot(
|
|
rows: Readonly<Record<string, Readonly<Record<string, unknown>>>>,
|
|
) {
|
|
return {
|
|
schemaVersion: 2,
|
|
registries: [
|
|
{
|
|
registryId: "FE-REG-TEST",
|
|
contract: { breakingFields: ["path"] },
|
|
rows,
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
describe("registry compatibility evidence", () => {
|
|
it("canonicalizes object and primitive-array ordering", () => {
|
|
expect(
|
|
canonicalRegistryJson({
|
|
second: ["b", "a"],
|
|
first: { z: 1, a: 2 },
|
|
}),
|
|
).toBe('{"first":{"a":2,"z":1},"second":["a","b"]}');
|
|
});
|
|
|
|
it("classifies additive, behavioral and breaking actual diffs", () => {
|
|
expect(
|
|
diffRegistrySnapshots(
|
|
snapshot({ A: { path: "/a" } }),
|
|
snapshot({ A: { path: "/a" }, B: { path: "/b" } }),
|
|
).impact,
|
|
).toBe("additive");
|
|
expect(
|
|
diffRegistrySnapshots(
|
|
snapshot({ A: { path: "/a", owner: "one" } }),
|
|
snapshot({ A: { path: "/a", owner: "two" } }),
|
|
).impact,
|
|
).toBe("behavior-change");
|
|
expect(
|
|
diffRegistrySnapshots(
|
|
snapshot({ A: { path: "/a" } }),
|
|
snapshot({ A: { path: "/moved" } }),
|
|
).impact,
|
|
).toBe("breaking");
|
|
expect(
|
|
diffRegistrySnapshots(
|
|
snapshot({ A: { path: "/a" } }),
|
|
snapshot({}),
|
|
).impact,
|
|
).toBe("breaking");
|
|
});
|
|
|
|
it("verifies the approved digest and complete breaking evidence", () => {
|
|
const before = snapshot({ A: { path: "/before" } });
|
|
const after = snapshot({ A: { path: "/after" } });
|
|
const digest = registrySnapshotDigest(before);
|
|
expect(
|
|
verifyRegistryBaselineApproval(before, {
|
|
schemaVersion: 1,
|
|
snapshotDigest: digest,
|
|
owner: "platform",
|
|
approvedAt: "2026-07-26T00:00:00.000Z",
|
|
}).passed,
|
|
).toBe(true);
|
|
expect(
|
|
verifyRegistryBaselineApproval(before, {
|
|
schemaVersion: 1,
|
|
snapshotDigest: "tampered",
|
|
owner: "platform",
|
|
approvedAt: "2026-07-26T00:00:00.000Z",
|
|
}).passed,
|
|
).toBe(false);
|
|
|
|
const diff = diffRegistrySnapshots(before, after);
|
|
expect(validateBreakingEvidence(diff, { changes: [] }).passed).toBe(false);
|
|
const changeId = diff.changes[0]?.changeId;
|
|
expect(
|
|
validateBreakingEvidence(diff, {
|
|
changes: [
|
|
{
|
|
changeId,
|
|
versionBump: "2",
|
|
migration: "dual-read",
|
|
compatibilityWindow: "one release",
|
|
rollback: "restore previous registry snapshot",
|
|
owner: "platform",
|
|
},
|
|
],
|
|
}).passed,
|
|
).toBe(true);
|
|
});
|
|
});
|