Files
suaveplan/packages/ui/react/react-audio/tests/purity.test.ts
2026-05-27 23:47:53 +01:00

78 lines
2.4 KiB
TypeScript

import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
import { join, resolve } from "node:path";
import { describe, expect, it } from "@suaveplan/testing/runner";
const PKG_ROOT = resolve(__dirname, "..");
const DIST = join(PKG_ROOT, "dist");
const ALLOWED_RUNTIME_DEPS = new Set([
"@suaveplan/audio-controllers",
"@suaveplan/audio-engine-browser",
"@suaveplan/audio-fx-plugin-audio-player",
"@suaveplan/audio-fx-plugin-base",
"@suaveplan/audio-fx-plugin-glados",
"@suaveplan/audio-fx-plugin-microphone",
"@suaveplan/audio-fx-plugin-mixer",
"@suaveplan/audio-timeline",
"@suaveplan/audio-transport",
"@suaveplan/error",
"@suaveplan/events",
"@suaveplan/opentelemetry",
"@suaveplan/types",
"tslib",
"zod",
"zustand",
]);
function walk(dir: string, out: string[] = []): string[] {
if (!existsSync(dir)) return out;
for (const name of readdirSync(dir)) {
const p = join(dir, name);
if (statSync(p).isDirectory()) walk(p, out);
else if (/\.(js|mjs|cjs)$/.test(name)) out.push(p);
}
return out;
}
describe("react-audio purity gates", () => {
it("runtime dependency set matches the allowlist", {
timeout: 5000,
}, () => {
const pkg = JSON.parse(
readFileSync(join(PKG_ROOT, "package.json"), "utf8")
) as { dependencies?: Record<string, string> };
const deps = Object.keys(pkg.dependencies ?? {});
for (const dep of deps) {
expect(ALLOWED_RUNTIME_DEPS.has(dep)).toBe(true);
}
for (const allowed of ALLOWED_RUNTIME_DEPS) {
expect(deps.includes(allowed)).toBe(true);
}
});
it("dist references no audio context or Node globals", {
timeout: 30000,
}, () => {
if (!existsSync(DIST)) {
// Skip pre-build — `bunx turbo build` will rerun.
return;
}
const files = walk(DIST);
const forbidden = [
/\bnew\s+AudioContext\b/,
/\bnew\s+OfflineAudioContext\b/,
/\binstanceof\s+AudioNode\b/,
/['"]node:fs['"]/,
/['"]node:path['"]/,
/\bprocess\.env\b/,
/\bBuffer\.from\b/,
];
for (const file of files) {
const text = readFileSync(file, "utf8");
for (const rx of forbidden) {
expect(rx.test(text)).toBe(false);
}
}
});
});