Files
HiveGrid-Wireframes/hivegrid-cloud/scripts/scan-removed-modules.test.ts
T

128 lines
5.8 KiB
TypeScript

import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import {
collectRemovedModuleSourceFiles,
findRemovedModuleMatches,
renderRemovedModuleScanResult,
scanRemovedModules,
} from "./scan-removed-modules.ts";
const tempRoots: string[] = [];
async function createFixtureRoot() {
const root = await mkdtemp(path.join(os.tmpdir(), "removed-modules-"));
tempRoots.push(root);
return root;
}
async function writeFixtureFile(root: string, relativePath: string, content: string) {
const absolutePath = path.join(root, relativePath);
await mkdir(path.dirname(absolutePath), { recursive: true });
await writeFile(absolutePath, content, "utf8");
return absolutePath;
}
afterEach(async () => {
await Promise.all(tempRoots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
});
describe("removed-module scanner", () => {
it("passes for clean runtime roots and reports observability counters", async () => {
const root = await createFixtureRoot();
await writeFixtureFile(root, "apps/web/app/root.tsx", "export const Root = () => null;\n");
await writeFixtureFile(root, "apps/worker/index.mjs", "export const worker = true;\n");
await writeFixtureFile(root, "packages/core/manifest.json", "{\"name\":\"core\"}\n");
const result = await scanRemovedModules(root);
const output = renderRemovedModuleScanResult(result);
expect(result.roots).toEqual(["apps", "packages"]);
expect(result.missingRoots).toEqual([]);
expect(result.files).toEqual(["apps/web/app/root.tsx", "apps/worker/index.mjs", "packages/core/manifest.json"]);
expect(result.diagnostics).toEqual([]);
expect(output).toContain("PASS removed-module scan");
expect(output).toContain("files scanned: 3");
expect(output).toContain("matches found: 0");
});
it("detects each forbidden runtime group with path, line, and excerpt", async () => {
const root = await createFixtureRoot();
await writeFixtureFile(
root,
"app/runtime.ts",
[
"const mailer = 'postmark';",
"const referral = 'Rewardful';",
"const block = 'PageBlocks';",
"const demo = 'my-site-demo';",
].join("\n"),
);
const result = await scanRemovedModules(root, ["app"]);
expect(result.diagnostics).toEqual([
{ id: "postmark", file: "app/runtime.ts", line: 1, excerpt: "const mailer = 'postmark';" },
{ id: "rewardful", file: "app/runtime.ts", line: 2, excerpt: "const referral = 'Rewardful';" },
{ id: "pageblocks", file: "app/runtime.ts", line: 3, excerpt: "const block = 'PageBlocks';" },
{ id: "site-demo", file: "app/runtime.ts", line: 4, excerpt: "const demo = 'my-site-demo';" },
]);
expect(renderRemovedModuleScanResult(result)).toContain("app/runtime.ts:4: [site-demo] const demo = 'my-site-demo';");
});
it("detects supported site-demo spellings and singular PageBlock", () => {
const diagnostics = findRemovedModuleMatches("Site-Demo\nsite demo\ndemo site\nSiteDemo\nPageBlock\n", "app/demo.ts");
expect(diagnostics.map((diagnostic) => diagnostic.id)).toEqual(["site-demo", "site-demo", "site-demo", "site-demo", "pageblocks"]);
});
it("ignores dependency, build, generated, cache, TC, optional plugin, test, fixture, story, and mock paths", async () => {
const root = await createFixtureRoot();
await writeFixtureFile(root, "app/entry.ts", "export const entry = true;\n");
await writeFixtureFile(root, "app/node_modules/pkg/index.ts", "postmark\n");
await writeFixtureFile(root, "app/build/server.js", "rewardful\n");
await writeFixtureFile(root, "app/.cache/cache.ts", "PageBlocks\n");
await writeFixtureFile(root, "app/.tc/plan.ts", "SiteDemo\n");
await writeFixtureFile(root, "app/generated/client.ts", "postmark\n");
await writeFixtureFile(root, "app/component.test.ts", "rewardful\n");
await writeFixtureFile(root, "app/component.stories.tsx", "PageBlocks\n");
await writeFixtureFile(root, "app/fixtures/data.ts", "demo site\n");
await writeFixtureFile(root, "app/__mocks__/mail.ts", "postmark\n");
await writeFixtureFile(root, "packages/plugins/index.ts", "rewardful\n");
await writeFixtureFile(root, "packages/core/types.d.ts", "declare const SiteDemo: string;\n");
await writeFixtureFile(root, "packages/core/bundle.min.js", "postmark\n");
await writeFixtureFile(root, "packages/core/source.js.map", "rewardful\n");
const result = await scanRemovedModules(root, ["app", "packages"]);
expect(result.files).toEqual(["app/entry.ts"]);
expect(result.diagnostics).toEqual([]);
});
it("records absent roots without failing collection", async () => {
const root = await createFixtureRoot();
await writeFixtureFile(root, "packages/core/index.ts", "export const core = true;\n");
const result = await collectRemovedModuleSourceFiles(root, ["app", "apps", "packages"]);
expect(result.roots).toEqual(["packages"]);
expect(result.missingRoots).toEqual(["app", "apps"]);
expect(result.files.map((file) => path.relative(root, file).split(path.sep).join("/"))).toEqual(["packages/core/index.ts"]);
});
it("scans markdown and mdx files inside runtime roots", async () => {
const root = await createFixtureRoot();
await writeFixtureFile(root, "packages/docs/runtime.md", "Legacy PageBlocks reference\n");
await writeFixtureFile(root, "packages/docs/runtime.mdx", "Legacy site demo reference\n");
const result = await scanRemovedModules(root, ["packages"]);
expect(result.diagnostics).toEqual([
{ id: "pageblocks", file: "packages/docs/runtime.md", line: 1, excerpt: "Legacy PageBlocks reference" },
{ id: "site-demo", file: "packages/docs/runtime.mdx", line: 1, excerpt: "Legacy site demo reference" },
]);
});
});