import path from 'node:path' import { fileURLToPath } from 'node:url' import { PostgreSqlContainer } from '@testcontainers/postgresql' import type { StartedPostgreSqlContainer } from '@testcontainers/postgresql' import { drizzle } from 'drizzle-orm/node-postgres' import type { NodePgDatabase } from 'drizzle-orm/node-postgres' import { migrate } from 'drizzle-orm/node-postgres/migrator' import * as schema from '#/db/schema.ts' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const migrationsFolder = path.resolve(__dirname, '../../drizzle') export type TestDatabase = { db: NodePgDatabase connectionUri: string stop: () => Promise } // A real, ephemeral Postgres per test file, per the spec's testing // decisions: no in-memory fake, no mocked Drizzle client. export const startTestDatabase = async (): Promise => { const container: StartedPostgreSqlContainer = await new PostgreSqlContainer( 'postgres:16-alpine', ).start() const connectionUri = container.getConnectionUri() const db = drizzle(connectionUri, { schema }) await migrate(db, { migrationsFolder }) return { db, connectionUri, stop: async () => { // End the pg Pool before tearing down the container, or a pending // connection emits an unhandled "terminating connection" error. await db.$client.end() await container.stop() }, } }