Files

71 lines
3.5 KiB
TypeScript
Raw Permalink Normal View History

import assert from "node:assert/strict";
import { test } from "node:test";
import { compileCapabilityResourceSource } from "../src/capability-language/parser.js";
import { formatQx } from "../src/capability-language/source.js";
import { compileExecutionPlan, compileKernelProgram, checkExecutionWorld } from "../src/execution-world/index.js";
import { generatePortableTypeScriptBindings } from "../src/bindings/portable.js";
import { buildArtifactFixture } from "./artifact-fixture.js";
import { compile, runtime, workspace } from "./acceptance-fixture.js";
test("acceptance syntax retains separate final-state ports through formatting, planning, adapters and artifacts", async () => {
const result = compile();
assert.ok(result.ok, JSON.stringify(result.diagnostics));
const formatted = compile(formatQx(runtime), formatQx(workspace));
assert.ok(formatted.ok, JSON.stringify(formatted.diagnostics));
const plan = compileExecutionPlan(result.workspace);
assert.equal(compileExecutionPlan(formatted.workspace).digest, plan.digest);
const kernel = compileKernelProgram(plan) as {
operations: { binding: { ports: { id: string }[]; acceptance: { export: string; ports: { id: string }[] } } }[];
packages: { exports: { id: string; acceptance?: string }[] }[];
};
assert.deepEqual(
kernel.operations[0]!.binding.ports.map((p) => p.id),
["write:value"],
);
assert.equal(kernel.operations[0]!.binding.acceptance.export, "runtime:check");
assert.deepEqual(kernel.operations[0]!.binding.acceptance.ports.map((p) => p.id).sort(), [
"read:ceiling",
"read:value",
]);
assert.equal(kernel.packages[0]!.exports.find((e) => e.id === "runtime:change")!.acceptance, "runtime:check");
assert.ok(
!generatePortableTypeScriptBindings(plan.definition.bindingSchema, "runtime@1", {
target: "target:org.quixos.execution.javascript@1",
}).includes('"runtime:check"'),
);
assert.ok(
generatePortableTypeScriptBindings(plan.definition.bindingSchema, "runtime@1", { target: "server" }).includes(
'"runtime:check"',
),
);
const artifacts = buildArtifactFixture(plan, "runtime@1");
await checkExecutionWorld(plan, [artifacts.manifest], artifacts.read);
});
test("acceptance declarations reject wrong effects/signatures and missing or mutable ports", () => {
for (const [pkg, ws] of [
[runtime.replace("snapshot targets [server]", "transaction targets [server]"), workspace],
[runtime.replace("snapshot targets [server]", "snapshot targets [JavaScript, server]"), workspace],
[
runtime.replace('check id "runtime:check" : int32 -> unit', 'check id "runtime:check" : string -> unit'),
workspace,
],
[
runtime.replace('check id "runtime:check" : int32 -> unit', 'check id "runtime:check" : int32 -> int32'),
workspace,
],
[runtime.replace('id "read:ceiling" : int32 [read]', 'id "read:ceiling" : int32 [write]'), workspace],
[runtime, workspace.replace("ceiling to state Ceiling;", "")],
[runtime.replace(" accept using check", ""), workspace],
])
assert.equal(compile(pkg, ws).ok, false, `${pkg}\n${ws}`);
});
test("generic acceptance syntax rejects explicitly until specialization is supported", () => {
const result = compileCapabilityResourceSource(
runtime.replace("operation change id", "operation change<value T> id"),
{
source: { repository: "https://example.test/limit.git", commit: "a".repeat(40) },
},
);
assert.equal(result.ok, false);
assert.ok(result.diagnostics.some((d) => d.code === "unsupported-generic-acceptance"));
});