Testing
memoryNetwork() runs the whole stack (handshake, encryption, sessions, delivery) inside one process, with no relay and no WebRTC. Frames are delivered asynchronously, as on a real network.
import { describe, expect, it, afterEach } from "vitest";
import { createPeer, memoryNetwork, type Peer } from "@vaultys/peer-sdk";
import { VaultysId } from "@vaultys/id";
const peers: Peer[] = [];
afterEach(() => Promise.all(peers.splice(0).map((p) => p.close())));
async function spawn(network: ReturnType<typeof memoryNetwork>) {
const peer = await createPeer({
identity: await VaultysId.generatePerson(),
transport: network.transport(),
acceptIncoming: () => true,
keepaliveMs: 0, // no timers left running after the test
});
peers.push(peer);
return peer;
}
describe("chat", () => {
it("delivers a message with the verified sender", async () => {
const network = memoryNetwork();
const alice = await spawn(network);
const bob = await spawn(network);
const received = new Promise((resolve) => bob.once("message", resolve));
await alice.send(bob.did, { text: "hi" });
expect(await received).toMatchObject({ from: alice.did, body: { text: "hi" } });
});
});
Simulating the network
const network = memoryNetwork();
network.disconnect(bob.did); // Bob can no longer be dialed (existing sessions stay open)
bob.disconnect(alice.did); // close the session between them
To test offline delivery, send to a DID before its peer exists, then create it: the message is delivered when it comes online. Use short retries to keep tests fast:
const alice = await createPeer({ identity, transport, retry: { initialMs: 50, maxMs: 100 } });
Tips
- Close every peer after each test, and set
keepaliveMs: 0, so no timers keep the test runner alive. memoryStore()is the default. Share one store between twocreatePeercalls with the same identity to test restarts.- Prefer waiting on events (
once("message"),once("delivered")) over fixed sleeps.