Files
suaveplan/packages/api-stack/api/create-suaveplan-plugin/tests/scaffold-output/scaffold-output.test.ts
2026-05-27 23:29:53 +01:00

129 lines
4.8 KiB
TypeScript

import {
existsSync,
mkdtempSync,
readFileSync,
rmSync,
statSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { describe, expect, it } from "@suaveplan/testing/runner";
import { SCAFFOLD_CODES, ScaffoldError } from "../../src/error-codes.js";
import { scaffold } from "../../src/generator/generator.js";
import { answersForFixture } from "../../src/prompt/prompt.js";
import { renderTree } from "../../src/templates/templates.js";
const FIXTURE_BY_DIR: Record<
string,
| "trusted-postgres-full"
| "isolated-sqlite-rest-only"
| "sandboxed-none-rest-only"
> = {
"trusted-postgres-full": "trusted-postgres-full",
"isolated-sqlite-rest-only": "isolated-sqlite-rest-only",
"sandboxed-none-rest-only": "sandboxed-none-rest-only",
};
const SNAPSHOT_ROOT = join(import.meta.dirname, "snapshots");
function makeTmp(prefix: string): string {
return mkdtempSync(join(tmpdir(), `${prefix}-`));
}
function readSnapshot(fixtureDir: string, relPath: string): string {
return readFileSync(join(SNAPSHOT_ROOT, fixtureDir, relPath), "utf8");
}
for (const [snapshotDir, fixture] of Object.entries(FIXTURE_BY_DIR)) {
describe(`scaffold-output: ${snapshotDir}`, () => {
it(`${snapshotDir} snapshot match`, { timeout: 30000 }, () => {
const files = renderTree(answersForFixture(fixture, "demo-plugin"));
for (const f of files) {
const expected = readSnapshot(snapshotDir, f.path);
expect(f.content).toBe(expected);
}
});
});
}
describe("scaffold-output: sandboxed-none-rest-only emits no integration / migrations", () => {
it("directories omitted when DB is none", { timeout: 5000 }, () => {
const files = renderTree(
answersForFixture("sandboxed-none-rest-only", "demo-plugin")
);
expect(files.some((f) => f.path.startsWith("tests/integration"))).toBe(
false
);
expect(files.some((f) => f.path.startsWith("migrations/"))).toBe(false);
});
});
describe("scaffold-output: vitest configs use createTestConfig", () => {
it("generated vitest configs use createTestConfig", {
timeout: 5000,
}, () => {
const files = renderTree(
answersForFixture("trusted-postgres-full", "demo-plugin")
);
const cfg = files.find((f) => f.path === "vitest.config.ts");
expect(cfg?.content.includes("@suaveplan/testing/config")).toBe(true);
expect(cfg?.content.includes("createTestConfig")).toBe(true);
expect(cfg?.content.includes("baseVitestConfig")).toBe(false);
const cfgI = files.find(
(f) => f.path === "vitest.integration.config.ts"
);
expect(cfgI?.content.includes("createTestConfig")).toBe(true);
});
});
describe("scaffold-output: postgres selection wires testing-integration-postgres", () => {
it("postgres selection wires testing-integration-postgres", {
timeout: 5000,
}, () => {
const files = renderTree(
answersForFixture("trusted-postgres-full", "demo-plugin")
);
const it_ = files.find(
(f) => f.path === "tests/integration/example.integration.test.ts"
);
expect(
it_?.content.includes("@suaveplan/testing-integration-postgres")
).toBe(true);
expect(it_?.content.includes("INTEGRATION")).toBe(true);
});
});
describe("scaffold-output: pre-existing directory refuses without force", () => {
it("pre-existing directory raises without force", { timeout: 5000 }, () => {
const root = makeTmp("scaffold-out-exists");
const answers = answersForFixture("sandboxed-none-rest-only", "demo");
// First write succeeds.
scaffold({ answers, targetDir: root, force: true });
// Second write without --force raises.
try {
expect(() => scaffold({ answers, targetDir: root })).toThrowError(
ScaffoldError
);
try {
scaffold({ answers, targetDir: root });
} catch (err) {
expect((err as ScaffoldError).code).toBe(
SCAFFOLD_CODES.DIRECTORY_EXISTS
);
}
} finally {
rmSync(root, { recursive: true, force: true });
}
});
it("--force overwrites prior files", { timeout: 5000 }, () => {
const root = makeTmp("scaffold-out-force");
const answers = answersForFixture("sandboxed-none-rest-only", "demo");
scaffold({ answers, targetDir: root, force: true });
scaffold({ answers, targetDir: root, force: true });
expect(existsSync(join(root, "plugin.json"))).toBe(true);
expect(statSync(join(root, "plugin.json")).isFile()).toBe(true);
rmSync(root, { recursive: true, force: true });
});
});