Public: anyone can read this; the crew can change it.

forked from trevato/cs

One AudioContext fake, behind the door: the sound device's test double stops being written three times #332

shipped production is serving it opened this has it
opened this

The engine opens the AudioContext (src/engine/sound.ts), so the engine should ship the fake one every game's tests open instead — the same argument as fakePage, and as the GL recorder.

Three copies exist: src/engine/sound.test.ts:150, src/range/audio.test.ts:81 and src/range/stage.test-helper.ts:158. They are the same Fake class — sampleRate, currentTime, state, destination, createBuffer, createBufferSource, createBiquadFilter, createGain, createOscillator, createStereoPanner, createDynamicsCompressor — differing only in what each writes down: the engine's keeps a log, the edges, the nodes, the buffers and the panners; the range's test keeps a log and the graph; the range's stage helper keeps a voices view (kind, frequency, gain, pan). Three doubles for one device is three things to keep in step with sound.ts.

Done looks like

  • [ ] One fake behind the door, in a module named for what it is (src/engine/context.ts reads right beside sound.ts), exported from src/engine/index.ts and named in src/engine/surface.json.
  • [ ] It records once, completely: every call with its arguments and its scheduled time, the graph as node→node edges, the nodes handed out, the buffers created, and counts of contexts opened and resume()s. Every view the three callers need is derived from that one recording — including the range helper's voices, which becomes a fold over the log and not a second fake.
  • [ ] Options, with their defaults stated in the docstring: whether createStereoPanner and createDynamicsCompressor exist as methods at all (a browser without one has no method rather than one that answers null — the shape sound.ts tests for), the starting currentTime (the engine's fake says 2, the range's says 0) and the starting state ("suspended" vs "running").
  • [ ] The range's panner trick survives: pan.value is assigned rather than scheduled, so the side lands in a setter and belongs to the next voice started. If the shared fake records it differently, the helper folds it — the assertions that read it do not weaken.
  • [ ] No assertion in sound.test.ts, src/range/audio.test.ts or the range's boot tests changes. If one must, say which and why in the pull: a moved assertion is a claim this change was not supposed to make.
  • [ ] Nothing outside the engine defines a Fake with createBufferSource afterwards.
  • [ ] Boundary, purity and independence tests pass; the fake ships in no bundle (measure the three ceilings); src/engine/GUIDE.md's sound section names the fake as something a game gets for its tests.
  • [ ] bun test green.

Files

src/engine/context.ts (new), src/engine/index.ts, src/engine/surface.json, src/engine/sound.test.ts, src/range/audio.test.ts, src/range/stage.test-helper.ts, src/engine/GUIDE.md.

Risks

  • The three fakes disagree about the clock and the initial state; those become options with a default, and the default has to be what sound.ts is actually tested against or the engine's own suite moves under it.
  • The fake must stay a recorder: it synthesises nothing and checks no sample. sound.test.ts walks the graph as a path and expects every node to connect to exactly one thing — keep that property, or its walk turns into a search.
  • src/range/audio.test.ts is 491 lines built on its copy. Read it before moving it, and move all three in one commit so a half-shared fake never sits in the tree.

Suggested: Torque — it is a recording of exact calls and scheduled times, and the tests that read it are numeric.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs