Files
fdbck/vitest.config.ts
mAi a0765c9bf7 test: vitest + jsdom for Svelte component tests
Sets up the runtime split for §3.A's per-question-type modules: each type's
ParticipantInput / BuilderEditor / ResultsBlock will live in its own .svelte
file and want testable input handling. The pure logic (schema, isAnswerEmpty,
ingest, csvColumns, etc.) stays on `bun test`; the Svelte components run on
vitest.

Why two runners:

- Bun test doesn't apply the `browser` export condition when resolving ESM,
  so it picks Svelte 5's `index-server.js` and @testing-library/svelte's
  mount() throws lifecycle_function_unavailable.
- Vitest reuses the existing vite-plugin-svelte and applies the right
  conditions natively. Run via `bun --bun vitest` so vitest itself executes
  on bun (Node 18 is too old for vitest 4's node:util.styleText usage).

Files:

- New vitest.config.ts (jsdom env, svelte plugin, browser conditions, picks
  up src/**/*.svelte.test.ts files only)
- New src/test-setup/vitest.ts — afterEach cleanup so consecutive render()
  calls don't pollute each other's getByTestId lookups
- New src/lib/components/SmokeTest.svelte + .svelte.test.ts — sanity check
  that the runner actually mounts a Svelte 5 component and reads props
- package.json scripts split: `test:server` (bun, 5 server files),
  `test:components` (vitest), `test` runs both
- Pinned @sveltejs/vite-plugin-svelte to ^5.0.0 (v7 needs Node 22+ for
  node:util.styleText; ours is on Node 18)

devDeps added (test-only): vitest, @testing-library/svelte,
@testing-library/jest-dom, jsdom.

54 server tests + 2 component tests pass. svelte-check + build clean.
2026-05-07 20:04:10 +02:00

34 lines
1.2 KiB
TypeScript

import { defineConfig } from 'vitest/config';
import { svelte } from '@sveltejs/vite-plugin-svelte';
/**
* Vitest config — runs *.svelte.test.ts files under jsdom with the Svelte
* plugin, so per-type ParticipantInput / BuilderEditor / ResultsBlock
* components in lib/questions/<type>.svelte (or any .svelte component) can
* be mounted via @testing-library/svelte.
*
* Server-side tests (.test.ts under lib/server/) stay on `bun test` per
* `bun run test:server`. Component tests live behind `bun run test:components`.
*
* The runtime split exists because:
* 1. Bun test doesn't apply `browser` export conditions when resolving ESM,
* so it picks Svelte's `index-server.js` and @testing-library/svelte's
* mount() throws lifecycle_function_unavailable.
* 2. Vitest reuses the existing svelte vite plugin; no extra runtime split.
*
* Both runners share the same expect()/describe()/test() API surface, so
* component tests look identical in spirit to the server-side ones.
*/
export default defineConfig({
plugins: [svelte({ hot: false })],
resolve: {
conditions: ['browser'],
},
test: {
environment: 'jsdom',
include: ['src/**/*.svelte.test.ts'],
setupFiles: ['./src/test-setup/vitest.ts'],
globals: false,
},
});