Support checked closed generic portable bindings
This commit is contained in:
@@ -36,3 +36,46 @@ test("generation rejects remote dependencies, wrong effects and unsupported shap
|
||||
entry.dependencyPorts[0]!.requirement = { kind: "reflection", selectors: ["active"] };
|
||||
assert.throws(generate, /Unsupported reflection port/);
|
||||
});
|
||||
|
||||
test("closed generic portable handlers have distinct concrete codecs and no universal casts", async () => {
|
||||
const { portableGenericPlan } = await import("./portable-generic-fixture.js");
|
||||
const plan = portableGenericPlan();
|
||||
const schema = plan.definition.bindingSchema;
|
||||
const pkg = schema.packages[0]!;
|
||||
assert.equal(pkg.exports.length, 2);
|
||||
const generated = generatePortableTypeScriptBindings(schema, pkg.revisionId, { target: "browser" });
|
||||
assert.match(generated, /readonly input: string/);
|
||||
assert.match(generated, /readonly input: ReadonlyArray<bigint>/);
|
||||
for (const entry of pkg.exports) {
|
||||
assert.ok(entry.application);
|
||||
assert.ok(generated.includes(JSON.stringify(entry.id)));
|
||||
assert.ok(generated.includes(JSON.stringify(entry.displayName)));
|
||||
}
|
||||
assert.notEqual(pkg.exports[0]!.displayName, pkg.exports[1]!.displayName);
|
||||
assert.equal(
|
||||
generated.replace('target = "browser"', 'target = "server"'),
|
||||
generatePortableTypeScriptBindings(schema, pkg.revisionId, { target: "server" }),
|
||||
);
|
||||
});
|
||||
|
||||
test("a portable subset of a mixed interface excludes remote dependencies", async () => {
|
||||
const schema = compileExecutionPlan(await loadReaderWorkspace()).definition.bindingSchema;
|
||||
const entry = schema.packages.flatMap((p) => p.exports).find((e) => e.displayName === "addHighlight")!;
|
||||
const iface = schema.interfaces.find((i) => i.revisionId === "interface:reader:document-data@1")!;
|
||||
const selected = entry.dependencyPorts.find((p) => p.requirement.kind === "interface")!.requirement;
|
||||
assert.equal(selected.kind, "interface");
|
||||
if (selected.kind !== "interface") throw Error("interface required");
|
||||
const operation = structuredClone(iface.members[0]!.operations[0]!);
|
||||
operation.id = "document:remote:get" as typeof operation.id;
|
||||
operation.execution = { kind: "remote" };
|
||||
iface.members.push({
|
||||
...structuredClone(iface.members[0]!),
|
||||
id: "document:remote" as (typeof iface.members)[0]["id"],
|
||||
displayName: "remote",
|
||||
operations: [operation],
|
||||
});
|
||||
const generate = () => generatePortableTypeScriptBindings(schema, "package:reader-runtime@1", { target: "browser" });
|
||||
assert.doesNotMatch(generate(), /readonly "remote.get"/);
|
||||
selected.operations!.push(operation.id);
|
||||
assert.throws(generate, /select a portable subset/);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user