62 lines
1.8 KiB
TypeScript
62 lines
1.8 KiB
TypeScript
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { describe, expect, test } from "vitest";
|
|
|
|
const presentationRoots = [
|
|
join(process.cwd(), "src", "lib", "ui"),
|
|
join(process.cwd(), "src", "routes"),
|
|
];
|
|
|
|
const forbiddenTerms = [
|
|
"dimensionlab",
|
|
"dimension lab",
|
|
"vaultwarden",
|
|
"forgejo",
|
|
"grafana",
|
|
"uptime kuma",
|
|
"prometheus",
|
|
"backrest",
|
|
"open webui",
|
|
"comfyui",
|
|
"adminer",
|
|
"cockpit",
|
|
"ollama",
|
|
"dimensionlab.net",
|
|
];
|
|
|
|
describe("presentation content boundary", () => {
|
|
test("keeps environment-specific content out of route and UI implementation", () => {
|
|
const source = presentationRoots.map(readPresentationSource).join("\n").toLowerCase();
|
|
|
|
expect(forbiddenTerms.filter((term) => source.includes(term))).toEqual([]);
|
|
});
|
|
|
|
test("does not keep legacy presentation component files in the React runtime", () => {
|
|
const legacyExtension = [".sve", "lte"].join("");
|
|
|
|
expect(findFiles(join(process.cwd(), "src"), legacyExtension)).toEqual([]);
|
|
});
|
|
});
|
|
|
|
function readPresentationSource(path: string): string {
|
|
if (!existsSync(path)) return "";
|
|
|
|
const stats = statSync(path);
|
|
if (stats.isFile()) {
|
|
if (path.endsWith(".test.ts")) return "";
|
|
if (path.includes(`${join("src", "lib", "ui", "stories")}${"/"}`)) return "";
|
|
if (!/\.(tsx|ts|js|mjs|css|json)$/.test(path)) return "";
|
|
return readFileSync(path, "utf8");
|
|
}
|
|
|
|
return readdirSync(path)
|
|
.map((entry) => readPresentationSource(join(path, entry)))
|
|
.join("\n");
|
|
}
|
|
|
|
function findFiles(path: string, extension: string): string[] {
|
|
const stats = statSync(path);
|
|
if (stats.isFile()) return path.endsWith(extension) ? [path] : [];
|
|
|
|
return readdirSync(path).flatMap((entry) => findFiles(join(path, entry), extension));
|
|
}
|