Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# test-utils
|
||||
|
||||
## Purpose
|
||||
|
||||
`test-utils.tsx` provides the in-memory `FakeSession` and the `withProvider` wrapper used
|
||||
by every chunk-C hook + component test. The fake mirrors the canonical `StreamSessionLike`
|
||||
contract from the spec — same method names, same event channels — so tests exercise the
|
||||
real React render path without booting transports or audio engines. Tests inject the
|
||||
fake via the provider's `sessionFactory`, drive state mutations through the public API,
|
||||
and assert the rendered DOM, hook return value, and recorded method calls.
|
||||
|
||||
The file lives at the package root rather than inside a feature directory because it is
|
||||
shared by every feature module; `vitest.config.ts` excludes it from coverage.
|
||||
|
||||
## Features
|
||||
|
||||
- `FakeSession` — `StreamSessionLike` implementation with synchronous mutators, an
|
||||
internal `calls` recorder, and helpers (`pushPeer`, `setMixer`, `triggerInterruption`)
|
||||
that emit the matching event channel.
|
||||
- `withProvider(session)` — returns a `wrapper` suitable for
|
||||
`renderHook`/`render({ wrapper })`.
|
||||
- Strongly typed: every method signature matches the canonical spec so a compile-time
|
||||
break in chunks A+B surfaces here first.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```tsx
|
||||
import { renderHook } from "@testing-library/react";
|
||||
import { FakeSession, withProvider } from "../../test-utils.js";
|
||||
import { useStreamSession } from "./use-stream-session.js";
|
||||
|
||||
const session = new FakeSession();
|
||||
const { result } = renderHook(() => useStreamSession(), {
|
||||
wrapper: withProvider(session),
|
||||
});
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```tsx
|
||||
const session = new FakeSession({
|
||||
state: "joined",
|
||||
peers: [{ id: "alice", displayName: "Alice", connectionState: "connected", rttMs: 32 }],
|
||||
});
|
||||
// Drive state changes deterministically:
|
||||
await act(async () => session.pushPeer({ id: "bob", ... }));
|
||||
expect(result.current.peers).toHaveLength(2);
|
||||
expect(session.calls.setTrackVolume).toEqual([["alice", -3]]);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `FakeSessionInit` — constructor options bag.
|
||||
- `FakeSession` — `StreamSessionLike` plus `calls`, `pushPeer`, `setPeers`, `setMixer`,
|
||||
`setLocalLevel`, `setPeerLevel`, `triggerInterruption`.
|
||||
- `withProvider(session)` — `(props: { children }) => ReactNode`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The fake's event-emit path is synchronous (no microtask hop) so test assertions can run
|
||||
immediately after the mutation without `act` for simple cases. When tests need to
|
||||
observe a React re-render fence, they wrap the mutator in `act(() => session.foo())`.
|
||||
The recorded `calls` arrays let solo-semantics tests verify that mutations route through
|
||||
the session's `setTrackVolume` / `setTrackMute` / `setTrackSolo` rather than being
|
||||
re-implemented inside the hook.
|
||||
Reference in New Issue
Block a user