Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
12 KiB
12 KiB
@suaveplan/testing-integration - Core integration test infrastructure: ServiceFixture interface, TestEnvironment, createIntegrationSetup() factory, HealthPoller, skipIfUnavailable() helper
Summary
Core integration test infrastructure for Vitest: fixture lifecycle management, health polling, and the global-setup bridge.
Documentation tree
- environment — (no submodules)
- test-environment — (no submodules)
- fixture — (no submodules)
- service-fixture — (no submodules)
- health-poller —
HealthPollerrepeatedly calls aServiceFixture'shealthCheck()method at a configurable interval until the servic… - skip-if-unavailable —
skipIfUnavailablereturns abeforeAll-compatible callback that marks the current test as skipped when the named ser… - create-integration-setup-internal — This module exposes
createIntegrationSetupWithInject()— the dependency-injected core of the public `createIntegratio… - fixture-registry — This module exposes the module-level
fixtureRegistryMap<string, ServiceFixture<Record<string, unknown>>>that brid… - skip-if-unavailable-internal — This module exposes
createSkipIfUnavailableWithInject()— the dependency-injected core of the public `skipIfUnavailab… - create-integration-setup —
createIntegrationSetupis the primary entry point for wiring integration test fixtures into the Vitest global-setup l… - global-setup —
global-setup.tsis the Vitest global-setup module that bridges the fixture registry populated by `createIntegrationSe…
- skip-if-unavailable —
skipIfUnavailablereturns abeforeAll-compatible callback that marks the current test as skipped when the named ser… - create-integration-setup-internal — This module exposes
createIntegrationSetupWithInject()— the dependency-injected core of the public `createIntegratio… - fixture-registry — This module exposes the module-level
fixtureRegistryMap<string, ServiceFixture<Record<string, unknown>>>that brid… - skip-if-unavailable-internal — This module exposes
createSkipIfUnavailableWithInject()— the dependency-injected core of the public `skipIfUnavailab… - create-integration-setup —
createIntegrationSetupis the primary entry point for wiring integration test fixtures into the Vitest global-setup l… - global-setup —
global-setup.tsis the Vitest global-setup module that bridges the fixture registry populated by `createIntegrationSe… - test-environment — (no submodules)- fixture — (no submodules)- service-fixture — (no submodules)- health-poller —
HealthPollerrepeatedly calls aServiceFixture'shealthCheck()method at a configurable interval until the servic… - skip-if-unavailable —
skipIfUnavailablereturns abeforeAll-compatible callback that marks the current test as skipped when the named ser… - create-integration-setup-internal — This module exposes
createIntegrationSetupWithInject()— the dependency-injected core of the public `createIntegratio… - fixture-registry — This module exposes the module-level
fixtureRegistryMap<string, ServiceFixture<Record<string, unknown>>>that brid… - skip-if-unavailable-internal — This module exposes
createSkipIfUnavailableWithInject()— the dependency-injected core of the public `skipIfUnavailab… - create-integration-setup —
createIntegrationSetupis the primary entry point for wiring integration test fixtures into the Vitest global-setup l… - global-setup —
global-setup.tsis the Vitest global-setup module that bridges the fixture registry populated by `createIntegrationSe… - test-environment — (no submodules)- fixture — (no submodules)- service-fixture — (no submodules)- health-poller —
HealthPollerrepeatedly calls aServiceFixture'shealthCheck()method at a configurable interval until the servic… - skip-if-unavailable —
skipIfUnavailablereturns abeforeAll-compatible callback that marks the current test as skipped when the named ser… - create-integration-setup-internal — This module exposes
createIntegrationSetupWithInject()— the dependency-injected core of the public `createIntegratio… - fixture-registry — This module exposes the module-level
fixtureRegistryMap<string, ServiceFixture<Record<string, unknown>>>that brid… - skip-if-unavailable-internal — This module exposes
createSkipIfUnavailableWithInject()— the dependency-injected core of the public `skipIfUnavailab… - create-integration-setup —
createIntegrationSetupis the primary entry point for wiring integration test fixtures into the Vitest global-setup l… - global-setup —
global-setup.tsis the Vitest global-setup module that bridges the fixture registry populated by `createIntegrationSe… - test-environment — (no submodules)- fixture — (no submodules) - service-fixture — (no submodules)- health-poller —
HealthPollerrepeatedly calls aServiceFixture'shealthCheck()method at a configurable interval until the servic… - skip-if-unavailable —
skipIfUnavailablereturns abeforeAll-compatible callback that marks the current test as skipped when the named ser… - create-integration-setup-internal — This module exposes
createIntegrationSetupWithInject()— the dependency-injected core of the public `createIntegratio… - fixture-registry — This module exposes the module-level
fixtureRegistryMap<string, ServiceFixture<Record<string, unknown>>>that brid… - skip-if-unavailable-internal — This module exposes
createSkipIfUnavailableWithInject()— the dependency-injected core of the public `skipIfUnavailab… - create-integration-setup —
createIntegrationSetupis the primary entry point for wiring integration test fixtures into the Vitest global-setup l… - global-setup —
global-setup.tsis the Vitest global-setup module that bridges the fixture registry populated by `createIntegrationSe…
Quick Start
// fixtures/redis.ts
import type { ServiceFixture } from "@suaveplan/testing-integration/fixture/service-fixture";
export const redisFixture: ServiceFixture<{ url: string }> = {
name: "redis",
async start() {
// start your real Redis container or in-process server
return { url: "redis://localhost:6379" };
},
async stop() { /* stop it */ },
async healthCheck() { return true; },
};
// vitest.config.ts
import { defineConfig } from "vitest/config";
import { createIntegrationSetup } from "@suaveplan/testing-integration/setup/create-integration-setup";
import { redisFixture } from "./fixtures/redis.js";
const { globalSetup, inject } = createIntegrationSetup({ redis: redisFixture });
export default defineConfig({ test: { globalSetup: [globalSetup] } });
export { inject };
// redis.test.ts
import { beforeEach } from "vitest";
import { inject } from "../vitest.config.js";
import { skipIfUnavailable } from "@suaveplan/testing-integration/helpers/skip-if-unavailable";
beforeEach(skipIfUnavailable("redis"));
it("reads from redis", async () => {
const { url } = inject("redis"); // typed as { url: string }
// ...
});
Module Reference
| Module | Purpose | Docs |
|---|---|---|
./fixture/service-fixture |
ServiceFixture<TConfig> interface + InferConfig<F> |
service-fixture.md |
./helpers/health-poller |
HealthPoller + TestEnvironmentError |
health-poller.md |
./helpers/skip-if-unavailable |
skipIfUnavailable() + _createSkipIfUnavailableWithInject() |
skip-if-unavailable.md |
./environment/test-environment |
TestEnvironment parallel fixture orchestrator |
test-environment.md |
./setup/create-integration-setup |
createIntegrationSetup() factory + _fixtureRegistry |
create-integration-setup.md |
./setup/global-setup |
Vitest setup/teardown hooks (global-setup module) |
global-setup.md |
Environment Bridge
The package uses two provide/inject keys as an internal implementation detail:
| Key | Type | Description |
|---|---|---|
__integration_configs__ |
Record<string, Record<string, unknown>> |
Config objects keyed by fixture key, populated in global-setup. |
__integration_failed__ |
string[] |
Names of fixtures whose start() threw, used by skipIfUnavailable. |
Do not read these keys directly — use inject(key) from createIntegrationSetup for configs and skipIfUnavailable(name) for skip guards.
Adding a New testing-integration-<service> Plugin
When creating a sibling fixture package (e.g. @suaveplan/testing-integration-clickhouse):
- Mirror the
vite.config.tsof an existing fixture (e.g.testing-integration-redis). Thebuild.rollupOptions.outputblock MUST contain all three ofpreserveModules: true,preserveModulesRoot: "src", andentryFileNames: "[name].js". Without the third line, Vite's lib mode derives the entry filename from the package name and the consumer-facingdist/index.jsis never written — the package will appear to build but fail to resolve from any sibling workspace. - Run
bun run check:fixture-resolvesfrom the repo root to verify the new package resolves. The repo-level CI gate//#check:fixture-resolves(inturbo.json) will fail otherwise.