Files
2026-07-12 15:55:18 +05:30

78 lines
2.8 KiB
TypeScript

/**
* Live Postgres/MySQL integration tests. These are GATED on env vars so the
* normal `bun test` run stays green without a database:
*
* WRNEXUS_PG_URL=postgres://… WRNEXUS_MYSQL_URL=mysql://… bun test packages/db
*
* The `bun run test:db:live` script spins up both via docker-compose, sets the
* env vars, runs this file, and tears the containers down.
*/
import { test, expect } from "bun:test";
import { v, table, createDb, createTableSql, paginate, type Dialect } from "../src/index.ts";
import { bunSql } from "../src/adapters/bunsql.ts";
const users = table<{ id: number; email: string; name: string; active: boolean }>("users", {
id: v.id(),
email: v.string().unique(),
name: v.string(),
active: v.boolean().default(true),
});
const targets: { dialect: Dialect; url: string }[] = [];
if (process.env.WRNEXUS_PG_URL)
targets.push({ dialect: "postgres", url: process.env.WRNEXUS_PG_URL });
if (process.env.WRNEXUS_MYSQL_URL)
targets.push({ dialect: "mysql", url: process.env.WRNEXUS_MYSQL_URL });
const ph = (dialect: Dialect, i: number) => (dialect === "postgres" ? `$${i}` : "?");
if (targets.length === 0) {
test.skip("live PG/MySQL (set WRNEXUS_PG_URL / WRNEXUS_MYSQL_URL to run)", () => {});
} else {
for (const { dialect, url } of targets) {
test(`${dialect}: DDL + CRUD + transaction + pagination`, async () => {
const db = createDb(bunSql(url, dialect));
try {
await db.exec("DROP TABLE IF EXISTS users");
await db.exec(createTableSql(users, dialect));
for (let i = 1; i <= 5; i++) {
await db.exec(
`INSERT INTO users (email, name, active) VALUES (${ph(dialect, 1)}, ${ph(dialect, 2)}, ${ph(dialect, 3)})`,
[`u${i}@x.com`, `U${i}`, true],
);
}
const count = await db.one<{ n: number | string }>("SELECT COUNT(*) AS n FROM users");
expect(Number(count?.n)).toBe(5);
// Transaction rollback leaves the table unchanged.
await db
.tx(async (t) => {
await t.exec(
`INSERT INTO users (email, name, active) VALUES (${ph(dialect, 1)}, ${ph(dialect, 2)}, ${ph(dialect, 3)})`,
["rollback@x.com", "R", true],
);
throw new Error("rollback");
})
.catch(() => {});
const after = await db.one<{ n: number | string }>("SELECT COUNT(*) AS n FROM users");
expect(Number(after?.n)).toBe(5);
const page = await paginate(
db,
{ sql: "SELECT * FROM users ORDER BY id", model: users },
{ page: 1, perPage: 2 },
);
expect(page.total).toBe(5);
expect(page.totalPages).toBe(3);
expect(page.items.length).toBe(2);
await db.exec("DROP TABLE IF EXISTS users");
} finally {
await db.close();
}
});
}
}