Skip to main content
@reintersect/sdk/testing runs your app against an in-memory Reintersect host. The host sends signed deliveries through your app’s real router, stores block state and viewer values, records every call your code makes to the Reintersect API, and checks every rendered tree with the same validator Reintersect’s server runs, so a tree that fails on the server fails here first, with the same message. Tests run without a network, a workspace or a running dev server. Using Effect? @reintersect/sdk/effect/testing gives the same host as an Effect service for @effect/vitest; see Testing in the Effect guide.

Set up a host

This is the test npm create reintersect writes:
src/app.test.ts
createTestHost only accepts a complete app, the same check reintersect build makes.

Host options

Blocks

press and act return the result: state, tree, notice, fieldErrors, openUrl, final, notify, revalidated, plus the updated block. Switch who acts with host.as(viewer):

References and events

Commands and message actions

Both return the outcome: The surface defaults to a test circle. The context a message action receives follows its declared context: the message’s thread is the message itself, and its conversation is a test conversation holding the message, unless you pass context: { thread, conversation, surrounding }. A message with conversationId: null, or a surrounding list, gives a "conversation" action surrounding messages instead of a conversation.

Calls to Reintersect

Your handlers’ calls through reintersect.* go to a fake API that records them:
Operations are blocks.insert, blocks.update, blocks.replace, blocks.updateWhere, blocks.revalidate, references.push, references.revalidate, notifications.send, replies.create, streams.sendEvent, invocations.respond and invocations.update. An invocations.respond call records the interactionToken and the rendered answer, whether your code called it or a deferred task did. A deferred task that fails records the SDK’s failure answer, a private danger notice: { visibility: "private", notice: { tone: "danger", text } }.

Time

The host runs on a test clock. await host.advance("10 minutes") moves it, which drives staleAfter refreshes on view, signature timestamps and token expiry. host.now() reads it.

Trees

The kit runs the server’s validator, so its checks cover anatomy, nesting, labels, limits and the rest of Limits and rules, plus action references. reintersect check runs the same checks. Pass a validator to run your own stricter check on every render. Failures are tagged errors you can match on, such as ReintersectTestControlMissingError (no visible button with that label), ReintersectTestTreeInvalidError and ReintersectTestPushMissingError.

Testing recipes

Recipes are ordinary blocks, so the same host tests them. Each recipe has a Promise and an Effect test you can copy from packages/sdk/src/recipes/__tests__: