# `createInMemorySqliteHarness` _(no submodules)_ ## Purpose Convenience builder for plugin test files. Wraps `createSqliteMemoryDb` with an idempotent `cleanup()` so the canonical `beforeEach` / `afterEach` pair stays one line each. The result conforms to `SqliteMemoryDb` so callers can treat the harness exactly like a direct factory return value, with the bonus that double-cleanup is safe — the second call observes the `closed` flag and returns without touching the database. This is the entry point Stage-5 plugin tests should reach for. Direct construction via `createSqliteMemoryDb` works too, but the harness keeps the test boilerplate uniform across packages. ## Features - Same shape as `SqliteMemoryDb` plus an extra `cleanup` method. - Idempotent `cleanup` — safe to call from both an explicit teardown and a try/finally. - Forwards every `SqliteMemoryDbOptions` field to `createSqliteMemoryDb`. ## Usage: Basic ```ts import { afterEach, beforeEach, it } from "@suaveplan/testing/runner"; import { createInMemorySqliteHarness, type InMemorySqliteHarness, } from "@suaveplan/api-db-sqlite-memory/testing"; let harness: InMemorySqliteHarness; beforeEach(() => { harness = createInMemorySqliteHarness(); }); afterEach(() => harness.cleanup()); it("inserts a row", { timeout: 5000 }, async () => { await harness.admin.execute( "CREATE TABLE t (id INTEGER PRIMARY KEY, tenant_id TEXT)" ); }); ``` ## Usage: Advanced Customise the tenant column + open a file-backed fixture for a longer-lived test: ```ts import { createInMemorySqliteHarness } from "@suaveplan/api-db-sqlite-memory/testing"; const harness = createInMemorySqliteHarness({ filename: "/tmp/long-fixture.sqlite", tenantColumn: "org_id", }); try { await harness.admin.execute( "CREATE TABLE items (id INTEGER PRIMARY KEY, org_id TEXT)" ); } finally { await harness.cleanup(); } ``` ## API Reference - `createInMemorySqliteHarness(options?)` — returns `InMemorySqliteHarness`. - `InMemorySqliteHarness` — extends `SqliteMemoryDb` with `cleanup(): Promise`. ## Implementation Notes `cleanup()` and `close()` share the same idempotency flag — the harness owns the `closed` boolean and the `close()` method on the embedded `SqliteMemoryDb` is exposed verbatim so legacy code that still calls `close` does not silently bypass the flag. This matters when a test file mixes a manual `close()` with an `afterEach` cleanup: the second of the two is a guaranteed no-op rather than a hard error from `bun:sqlite`'s "database already closed" path.