Files
suaveplan/packages/gaming/games/ecs/tests/purity.test.ts
2026-05-27 23:47:53 +01:00

53 lines
1.6 KiB
TypeScript

import { readdir, readFile } from "node:fs/promises";
import { join } from "node:path";
import { describe, expect, it } from "@suaveplan/testing/runner";
const SRC_ROOT = join(__dirname, "..", "src");
const BANNED_PATTERNS = [
/\bfrom\s+["']node:/,
/\bfrom\s+["']fs["']/,
/\bfrom\s+["']path["']/,
/\bfrom\s+["']crypto["']/,
/\brequire\(["']node:/,
/\bprocess\.[a-zA-Z]/,
/\bBuffer\.[a-zA-Z]/,
/\bwindow\./,
/\bdocument\./,
/\bnavigator\./,
];
async function* walk(dir: string): AsyncGenerator<string> {
const entries = await readdir(dir, { withFileTypes: true });
for (const entry of entries) {
const full = join(dir, entry.name);
if (entry.isDirectory()) {
yield* walk(full);
} else if (
entry.isFile() &&
entry.name.endsWith(".ts") &&
!entry.name.endsWith(".test.ts") &&
!entry.name.endsWith(".spec.ts") &&
!entry.name.endsWith(".bench.ts")
) {
yield full;
}
}
}
describe("purity guards", () => {
it("built dist references no Node or browser globals", {
timeout: 5000,
}, async () => {
const offenders: Array<{ file: string; pattern: string }> = [];
for await (const file of walk(SRC_ROOT)) {
const source = await readFile(file, "utf8");
for (const pattern of BANNED_PATTERNS) {
if (pattern.test(source)) {
offenders.push({ file, pattern: pattern.source });
}
}
}
expect(offenders).toEqual([]);
});
});