plan/react-rewrite #1
@@ -0,0 +1,80 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { execSync } from "node:child_process";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import crypto from "node:crypto";
|
||||
|
||||
const ROOT = path.resolve(import.meta.dirname, "../..");
|
||||
|
||||
/** Short random suffix to avoid collisions when tests run in parallel. */
|
||||
function uid(): string {
|
||||
return crypto.randomBytes(4).toString("hex");
|
||||
}
|
||||
|
||||
function lintString(filePath: string, content: string): string {
|
||||
const absPath = path.join(ROOT, filePath);
|
||||
fs.mkdirSync(path.dirname(absPath), { recursive: true });
|
||||
fs.writeFileSync(absPath, content, "utf8");
|
||||
try {
|
||||
execSync(`pnpm exec eslint "${absPath}" --format json`, {
|
||||
cwd: ROOT,
|
||||
encoding: "utf8",
|
||||
stdio: ["pipe", "pipe", "pipe"],
|
||||
});
|
||||
return "PASS";
|
||||
} catch (err: unknown) {
|
||||
const error = err as { stdout?: string };
|
||||
return error.stdout ?? "UNKNOWN_ERROR";
|
||||
} finally {
|
||||
fs.unlinkSync(absPath);
|
||||
// Remove empty parent directories created for probes
|
||||
let dir = path.dirname(absPath);
|
||||
const srcDir = path.join(ROOT, "src");
|
||||
while (dir.length > srcDir.length) {
|
||||
try {
|
||||
fs.rmdirSync(dir);
|
||||
} catch {
|
||||
break;
|
||||
}
|
||||
dir = path.dirname(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
describe("no-restricted-imports rules", () => {
|
||||
it("blocks @opentelemetry/sdk-metrics outside otel.ts", () => {
|
||||
const id = uid();
|
||||
const result = lintString(
|
||||
`src/features/online-board/__ri_probe_${id}__.ts`,
|
||||
'import { MeterProvider } from "@opentelemetry/sdk-metrics";\nexport const x = MeterProvider;\n',
|
||||
);
|
||||
expect(result).toContain("no-restricted-imports");
|
||||
});
|
||||
|
||||
it("blocks react-i18next outside provider.tsx", () => {
|
||||
const id = uid();
|
||||
const result = lintString(
|
||||
`src/features/online-board/__ri_probe_${id}__.ts`,
|
||||
'import { useTranslation } from "react-i18next";\nexport const x = useTranslation;\n',
|
||||
);
|
||||
expect(result).toContain("no-restricted-imports");
|
||||
});
|
||||
|
||||
it("blocks @microsoft/signalr in routes/ (SSR bundle)", () => {
|
||||
const id = uid();
|
||||
const result = lintString(
|
||||
`src/routes/__probe_${id}__/__ri_probe__.ts`,
|
||||
'import { HubConnectionBuilder } from "@microsoft/signalr";\nexport const x = HubConnectionBuilder;\n',
|
||||
);
|
||||
expect(result).toContain("no-restricted-imports");
|
||||
});
|
||||
|
||||
it("blocks localStorage outside storage.ts", () => {
|
||||
const id = uid();
|
||||
const result = lintString(
|
||||
`src/features/online-board/__ri_probe_${id}__.ts`,
|
||||
'const x = localStorage.getItem("key");\nexport default x;\n',
|
||||
);
|
||||
expect(result).toContain("no-restricted-globals");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user