Skip to content

test(backend): init/construct/runtime error-frame coverage#108

Open
gmaclennan wants to merge 2 commits into
mainfrom
test/backend-init-handler
Open

test(backend): init/construct/runtime error-frame coverage#108
gmaclennan wants to merge 2 commits into
mainfrom
test/backend-init-handler

Conversation

@gmaclennan

Copy link
Copy Markdown
Member

Summary

PR #36 added the rootkey handshake ({type:"init",rootKey:"<base64>"}) and the structured error-frame broadcast on the control socket, but backend/index.js's validation and fatal-handling logic was untested. This adds that coverage with a surgical, behaviour-preserving refactor.

  • Extracted the init-payload validation (string check, strict-base64-22 check, decode-to-16-bytes check) into a pure backend/lib/validate-init.mjs#validateInit that returns either the 16-byte Buffer or a structured error. The inline checks moved verbatim; index.js's init handler now calls the helper.
  • Extracted the fatal error-frame construction into backend/lib/error-frame.mjs#errorFrame and made handleFatal's broadcast / captureFatal / flush / exit deps injectable (they default to the current module singletons, so runtime behaviour is unchanged).
  • Added unit tests for both pure helpers and child_process.spawn-based integration tests that drive a fake control-socket client against the real loader.mjs -> index.js boot to assert the process-level error frames and non-zero exit.
  • Wired the new top-level index.test.mjs into the node --test runner (backend/package.json test script).

The refactor is kept minimal because backend/index.js is also touched by the in-flight Sentry work — this should merge before the Sentry PR (both touch backend/index.js).

Acceptance criteria (#38)

  • Runner wired — already node --test; confirmed and extended to include the new top-level index.test.mjs.
  • Init malformed -> non-zero exit + phase "init" broadcast.
  • Construct failure -> phase "construct" broadcast before exit.
  • Uncaught throw -> phase "runtime" broadcast.
  • Init handler unit coverage: non-string rootKey -> error; wrong-length-after-decode -> error; valid -> resolves; second init after consumption -> ignored.

Checks run

  • npm --prefix backend ci --ignore-scripts then cd backend && node --test (and npm test): 43 pass / 0 fail (35 pre-existing + 8 new across validate-init.test.mjs and index.test.mjs).
  • npm run types (backend tsc): my changes add no new errors. One pre-existing error remains — lib/install-polywasm.js(16): TS7016 'polywasm' has no declaration file — which is present on a pristine origin/main checkout (untouched file, missing @types) and unrelated to this PR.

Not run locally

  • No native (Kotlin/Swift) suites are involved in this change, so nothing native to run.
  • The integration tests spawn the real backend; they rely on @comapeo/core importing under Node 24, which it does in this environment. CI runs the same node --test.

Closes #38

🤖 Generated with Claude Code

gmaclennan and others added 2 commits June 22, 2026 12:08
Extract the init-payload validation into a pure `validateInit` helper and
the fatal error-frame construction into `errorFrame`, then make
`handleFatal`'s broadcast/sentry/exit deps injectable. Runtime behaviour
is unchanged — the inline checks moved verbatim, and `handleFatal` defaults
to the same module singletons.

Add unit tests for the validators and spawn-based integration tests that
drive a fake control-socket client to assert the process-level error frames
and non-zero exit for the init, construct, and runtime phases. Wire the new
top-level test file into the `node --test` runner.

Closes #38

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gmaclennan gmaclennan marked this pull request as ready for review June 22, 2026 12:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Backend test infrastructure + init handler tests

1 participant