import { describe, expect, test } from "bun:test"; import { createDatabase, type Database } from "../modules/database/src/index.ts"; import { Field } from "../modules/database/src/decorators/Field.ts"; import { Hydrate } from "../modules/database/src/decorators/Hydrate.ts"; import { Table } from "../modules/database/src/decorators/Table.ts"; /** * Tests of the postgres adapter. * * The tests need a database, the connection string is read from * `DATABASE_URL`. Without it the suite is skipped. */ const url = process.env.DATABASE_URL; @Table("muddle_users") class User { @Field({ type: "text", primary: true }) id: string; @Field({ type: "text", unique: true, encode: (value: string) => value.trim().toLowerCase(), }) email: string; @Field({ type: "text", nullable: true, encode: (value: string | null) => value?.trim() ?? null, }) name: string | null; @Field({ type: "int", default: 0 }) age: number; @Field({ type: "bool", default: false }) active: boolean; @Hydrate({ decode: (row) => String(row.email).split("@")[1] ?? "" }) domain: string; } async function database(): Promise { const db = createDatabase({ dialect: "postgres", url }); db.model(User); await db.migrate(); return db; } describe.skipIf(!url)("postgres", () => { test("creates the table of a model", async () => { const db = await database(); const rows = await db.model(User).query( "SELECT table_name FROM information_schema.tables WHERE table_name = 'muddle_users'", ); expect(rows).toHaveLength(1); await db.close(); }); test("inserts, reads, updates and deletes", async () => { const db = await database(); const users = db.model(User); await users.where("id", "1").delete(); await users.create({ id: "1", email: " ADA@Example.COM ", name: " Ada ", age: 36, active: true, }); const found = await users.where("id", "1").first(); expect(found?.email).toBe("ada@example.com"); expect(found?.name).toBe("Ada"); expect(found?.active).toBe(true); expect(found?.domain).toBe("example.com"); expect(await users.where("id", "1").update({ age: 37 })).toBe(1); expect((await users.where("id", "1").first())?.age).toBe(37); expect(await users.where("id", "1").delete()).toBe(1); await db.close(); }); test("counts and filters rows", async () => { const db = await database(); const users = db.model(User); await users.where("id", "2").delete(); await users.create({ id: "2", email: "grace@example.com", name: "Grace", age: 45, }); expect(await users.count()).toBeGreaterThan(0); expect(await users.where("age", ">", 40).count()).toBeGreaterThan(0); await users.where("id", "2").delete(); await db.close(); }); });