Implement main-thread Camino sessions and synchronous CRDT editing
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import assert from "node:assert/strict";
|
||||
import { test } from "node:test";
|
||||
import { compileCapabilityResourceSource } from "../src/capability-language/index.js";
|
||||
import { compileQuery } from "../src/query/compile.js";
|
||||
import { defaultQueryBudgets } from "../src/query/types.js";
|
||||
import { portableValueSchema, tsType } from "../src/bindings/portable.js";
|
||||
import { isStorableType, TypeSubstitution } from "../src/capability-model/index.js";
|
||||
|
||||
const source = { repository: "https://example.test/variants.git", commit: "a".repeat(40) };
|
||||
const declaration = readFileSync("test/fixtures/canvas-content.qx", "utf8");
|
||||
const result = compileCapabilityResourceSource(declaration, { source });
|
||||
assert.ok(result.ok, JSON.stringify(result.diagnostics));
|
||||
if (result.resource.kind !== "interface") throw Error("Expected interface");
|
||||
const iface = result.resource.revision;
|
||||
const entries = iface.members[0];
|
||||
if (entries.kind !== "value") throw Error("Expected value");
|
||||
|
||||
test("native variant aliases lower into nominal cases with typed payloads", () => {
|
||||
assert.equal(entries.valueType.kind, "list");
|
||||
assert.ok(isStorableType(entries.valueType));
|
||||
const schema = portableValueSchema(entries.valueType) as any;
|
||||
assert.equal(schema.value.id, "canvas:entry@1");
|
||||
assert.equal(schema.value.cases.stroke.id, "canvas:stroke");
|
||||
assert.match(tsType(entries.valueType), /kind: "stroke"/);
|
||||
assert.match(tsType(entries.valueType), /ReadonlyArray<.*"x": number/);
|
||||
const substitution = new TypeSubstitution({
|
||||
arguments: new Map([["T", { kind: "value", type: { kind: "scalar", name: "string" } }]]),
|
||||
applyInterface: () => {
|
||||
throw Error("unused");
|
||||
},
|
||||
implementsInterface: () => false,
|
||||
});
|
||||
assert.deepEqual(
|
||||
substitution.value({
|
||||
kind: "variant",
|
||||
id: "box",
|
||||
cases: { some: { id: "box:some", value: { kind: "parameter", parameterId: "T" } } },
|
||||
}),
|
||||
{ kind: "variant", id: "box", cases: { some: { id: "box:some", value: { kind: "scalar", name: "string" } } } },
|
||||
);
|
||||
});
|
||||
test("variant query scalars keep their checked payload type and reject branch selection", async () => {
|
||||
const query = {
|
||||
id: "canvas-query",
|
||||
displayName: "Canvas",
|
||||
root: { kind: "object" as const, interface: iface.revisionId },
|
||||
document: "canvas.graphql",
|
||||
operation: "Canvas",
|
||||
fragments: [],
|
||||
views: [],
|
||||
allowances: [],
|
||||
budgets: { ...defaultQueryBudgets },
|
||||
watch: true,
|
||||
};
|
||||
const checked = await compileQuery(query, [iface], async () => `query Canvas { root { entries } }`);
|
||||
assert.equal(checked.output.kind, "record");
|
||||
if (checked.output.kind !== "record") return;
|
||||
const root = checked.output.fields.root;
|
||||
assert.equal(root.kind, "record");
|
||||
if (root.kind !== "record") return;
|
||||
assert.deepEqual(root.fields.entries, entries.valueType);
|
||||
await assert.rejects(compileQuery(query, [iface], async () => `query Canvas { root { entries { kind value } } }`));
|
||||
});
|
||||
test("unknown and duplicate cases fail; reference payloads remain nonstorable", () => {
|
||||
const duplicate = compileCapabilityResourceSource(declaration.replace('"canvas:image"', '"canvas:stroke"'), {
|
||||
source,
|
||||
});
|
||||
assert.equal(duplicate.ok, false);
|
||||
assert.ok(
|
||||
!isStorableType({
|
||||
kind: "variant",
|
||||
id: "transport",
|
||||
cases: {
|
||||
ref: {
|
||||
id: "ref",
|
||||
value: { kind: "object-ref", expectation: { kind: "interface", interfaceRevisionId: iface.revisionId } },
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user