Initial Commit
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Schema discovery integration test — verifies the filesystem-based
|
||||
* `discoverSchemas` pipeline against the live SurrealDB v3.0.4 engine.
|
||||
*
|
||||
* Spec: `openspec/changes/surrealdb-integration-tests/specs/database-surrealdb-integration/spec.md`
|
||||
* Requirement "Schema discovery verified against the real engine"
|
||||
*
|
||||
* WHEN `DEFINE TABLE a SCHEMAFULL FIELD x TYPE string` and
|
||||
* `DEFINE TABLE b SCHEMAFULL FIELD y TYPE int` have been executed
|
||||
* THEN discovery returns both `a` and `b`, with `a.x: string` and
|
||||
* `b.y: int`.
|
||||
*
|
||||
* Strategy: write two `.surql` files into a tmpdir, run `discoverSchemas` to
|
||||
* enumerate them, apply each file's contents via the adapter against an
|
||||
* isolated namespace/database, then introspect the engine via `INFO FOR DB`
|
||||
* and `INFO FOR TABLE` to assert the tables and field types are present.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import {
|
||||
discoverSchemas,
|
||||
readSchemaContent,
|
||||
} from "../../src/schema/discovery.js";
|
||||
import { connectAdapter } from "./helpers/connect.js";
|
||||
import { randomNamespace } from "./helpers/random-ns.js";
|
||||
import { surrealUnavailable } from "./integration-setup.js";
|
||||
|
||||
describe.skipIf(surrealUnavailable)(
|
||||
"SurrealDB schema discovery (real SurrealDB v3.0.4)",
|
||||
() => {
|
||||
it("lists every defined table and field with the expected type", async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), "surreal-discovery-int-"));
|
||||
const ns = randomNamespace();
|
||||
const { adapter } = await connectAdapter({
|
||||
namespaceOverride: ns,
|
||||
databaseOverride: ns,
|
||||
});
|
||||
try {
|
||||
await writeFile(
|
||||
join(dir, "schema.surql"),
|
||||
"DEFINE TABLE a SCHEMAFULL;\nDEFINE FIELD x ON a TYPE string;"
|
||||
);
|
||||
await writeFile(
|
||||
join(dir, "tables.surql"),
|
||||
"DEFINE TABLE b SCHEMAFULL;\nDEFINE FIELD y ON b TYPE int;"
|
||||
);
|
||||
|
||||
const files = await discoverSchemas(dir);
|
||||
expect(files.map((f) => f.name)).toEqual(["schema", "tables"]);
|
||||
|
||||
for (const file of files) {
|
||||
const content = await readSchemaContent(file);
|
||||
for (const stmt of content
|
||||
.split(";")
|
||||
.map((s) => s.trim())
|
||||
.filter((s) => s.length > 0)) {
|
||||
await adapter.execute(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
const dbInfo =
|
||||
await adapter.query<Record<string, unknown>>("INFO FOR DB");
|
||||
expect(dbInfo.length).toBeGreaterThan(0);
|
||||
const tables = (dbInfo[0]?.tables ?? {}) as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
expect(tables.a).toBeDefined();
|
||||
expect(tables.b).toBeDefined();
|
||||
|
||||
const tableA =
|
||||
await adapter.query<Record<string, unknown>>(
|
||||
"INFO FOR TABLE a"
|
||||
);
|
||||
const fieldsA = (tableA[0]?.fields ?? {}) as Record<
|
||||
string,
|
||||
string
|
||||
>;
|
||||
expect(fieldsA.x).toBeDefined();
|
||||
expect(fieldsA.x).toMatch(/string/i);
|
||||
|
||||
const tableB =
|
||||
await adapter.query<Record<string, unknown>>(
|
||||
"INFO FOR TABLE b"
|
||||
);
|
||||
const fieldsB = (tableB[0]?.fields ?? {}) as Record<
|
||||
string,
|
||||
string
|
||||
>;
|
||||
expect(fieldsB.y).toBeDefined();
|
||||
expect(fieldsB.y).toMatch(/int/i);
|
||||
} finally {
|
||||
await adapter.disconnect();
|
||||
await rm(dir, { recursive: true, force: true });
|
||||
}
|
||||
}, 30000);
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user