111 lines
3.7 KiB
TypeScript
111 lines
3.7 KiB
TypeScript
import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { afterEach, beforeEach, describe, expect, it } from "bun:test";
|
|
import {
|
|
banReason,
|
|
checkWasmSubpathDeps,
|
|
extractSpecifiers,
|
|
} from "./check-wasm-subpath-deps.js";
|
|
|
|
let tmp: string;
|
|
|
|
beforeEach(async () => {
|
|
tmp = await mkdtemp(join(tmpdir(), "wasm-deps-"));
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await rm(tmp, { recursive: true, force: true });
|
|
});
|
|
|
|
async function writeFixture(rel: string, content: string): Promise<string> {
|
|
const full = join(tmp, rel);
|
|
await mkdir(join(full, ".."), { recursive: true });
|
|
await writeFile(full, content, "utf8");
|
|
return full;
|
|
}
|
|
|
|
describe("check-wasm-subpath-deps", () => {
|
|
it("banReason flags node: specifiers", { timeout: 5000 }, () => {
|
|
expect(banReason("node:fs")).toMatch(/node:/);
|
|
});
|
|
|
|
it("banReason flags exact bans", { timeout: 5000 }, () => {
|
|
expect(banReason("hono")).toMatch(/banned package/);
|
|
expect(banReason("@suaveplan/api-host")).toMatch(/banned package/);
|
|
});
|
|
|
|
it("banReason flags prefix bans", { timeout: 5000 }, () => {
|
|
expect(banReason("@hono/zod-validator")).toMatch(/banned prefix/);
|
|
expect(banReason("@opentelemetry/sdk-metrics")).toMatch(
|
|
/banned prefix/
|
|
);
|
|
expect(banReason("@opentelemetry/sdk-trace-base")).toMatch(
|
|
/banned prefix/
|
|
);
|
|
});
|
|
|
|
it("banReason passes safe specifiers", { timeout: 5000 }, () => {
|
|
expect(banReason("@opentelemetry/api")).toBeNull();
|
|
expect(banReason("zod")).toBeNull();
|
|
expect(banReason("@suaveplan/error")).toBeNull();
|
|
});
|
|
|
|
it("extractSpecifiers picks up named, default, and type imports", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const src = `
|
|
import x from "a";
|
|
import { b } from "b";
|
|
import type { C } from "c";
|
|
export { d } from "d";
|
|
// import "ignored-in-comment";
|
|
`;
|
|
const out = extractSpecifiers(src);
|
|
expect(out).toContain("a");
|
|
expect(out).toContain("b");
|
|
expect(out).toContain("c");
|
|
expect(out).toContain("d");
|
|
expect(out).not.toContain("ignored-in-comment");
|
|
});
|
|
|
|
it("rejects banned specifier in wasm subpath", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
// Build a tiny fixture: entry imports "hono" directly.
|
|
const entry = await writeFixture(
|
|
"packages/example/wasm/index.ts",
|
|
`import { Hono } from "hono";\nexport const app = new Hono();\n`
|
|
);
|
|
const hits = await checkWasmSubpathDeps({ repoRoot: tmp, entry });
|
|
expect(hits.length).toBeGreaterThan(0);
|
|
const hononHit = hits.find((h) => h.specifier === "hono");
|
|
expect(hononHit).toBeDefined();
|
|
});
|
|
|
|
it("accepts a clean entry with only allowed specifiers", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
const entry = await writeFixture(
|
|
"packages/example/wasm/index.ts",
|
|
`import z from "zod";\nimport { foo } from "./foo.js";\n`
|
|
);
|
|
await writeFixture(
|
|
"packages/example/wasm/foo.ts",
|
|
"export const foo = 1;\n"
|
|
);
|
|
const hits = await checkWasmSubpathDeps({ repoRoot: tmp, entry });
|
|
expect(hits).toEqual([]);
|
|
});
|
|
|
|
it("detects node:* specifier in entry", { timeout: 5000 }, async () => {
|
|
const entry = await writeFixture(
|
|
"packages/example/wasm/index.ts",
|
|
`import fs from "node:fs";\n`
|
|
);
|
|
const hits = await checkWasmSubpathDeps({ repoRoot: tmp, entry });
|
|
expect(hits.length).toBeGreaterThan(0);
|
|
expect(hits[0]?.specifier).toBe("node:fs");
|
|
});
|
|
});
|