Files
ST-Bionic-Memory-Ecology/tests/graph-snapshot-schema.mjs

80 lines
3.9 KiB
JavaScript

// ST-BME restrained rebirth — durable graph snapshot schema contract tests.
//
// Locks the forward-compatibility discipline: frozen top-level keys, explicit
// schemaVersion, tolerant parsing (unknown nested fields preserved), and that
// the real durable buildSnapshotFromGraph path stamps the top-level version.
import assert from "node:assert/strict";
import {
GRAPH_SNAPSHOT_SCHEMA_VERSION,
GRAPH_SNAPSHOT_TOP_LEVEL_KEYS,
findUnknownTopLevelSnapshotKeys,
inspectGraphSnapshotContract,
normalizeGraphSnapshotShape,
readGraphSnapshotSchemaVersion,
} from "../sync/graph-snapshot-schema.js";
import {
BME_DB_SCHEMA_VERSION,
buildSnapshotFromGraph,
} from "../sync/bme-db.js";
import { createEmptyGraph } from "../graph/graph.js";
// 1. Top-level key set is frozen and matches the durable contract.
assert.deepEqual(
[...GRAPH_SNAPSHOT_TOP_LEVEL_KEYS].sort(),
["edges", "meta", "nodes", "schemaVersion", "state", "tombstones"],
);
assert.throws(() => {
"use strict";
GRAPH_SNAPSHOT_TOP_LEVEL_KEYS.push("rogue");
});
console.log(" ✓ durable snapshot top-level key set is frozen");
// 2. Tolerant parse preserves unknown nested fields, drops unknown top-level.
const dirty = {
schemaVersion: 1,
meta: { schemaVersion: 1, chatId: "chat-a", futureMetaField: { a: 1 } },
nodes: [{ id: "n1", type: "char", futureNodeField: "keep-me" }],
edges: [{ id: "e1", fromId: "n1", toId: "n2", futureEdgeField: 7 }],
tombstones: [{ id: "t1", kind: "node", futureTombField: true }],
state: { lastProcessedFloor: 3, futureStateField: "keep" },
rogueTopLevel: "should-be-dropped",
};
const normalized = normalizeGraphSnapshotShape(dirty);
assert.deepEqual(findUnknownTopLevelSnapshotKeys(dirty), ["rogueTopLevel"]);
assert.equal("rogueTopLevel" in normalized, false, "unknown top-level dropped");
assert.equal(normalized.nodes[0].futureNodeField, "keep-me", "unknown node field preserved");
assert.equal(normalized.edges[0].futureEdgeField, 7, "unknown edge field preserved");
assert.equal(normalized.tombstones[0].futureTombField, true, "unknown tombstone field preserved");
assert.equal(normalized.meta.futureMetaField.a, 1, "unknown meta field preserved");
assert.equal(normalized.state.futureStateField, "keep", "unknown state field preserved");
console.log(" ✓ tolerant parse preserves unknown nested fields, drops unknown top-level");
// 3. Malformed input never throws; returns an empty valid snapshot.
for (const bad of [null, undefined, 42, "x", [], true]) {
const safe = normalizeGraphSnapshotShape(bad);
const inspection = inspectGraphSnapshotContract(safe);
assert.equal(inspection.valid, true, "normalized malformed input is contract-valid");
assert.equal(safe.schemaVersion, GRAPH_SNAPSHOT_SCHEMA_VERSION);
}
console.log(" ✓ malformed input normalizes to an empty valid snapshot without throwing");
// 4. schemaVersion is read from top-level first, then meta fallback.
assert.equal(readGraphSnapshotSchemaVersion({ schemaVersion: 3, meta: { schemaVersion: 1 } }), 3);
assert.equal(readGraphSnapshotSchemaVersion({ meta: { schemaVersion: 2 } }), 2);
assert.equal(readGraphSnapshotSchemaVersion({}), 0);
console.log(" ✓ schemaVersion resolves from top-level then meta fallback");
// 5. The REAL durable path stamps an explicit top-level schemaVersion.
const graph = createEmptyGraph();
const durable = buildSnapshotFromGraph(graph, { chatId: "chat-real" });
const durableInspection = inspectGraphSnapshotContract(durable);
assert.equal(durableInspection.valid, true, "durable snapshot matches frozen contract");
assert.equal(durable.schemaVersion, BME_DB_SCHEMA_VERSION, "durable snapshot has top-level schemaVersion");
assert.equal(durable.meta.schemaVersion, BME_DB_SCHEMA_VERSION, "meta schemaVersion mirrors top-level");
assert.deepEqual(findUnknownTopLevelSnapshotKeys(durable), [], "durable snapshot has no rogue top-level keys");
console.log(" ✓ real buildSnapshotFromGraph stamps explicit top-level schemaVersion");
console.log("graph-snapshot-schema tests passed");