110 lines
2.7 KiB
TypeScript
110 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();
|
|
});
|
|
});
|