@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 testnpm 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 throughreintersect.* 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 frompackages/sdk/src/recipes/__tests__: