Files
2026-05-27 23:29:53 +01:00

6.9 KiB

Why

We have a complete real-services test harness (docker/docker-compose.test.yml + the seven @suaveplan/testing-integration-* fixtures) and zero consumers wired to it. grep -rln "testing-integration-" packages apps outside packages/dev/testing-integration* returns nothing. Meanwhile @suaveplan/database/surrealdb ships its adapter tests against an in-suite makeFakeClient() DI fake (src/adapter/surreal-adapter.test.ts). That fake validates the adapter's shape against the SurrealClientLike port; it does not verify that the real surrealdb.js v2 client + SurrealDB v3.0.4 server actually behave the way the adapter assumes.

The db.create() drops content in surrealdb.js v2 + SurrealDB v3 issue we already burned on (forced the workaround INSERT INTO query) is exactly the class of bug a fake client cannot catch. Adapter assumptions about session use-NS/DB binding, query parameter passthrough, transaction semantics, version detection, and singleton lifecycle all need to be exercised against the real engine — that is the whole point of the docker-compose stack.

This change wires @suaveplan/database/surrealdb to @suaveplan/testing-integration-surrealdb as the first real consumer of the integration harness, establishing the pattern the remaining I/O packages will follow (db-sqlite against postgres, storage-s3 against garage, email-* against mailpit, search-* against typesense, etc.). Scope is intentionally narrow: surrealdb only, no sweep yet.

What Changes

New integration-test surface in @suaveplan/database/surrealdb

  • New tests/integration/ directory (sibling of tests/), separated from the unit suite. Per the project's hybrid placement rule (per-feature unit tests co-located in src/; cross-cutting tests in tests/), real-DB tests live in tests/integration/ because they are cross-cutting (depend on a backing service rather than a single feature module).
  • New vitest.integration.config.ts extending the package's existing config, registering SurrealDBFixture via createIntegrationSetup({ surrealdb: new SurrealDBFixture() }).
  • New script entry in package.json: "test:integration": "vitest run --config vitest.integration.config.ts".
  • Default unit suite (bunx turbo test --filter=@suaveplan/database/surrealdb) does not run integration tests — they are opt-in via the new script and CI gate.
  • Each integration test calls skipIfUnavailable("surrealdb", inject) at the top so the suite is skipped (not failed) when docker is not running locally.

Integration test coverage (real SurrealDB v3.0.4 container)

  • surreal-adapter.integration.test.ts — connect / use(ns,db) / signin / query SELECT 1 / disconnect, asserting against the live engine, not a fake.
  • singleton.integration.test.ts — getSingleton returns the same connected adapter instance for the same name, closeSingleton actually closes the WS, closeAllSingletons is reverse-order safe, registry isolation when an explicit Map is passed.
  • version-detector.integration.test.ts — version detector returns the real server version string and parses it correctly.
  • init.integration.test.ts — namespace + database creation flow against the live engine, including the db.create() drop-content workaround path documented in feedback memory surrealdb-create-content-drop.
  • connection.integration.test.ts — 'ConnectionRefused' error code surfacing matches the documented branch (error?.code === 'ConnectionRefused' || error?.message?.includes('Unable to connect')).
  • discovery.integration.test.ts — schema discovery against a real fresh database with seeded tables/fields.

CI gate

  • New turbo task test:integration that runs only on the integration entry script. Wired in CI behind docker compose -f docker/docker-compose.test.yml up -d + the env-bridge variables from docker/README.md.
  • Unit-coverage gate (test:coverage) is unchanged — integration tests do not count toward Istanbul 100% on src/. They verify behaviour against real I/O, which is orthogonal to source coverage.

Out of scope

  • Sweeping the same pattern across the other six fixtures (postgres, redis, mailpit, typesense, garage-s3, step-ca). That follows in separate per-package changes after surrealdb proves the wiring.
  • Replacing the existing makeFakeClient() adapter unit tests. The fake-client suite stays — it pins the port contract and runs in milliseconds without docker. Integration tests are additive.
  • Changes to @suaveplan/testing-integration-surrealdb itself. The fixture is already shipped and conformant.
  • Changes to the docker-compose stack itself.

Capabilities

New Capabilities

  • database-surrealdb-integration — defines the integration-test contract for @suaveplan/database/surrealdb: which adapter behaviours MUST be verified against a real container, the env-bridge passthrough rule, the local-skip rule when docker is unavailable, and the CI gate.

Modified Capabilities

  • None. testing-integration-surrealdb is consumed unmodified.

Dependencies

This change is the consumer wire-up; it depends on three upstream fixes landing first:

  1. testing-integration-vite-entry-fix — without it, @suaveplan/testing-integration-surrealdb cannot be imported by name (its dist/index.js is not emitted).
  2. testing-integration-build-fix (Option A) — without it, createIntegrationSetup() returns a data:video/mp2t;base64,… URL for globalSetup, which Vitest cannot load. surrealdb-integration-tests consumes the public createIntegrationSetup API and would otherwise have to hand-roll a TestEnvironment driver (the rebel pattern in storage-s3 that this stack eliminates).
  3. testing-integration-bun-runtime-compat (Option B) — without it, bunx vitest run panics in uv_version_string before any container starts; this monorepo runs every test under Bun per CLAUDE.md.

surrealdb-integration-tests MUST NOT be archived until all three upstream changes have shipped and the suite has been observed actually starting a real SurrealDB container under Bun.

Impact

  • Affected code: packages/database/surrealdb/tests/integration/** (new), packages/database/surrealdb/vitest.integration.config.ts (new), packages/database/surrealdb/package.json (new script + dev dep on @suaveplan/testing-integration-surrealdb and @suaveplan/testing-integration).
  • Affected consumers: none — this is additive test coverage on a leaf package.
  • CI: new job step that brings up docker-compose.test.yml and runs bunx turbo test:integration --filter=@suaveplan/database/surrealdb. Local developers can either run docker first or rely on skipIfUnavailable() to no-op the suite.
  • Documentation: README of @suaveplan/database/surrealdb gets a new "Integration tests" section. docker/README.md already covers the env-bridge — no change needed there.
  • CLAUDE.md / MANIFEST.md: no new package, so no manifest regeneration. The surrealdb package description in CLAUDE.md does not need to change.