Initial Commit
This commit is contained in:
85
packages/ui/react/react-midi/src/test-utils.md
Normal file
85
packages/ui/react/react-midi/src/test-utils.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# `test-utils`
|
||||
|
||||
## Purpose
|
||||
|
||||
Provides the deterministic in-memory implementations of the Web MIDI
|
||||
shape used throughout the `@suaveplan/react-midi` test suite. These
|
||||
are not mocks — they are real, faithful implementations of the
|
||||
`WebMIDIInput` / `WebMIDIOutput` / `WebMIDIAccess` contracts that
|
||||
the production code consumes, so every test exercises the same
|
||||
integration path that a real browser would. The helpers cover the
|
||||
three pieces a typical test needs: fake input ports that can be
|
||||
driven by calling `fire(bytes)`, fake output ports that record
|
||||
received bytes in a `sent: number[][]` array, and a fake access
|
||||
object that publishes `inputs`, `outputs`, and an `onstatechange`
|
||||
slot whose subscribers fire on `addInput` / `removeInput`.
|
||||
|
||||
A small `<FakeMidiProvider>` wrapper composes `MidiRequestContext`
|
||||
plus `<MidiProvider>` and exposes a `requestSpy` callback so tests
|
||||
can assert that `navigator.requestMIDIAccess` is called exactly once
|
||||
under StrictMode.
|
||||
|
||||
## Features
|
||||
|
||||
- `makeFakeInput(id, name?)` — port with a `fire(bytes)` helper.
|
||||
- `makeFakeOutput(id, name?)` — port with a `sent` log of received
|
||||
buffers.
|
||||
- `makeFakeAccess({ inputs?, outputs?, sysex? })` — access object
|
||||
with `addInput` / `addOutput` / `removeInput` runtime mutators
|
||||
that fire the `statechange` listener.
|
||||
- `<FakeMidiProvider>` — wires injection + `<MidiProvider>` and
|
||||
forwards a `requestSpy` callback for assertion in StrictMode
|
||||
scenarios.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```tsx
|
||||
import {
|
||||
FakeMidiProvider,
|
||||
makeFakeAccess,
|
||||
makeFakeInput,
|
||||
} from "./test-utils";
|
||||
|
||||
const input = makeFakeInput("a");
|
||||
render(
|
||||
<FakeMidiProvider access={makeFakeAccess({ inputs: [input] })}>
|
||||
<MyComponent />
|
||||
</FakeMidiProvider>
|
||||
);
|
||||
input.fire([0x90, 0x40, 0x40]);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```tsx
|
||||
// Assert exactly-once request under StrictMode.
|
||||
let count = 0;
|
||||
render(
|
||||
<StrictMode>
|
||||
<FakeMidiProvider
|
||||
access={makeFakeAccess()}
|
||||
requestSpy={() => {
|
||||
count += 1;
|
||||
}}
|
||||
>
|
||||
<MyTree />
|
||||
</FakeMidiProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
expect(count).toBe(1);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `makeFakeInput(id, name?): FakeInput`.
|
||||
- `makeFakeOutput(id, name?): FakeOutput` — `{ sent: number[][] }`.
|
||||
- `makeFakeAccess(opts?): FakeAccess` — `{ addInput, addOutput, removeInput }`.
|
||||
- `<FakeMidiProvider access, requestImpl?, requestSpy?, sysex?>`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The helpers live under `src/` rather than `tests/` because they are
|
||||
imported by `.test.tsx` files co-located with feature modules.
|
||||
Production code never imports from `test-utils.tsx` — the file is
|
||||
explicitly excluded from the coverage report and the `tsc` library
|
||||
output so it never lands in the published bundle.
|
||||
Reference in New Issue
Block a user