Initial Commit
This commit is contained in:
200
packages/ui/react/react-ui/scripts/check-registry-eject.test.ts
Normal file
200
packages/ui/react/react-ui/scripts/check-registry-eject.test.ts
Normal 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/);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user