first commit
This commit is contained in:
92
docs/api-stack/api/api-worker-host/src/testing/testing.md
Normal file
92
docs/api-stack/api/api-worker-host/src/testing/testing.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Worker host conformance harness
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`runWorkerHostConformance` spins up an in-process worker-shaped peer
|
||||
using paired `MessageChannel` ports. It exists so this package's own
|
||||
test suite — and the lifecycle-driver tests inside `api-host` — can
|
||||
exercise the full bootstrap → lifecycle → capability-proxy chain
|
||||
without spawning a real `node:worker_threads` `Worker`. Two paired
|
||||
ports are wired up (one for control, one for capability), the
|
||||
bootstrap is run on the worker-side ports, a stub capability server
|
||||
is mounted on the main-side of the capability port, and a main-side
|
||||
RPC client is wired to the control port — giving callers everything
|
||||
they need to drive lifecycle commands and observe capability call
|
||||
dispatch deterministically.
|
||||
|
||||
## Features
|
||||
|
||||
- Optional overrides for `manifest`, `capabilityHandles`, plugin
|
||||
`hooks` and the main-side `capabilityHandlers`.
|
||||
- Reasonable defaults (`{ name: "test-plugin", version: "0.1.0",
|
||||
tier: "isolated", capabilities: [] }`) so trivial tests need zero
|
||||
setup.
|
||||
- Returns the live `WorkerHost`, the main-side `WorkerRpcClient`,
|
||||
the stub capability server, both port pairs and a single
|
||||
`dispose()` that tears everything down in reverse order.
|
||||
- No real `Worker` thread spawned — pure structured-clone routing
|
||||
via `MessageChannel`.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import {
|
||||
runWorkerHostConformance,
|
||||
} from "@suaveplan/api-worker-host/testing";
|
||||
|
||||
const h = runWorkerHostConformance({
|
||||
hooks: { install: () => {} },
|
||||
});
|
||||
const ack = await h.mainClient.call("lifecycle.dispatch", [
|
||||
{ command: "install" },
|
||||
]);
|
||||
h.dispose();
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
Provide capability handles + main-side handlers to round-trip a
|
||||
capability call:
|
||||
|
||||
```ts
|
||||
import {
|
||||
runWorkerHostConformance,
|
||||
} from "@suaveplan/api-worker-host/testing";
|
||||
|
||||
const h = runWorkerHostConformance({
|
||||
capabilityHandles: { db: { methods: ["query"] } },
|
||||
capabilityHandlers: {
|
||||
"db.query": (params) => ({ rows: [params[0]] }),
|
||||
},
|
||||
});
|
||||
const query = h.host.capabilities.db?.query;
|
||||
const result = await query?.("SELECT 1");
|
||||
h.dispose();
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `runWorkerHostConformance(opts?): WorkerHostConformanceHarness`
|
||||
- `WorkerHostConformanceOptions`:
|
||||
- `manifest?: ManifestEnvelope`
|
||||
- `capabilityHandles?: CapabilityHandles`
|
||||
- `hooks?: PluginLifecycleHooks`
|
||||
- `capabilityHandlers?: WorkerRpcHandlers`
|
||||
- `WorkerHostConformanceHarness`:
|
||||
- `host: WorkerHost`
|
||||
- `mainClient: WorkerRpcClient`
|
||||
- `capabilityServer: WorkerRpcServer`
|
||||
- `controlPorts / capabilityPorts: InProcessPortPair`
|
||||
- `dispose(): void`
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`dispose()` closes the main-side client first so it stops sending,
|
||||
then the worker host (which closes its own server + capability
|
||||
client), then the main-side capability server, then both port pairs.
|
||||
Closing in reverse-construction order avoids `port already closed`
|
||||
log noise in vitest while still flushing the inflight RPC budget.
|
||||
Reference in New Issue
Block a user