tests: add renderer-SDK mock layer + first 2 component-/hook-level pilots

Foundations for widening Vitest coverage past the pure-helper subset.

The real `@nitrots/nitro-renderer` eagerly loads Pixi v8 and the full
Habbo message parser/composer registry at module-import time, which
jsdom cannot host: any `tests/**` file that transitively pulled a
renderer symbol would throw before a single assertion ran. That's
why the existing 8 suites all stuck to pure modules imported by
concrete path and used `import type` for renderer-side names.

Add a stub at `tests/mocks/renderer-mock.ts`, aliased over the package
via `vitest.config.mts`. It exports:

- Explicit behavioral stubs for the symbols tests actually exercise:
  `NitroLogger`, `GetEventDispatcher`, the `mockEventDispatcher`
  helper with `addEventListener` / `removeEventListener` /
  `dispatchEvent` / `hasListeners`, and `RoomSessionDoorbellEvent`
  (signature matches the real `(type, session, userName)` to keep
  tsgo happy).
- String-keyed Proxy enums for `NitroEventType`, `RoomObjectCategory`,
  `AvatarFigurePartType`, etc. — each access returns a stable unique
  string so dispatch and listener agree.
- Lightweight `class StubClass {}` placeholders for the ~30 Pixi and
  gameplay classes the `src/api/*` barrel touches at import time
  (`NitroAlphaFilter`, `NitroContainer`, `EventDispatcher`, …).
  Keeps the cascade from throwing without simulating behavior tests
  don't care about.
- Singleton getters (`GetAssetManager`, `GetCommunication`,
  `GetSessionDataManager`, …) returning a chainable Proxy so deeply
  nested `GetX().y.z(…)` access evaluates to no-op proxies.

Pilots on top of that layer (each one designed to catch a different
class of regression):

- `tests/WidgetErrorBoundary.test.tsx` (4 cases) — happy path,
  default silent fallback + `NitroLogger.error` call, custom
  fallback node, default `unknown` widget name.
- `tests/useDoorbellState.test.tsx` (7 cases) — initial empty state,
  append on `RSDE_DOORBELL`, dedup duplicate names, remove on
  `RSDE_ACCEPTED` / `RSDE_REJECTED`, ignore stale events for
  never-pending users, full unsubscribe on unmount.

Suite count now 124/124 across 10 files (was 113/113 across 8).
`yarn typecheck` still green.

Docs: CLAUDE.md's Vitest row and "Where everything lives" pointer
updated; `docs/ARCHITECTURE.md` Tests section now lists the new
suites + a description of what the mock layer covers, and the
"Wider Vitest coverage" entry in the next-steps list is reframed
from "needs a renderer mock" to "pick the next adopter".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
simoleo89
2026-05-13 21:31:08 +02:00
parent 622d73c2f0
commit c4018392f9
6 changed files with 519 additions and 17 deletions
+7 -2
View File
@@ -5,8 +5,12 @@ import { resolve } from 'path';
* Test runner config — kept separate from vite.config.mjs because the
* dev/build config wires up the renderer SDK via filesystem aliases that
* point at sibling working trees (`../renderer`, `../Nitro_Render_V3`).
* Tests are deliberately written against pure modules (helpers, stores)
* that don't pull in the renderer.
*
* Test files were originally written against pure modules (helpers,
* stores) that don't pull in the renderer. We now also support
* component-level tests by aliasing `@nitrots/nitro-renderer` to a
* hand-written stub at `tests/mocks/renderer-mock.ts` so jsdom doesn't
* try to evaluate Pixi + the full message parser/composer registry.
*/
export default defineConfig({
test: {
@@ -18,6 +22,7 @@ export default defineConfig({
},
resolve: {
alias: {
'@nitrots/nitro-renderer': resolve(__dirname, 'tests/mocks/renderer-mock.ts'),
'@': resolve(__dirname, 'src')
}
}