import * as fs from "node:fs"; import * as os from "node:os"; import * as path from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import { cleanupAnalysisArtifacts, getAnalysisArtifactPaths } from "./analysisArtifacts"; const tempDirs: string[] = []; async function makeDataDir() { const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "analysis-artifacts-")); tempDirs.push(dir); return dir; } afterEach(async () => { await Promise.all(tempDirs.splice(0).map((dir) => fs.promises.rm(dir, { recursive: true, force: true }))); }); describe("cleanupAnalysisArtifacts", () => { it("deletes the plugin directory and all legacy files for only the requested result", async () => { const dataDir = await makeDataDir(); const analysisDir = path.join(dataDir, "tasks", "7", "analysis"); await fs.promises.mkdir(path.join(analysisDir, "57"), { recursive: true }); await fs.promises.mkdir(path.join(analysisDir, "58"), { recursive: true }); const files = [ "heatmap_57.bin", "deviation_57.bin", "assembly_vertex_57_car-body.bin", "assembly_vertex_57_bogie.bin", "heatmap_58.bin", "assembly_vertex_570_other.bin", ]; await Promise.all(files.map((name) => fs.promises.writeFile(path.join(analysisDir, name), name))); await cleanupAnalysisArtifacts(7, 57, dataDir); await expect(fs.promises.stat(path.join(analysisDir, "57"))).rejects.toMatchObject({ code: "ENOENT" }); for (const name of files.slice(0, 4)) { await expect(fs.promises.stat(path.join(analysisDir, name))).rejects.toMatchObject({ code: "ENOENT" }); } await expect(fs.promises.stat(path.join(analysisDir, "58"))).resolves.toBeDefined(); await expect(fs.promises.stat(path.join(analysisDir, "heatmap_58.bin"))).resolves.toBeDefined(); await expect(fs.promises.stat(path.join(analysisDir, "assembly_vertex_570_other.bin"))).resolves.toBeDefined(); }); it("rejects invalid IDs before constructing a filesystem target", () => { expect(() => getAnalysisArtifactPaths(7, Number.NaN, "/data")).toThrow("resultId"); expect(() => getAnalysisArtifactPaths(7, -1, "/data")).toThrow("resultId"); expect(() => getAnalysisArtifactPaths(1.5, 2, "/data")).toThrow("taskId"); }); it("is idempotent when artifacts are already absent", async () => { const dataDir = await makeDataDir(); await expect(cleanupAnalysisArtifacts(7, 57, dataDir)).resolves.toBeUndefined(); await expect(cleanupAnalysisArtifacts(7, 57, dataDir)).resolves.toBeUndefined(); }); });