db: add TestDB module

This commit is contained in:
Alex Gleason 2025-03-03 12:21:02 -06:00
parent a21ec4600a
commit 14b809b1e8
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
3 changed files with 75 additions and 0 deletions

View file

@ -0,0 +1,25 @@
import { DittoConf } from '@ditto/conf';
import { NPostgres } from '@nostrify/db';
import { genEvent } from '@nostrify/nostrify/test';
import { assertEquals } from '@std/assert';
import { DittoPolyPg } from './DittoPolyPg.ts';
import { TestDB } from './TestDB.ts';
Deno.test('TestDB', async () => {
const conf = new DittoConf(Deno.env);
const orig = new DittoPolyPg(conf.databaseUrl);
await using db = new TestDB(orig);
await db.migrate();
await db.clear();
const store = new NPostgres(orig.kysely);
await store.event(genEvent());
assertEquals((await store.count([{}])).count, 1);
await db.clear();
assertEquals((await store.count([{}])).count, 0);
});

View file

@ -0,0 +1,49 @@
import { type Kysely, sql } from 'kysely';
import type { DittoDB } from '../DittoDB.ts';
import type { DittoTables } from '../DittoTables.ts';
/** Wraps another DittoDB implementation to clear all data when disposed. */
export class TestDB implements DittoDB {
constructor(private db: DittoDB) {}
get kysely(): Kysely<DittoTables> {
return this.db.kysely;
}
get poolSize(): number {
return this.db.poolSize;
}
get availableConnections(): number {
return this.db.availableConnections;
}
migrate(): Promise<void> {
return this.db.migrate();
}
listen(channel: string, callback: (payload: string) => void): void {
return this.db.listen(channel, callback);
}
/** Truncate all tables. */
async clear(): Promise<void> {
const query = sql<{ tablename: string }>`select tablename from pg_tables where schemaname = current_schema()`;
const { rows } = await query.execute(this.db.kysely);
for (const { tablename } of rows) {
if (tablename.startsWith('kysely_')) {
continue; // Skip Kysely's internal tables
} else {
await sql`truncate table ${sql.ref(tablename)} cascade`.execute(this.db.kysely);
}
}
}
async [Symbol.asyncDispose](): Promise<void> {
await this.clear();
await this.db[Symbol.asyncDispose]();
}
}

View file

@ -2,6 +2,7 @@ export { DittoPglite } from './adapters/DittoPglite.ts';
export { DittoPolyPg } from './adapters/DittoPolyPg.ts'; export { DittoPolyPg } from './adapters/DittoPolyPg.ts';
export { DittoPostgres } from './adapters/DittoPostgres.ts'; export { DittoPostgres } from './adapters/DittoPostgres.ts';
export { DummyDB } from './adapters/DummyDB.ts'; export { DummyDB } from './adapters/DummyDB.ts';
export { TestDB } from './adapters/TestDB.ts';
export type { DittoDB } from './DittoDB.ts'; export type { DittoDB } from './DittoDB.ts';
export type { DittoTables } from './DittoTables.ts'; export type { DittoTables } from './DittoTables.ts';