Initial Commit
This commit is contained in:
91
packages/media/audio/audio-cli/tests/purity.test.ts
Normal file
91
packages/media/audio/audio-cli/tests/purity.test.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { readdir, readFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
|
||||
const PKG_ROOT = join(__dirname, "..");
|
||||
const SRC = join(PKG_ROOT, "src");
|
||||
|
||||
// Match a *use* of the global as a free identifier (assignment, property access,
|
||||
// or function call), not occurrences inside compound identifiers like `AudioDocument`.
|
||||
const BROWSER_GLOBALS = [
|
||||
"window",
|
||||
"document",
|
||||
"navigator",
|
||||
"AudioContext",
|
||||
"AudioBuffer",
|
||||
];
|
||||
|
||||
function stripCommentsAndStrings(src: string): string {
|
||||
// Drop /* ... */, // ..., and "..." / '...' content so we only see code.
|
||||
return src
|
||||
.replace(/\/\*[\s\S]*?\*\//g, " ")
|
||||
.replace(/\/\/[^\n]*/g, " ")
|
||||
.replace(/"(?:[^"\\]|\\.)*"/g, '""')
|
||||
.replace(/'(?:[^'\\]|\\.)*'/g, "''");
|
||||
}
|
||||
|
||||
function refersToGlobal(src: string, name: string): boolean {
|
||||
const code = stripCommentsAndStrings(src);
|
||||
// Token must start after a non-identifier char and be followed by a
|
||||
// property access (.), call site (() or [), assignment (= but not ==),
|
||||
// semicolon, comma, or close paren.
|
||||
const re = new RegExp(
|
||||
`(?:^|[^A-Za-z0-9_.])${name}(?=[.(\\[]|\\s*=[^=])`,
|
||||
"m"
|
||||
);
|
||||
return re.test(code);
|
||||
}
|
||||
|
||||
async function* walk(dir: string): AsyncGenerator<string> {
|
||||
const entries = await readdir(dir, { withFileTypes: true });
|
||||
for (const e of entries) {
|
||||
const full = join(dir, e.name);
|
||||
if (e.isDirectory()) yield* walk(full);
|
||||
else if (
|
||||
e.isFile() &&
|
||||
e.name.endsWith(".ts") &&
|
||||
!e.name.endsWith(".test.ts")
|
||||
)
|
||||
yield full;
|
||||
}
|
||||
}
|
||||
|
||||
describe("audio-cli purity", () => {
|
||||
it("source references no browser-only globals", {
|
||||
timeout: 5000,
|
||||
}, async () => {
|
||||
for await (const path of walk(SRC)) {
|
||||
const src = await readFile(path, "utf8");
|
||||
for (const global of BROWSER_GLOBALS) {
|
||||
expect(
|
||||
refersToGlobal(src, global),
|
||||
`${path} references ${global}`
|
||||
).toBe(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("declared dependency set is limited to the spec list", {
|
||||
timeout: 5000,
|
||||
}, async () => {
|
||||
const raw = await readFile(join(PKG_ROOT, "package.json"), "utf8");
|
||||
const pkg = JSON.parse(raw) as {
|
||||
dependencies?: Record<string, string>;
|
||||
};
|
||||
const allowed = new Set([
|
||||
"@suaveplan/audio-codecs",
|
||||
"@suaveplan/audio-core",
|
||||
"@suaveplan/audio-engine-server",
|
||||
"@suaveplan/error",
|
||||
"@suaveplan/types",
|
||||
"@opentelemetry/api",
|
||||
"tslib",
|
||||
"zod",
|
||||
]);
|
||||
for (const dep of Object.keys(pkg.dependencies ?? {})) {
|
||||
expect(allowed.has(dep), `unexpected runtime dep ${dep}`).toBe(
|
||||
true
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user