muddle/tests/postgres.test.ts
2026-10-23 08:53:07 -04:00

105 lines
2.7 KiB
TypeScript

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<Database> {
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();
});
});