import { describe, expect, test } from "bun:test"; import type { BUN_MARIADB_TableSchemaType } from "../../types"; import orderDBSchema from "./order-db-schema"; function table({ name, refs = [], }: { name: string; refs?: string[]; }): BUN_MARIADB_TableSchemaType { return { tableName: name, fields: refs.map((ref) => ({ fieldName: `${ref}_id`, dataType: "BIGINT", foreignKey: { destinationTableName: ref, destinationTableColumnName: "id", }, })), }; } async function order(tables: BUN_MARIADB_TableSchemaType[]) { const res = await orderDBSchema({ db_schema: { tables } }); return res.tables.map((t) => t.tableName); } describe("orderDBSchema", () => { test("places parents before children", async () => { expect( await order([ table({ name: "comments", refs: ["posts", "users"] }), table({ name: "posts", refs: ["users"] }), table({ name: "users" }), ]), ).toEqual(["users", "posts", "comments"]); }); test("keeps declaration order when there are no dependencies", async () => { expect( await order([table({ name: "b" }), table({ name: "a" })]), ).toEqual(["b", "a"]); }); test("handles self references without recursing forever", async () => { expect( await order([ table({ name: "categories", refs: ["categories"] }), table({ name: "comments", refs: ["comments", "users"] }), table({ name: "users" }), ]), ).toEqual(["categories", "users", "comments"]); }); test("handles cycles and emits each table once", async () => { const res = await order([ table({ name: "a", refs: ["b"] }), table({ name: "b", refs: ["a"] }), table({ name: "c", refs: ["a"] }), ]); expect(res).toHaveLength(3); expect(new Set(res).size).toBe(3); expect(res.indexOf("c")).toBeGreaterThan(res.indexOf("a")); }); test("ignores references to tables outside the schema", async () => { expect( await order([table({ name: "posts", refs: ["external_users"] })]), ).toEqual(["posts"]); }); });