import assert from "node:assert/strict"; import test from "node:test"; import { ImageClient } from "../src/client"; import { ProtocolError } from "../src/protocol"; import { control, startImage } from "./server"; test( "behavior browsing retrieves immutable revision source and preserves connection after missing revisions", { timeout: 10000 }, async (t) => { const image = await startImage(); let client: ImageClient | undefined; t.after(async () => { client?.close(); await image.stop(); }); client = await ImageClient.connect(image.address, (error) => assert.equal(error, undefined)); const original = await client.behaviorSource("counter", 1n); assert.match(original, /pub fn handle/); const source = "pub fn handle(state, message) { (state + 2, []) }\n"; const published = await control(image.address, { operation: "publish_behavior", parameters: { name: "counter", expected_revision: 1, source }, }); assert.match(JSON.stringify(published), /"kind":"behavior"/); const behavior = (await client.behaviors()).find((behavior) => behavior.name === "counter"); assert.ok(behavior); assert.equal(behavior.revision, 2n); assert.deepEqual( behavior.history.map((version) => version.revision), [1n, 2n], ); assert.equal(await client.behaviorSource("counter", 2n), source); assert.equal(await client.behaviorSource("counter", 1n), original); await assert.rejects(client.behaviorSource("counter", 3n), ProtocolError); await assert.rejects(client.behaviorSource("missing", 1n), ProtocolError); for (const revision of [0n, -1n, 18446744073709551616n]) { await assert.rejects(client.behaviorSource("counter", revision), /positive u64/); } await assert.rejects(client.behaviorSource(" ", 1n), /behavior name/); assert.equal(await client.behaviorSource("counter", 1n), original); }, );