Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,200 @@
/**
* Tests for `check-registry-eject.ts`.
*
* Builds fixtures filesystems on disk under `mkdtemp` and exercises
* the exported helpers (`audit`, `loadEntry`) directly. The script's
* `main()` is exercised indirectly through these helpers — its
* top-level behaviour (process.exit) is covered by the lint gate
* itself running on real source.
*/
import { afterEach, beforeEach, describe, expect, it } from "@suaveplan/testing/runner";
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { audit, loadEntry } from "./check-registry-eject.js";
let workDir: string;
beforeEach(async () => {
workDir = await mkdtemp(join(tmpdir(), "registry-eject-"));
});
afterEach(async () => {
await rm(workDir, { recursive: true, force: true });
});
async function writeJson(rel: string, body: unknown): Promise<string> {
const full = join(workDir, rel);
await mkdir(join(full, ".."), { recursive: true });
await writeFile(full, JSON.stringify(body, null, 2), "utf8");
return full;
}
async function writeFixture(rel: string, content = ""): Promise<string> {
const full = join(workDir, rel);
await mkdir(join(full, ".."), { recursive: true });
await writeFile(full, content, "utf8");
return full;
}
describe("loadEntry", () => {
it("loads a valid registry entry", { timeout: 5000 }, async () => {
const entry = await writeJson("button.json", {
name: "@suaveplan/button",
type: "registry:ui",
files: [{ path: "button.tsx", type: "registry:ui" }],
});
const result = await loadEntry(entry);
expect("error" in result).toBe(false);
});
it("rejects an entry without a name", { timeout: 5000 }, async () => {
const entry = await writeJson("bad.json", {
type: "registry:ui",
files: [],
});
const result = await loadEntry(entry);
expect("error" in result).toBe(true);
});
it("rejects an entry with non-array files", {
timeout: 5000,
}, async () => {
const entry = await writeJson("bad.json", {
name: "x",
type: "registry:ui",
files: "oops",
});
const result = await loadEntry(entry);
expect("error" in result).toBe(true);
});
it("rejects malformed JSON", { timeout: 5000 }, async () => {
const entry = await writeFixture("bad.json", "{ not json");
const result = await loadEntry(entry);
expect("error" in result).toBe(true);
});
});
describe("audit", () => {
it("returns no diagnostics on a clean fixtures tree", {
timeout: 5000,
}, async () => {
const componentsDir = join(workDir, "src/components");
await writeFixture("src/components/button/button.tsx", "export {}");
const entry = await writeJson("registry/r/button.json", {
name: "@x/button",
type: "registry:ui",
files: [{ path: "button.tsx", type: "registry:ui" }],
});
const diagnostics = await audit({
registryEntries: [entry],
componentDirs: ["button"],
componentsDir,
});
expect(diagnostics).toEqual([]);
});
it("flags a component directory with no registry entry", {
timeout: 5000,
}, async () => {
const componentsDir = join(workDir, "src/components");
await writeFixture("src/components/button/button.tsx", "export {}");
const diagnostics = await audit({
registryEntries: [],
componentDirs: ["button"],
componentsDir,
});
expect(
diagnostics.find(
(d) => d.kind === "MISSING_REGISTRY_ENTRY"
)?.message
).toMatch(/button/);
});
it("flags a registry entry whose source file is missing", {
timeout: 5000,
}, async () => {
const componentsDir = join(workDir, "src/components");
await mkdir(join(componentsDir, "ghost"), { recursive: true });
const entry = await writeJson("registry/r/ghost.json", {
name: "@x/ghost",
type: "registry:ui",
files: [{ path: "ghost.tsx", type: "registry:ui" }],
});
const diagnostics = await audit({
registryEntries: [entry],
componentDirs: ["ghost"],
componentsDir,
});
expect(
diagnostics.find((d) => d.kind === "MISSING_SOURCE_FILE")?.message
).toMatch(/ghost\.tsx/);
});
it("flags an orphan registry entry (no matching component dir)", {
timeout: 5000,
}, async () => {
const componentsDir = join(workDir, "src/components");
await writeFixture(
"src/components/button/button.tsx",
"export {}"
);
const entryButton = await writeJson("registry/r/button.json", {
name: "@x/button",
type: "registry:ui",
files: [{ path: "button.tsx", type: "registry:ui" }],
});
const entryStale = await writeJson("registry/r/removed.json", {
name: "@x/removed",
type: "registry:ui",
files: [{ path: "removed.tsx", type: "registry:ui" }],
});
const diagnostics = await audit({
registryEntries: [entryButton, entryStale],
componentDirs: ["button"],
componentsDir,
});
expect(
diagnostics.find(
(d) => d.kind === "ORPHAN_REGISTRY_ENTRY"
)?.message
).toMatch(/removed/);
});
it("flags an entry with empty files[]", { timeout: 5000 }, async () => {
const componentsDir = join(workDir, "src/components");
await writeFixture("src/components/foo/foo.tsx", "export {}");
const entry = await writeJson("registry/r/foo.json", {
name: "@x/foo",
type: "registry:ui",
files: [],
});
const diagnostics = await audit({
registryEntries: [entry],
componentDirs: ["foo"],
componentsDir,
});
expect(
diagnostics.find((d) => d.kind === "EMPTY_FILES_LIST")?.message
).toMatch(/foo\.json/);
});
it("flags malformed JSON entries", { timeout: 5000 }, async () => {
const componentsDir = join(workDir, "src/components");
await writeFixture("src/components/foo/foo.tsx", "");
const entry = await writeFixture(
"registry/r/foo.json",
"{ not json"
);
const diagnostics = await audit({
registryEntries: [entry],
componentDirs: ["foo"],
componentsDir,
});
expect(
diagnostics.find((d) => d.kind === "MALFORMED_ENTRY")?.message
).toMatch(/foo\.json/);
});
});