13 lines
3.0 KiB
JavaScript
13 lines
3.0 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import crypto from "node:crypto";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { execFileSync } from "node:child_process";
|
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); const planPath = path.join(root, "tests/golden/M15-03A/next-task-plan.json"); const reportPath = path.join(root, "tests/golden/M15-03C/task-graph-check-report.json"); const manifestPath = path.join(root, "tests/golden/M15-03C/manifest.json"); const sha256 = (b) => crypto.createHash("sha256").update(b).digest("hex"); const fileSha256 = (f) => sha256(fs.readFileSync(f)); const relative = (f) => path.relative(root, f).replaceAll(path.sep, "/");
|
|
const plan = JSON.parse(fs.readFileSync(planPath, "utf8")); const ids = new Set(plan.tasks.map((task) => task.id)); const active = plan.tasks.filter((task) => task.state === "active"); const missingDeps = []; const cycles = []; for (const task of plan.tasks) { for (const dep of task.dependencies) { if (!ids.has(dep)) missingDeps.push(`${task.id}->${dep}`); let cursor = dep; const visited = new Set([task.id]); while (cursor) { if (visited.has(cursor)) { cycles.push(task.id); break; } visited.add(cursor); cursor = plan.tasks.find((candidate) => candidate.id === cursor)?.dependencies[0] ?? null; } } }
|
|
assert.equal(active.length, 1); assert.equal(missingDeps.length, 0); assert.equal(cycles.length, 0); assert.equal(plan.tasks.length, 6900);
|
|
const report = { schemaVersion: 1, task: "M15-03C", operation: "BLENDER_TASK_GRAPH_CHECK", source: { path: "tests/golden/M15-03A/next-task-plan.json", sha256: fileSha256(planPath) }, summary: { nodes: plan.tasks.length, active: active.length, missingDependencies: missingDeps.length, cycles: cycles.length }, activeTask: active[0].id, nextTask: "M15-03D" };
|
|
if (process.env.UPDATE_M15_03C_MANIFEST === "1") { fs.mkdirSync(path.dirname(reportPath), { recursive: true }); fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`); const paths = { parentManifest: path.join(root, "tests/golden/M15-03B/manifest.json"), checker: path.join(root, "tools/web/check-blender-task-graph.mjs"), plan: planPath, report: reportPath, package: path.join(root, "web/package.json") }; const artifacts = Object.fromEntries(Object.entries(paths).map(([name, file]) => [name, { path: relative(file), sha256: fileSha256(file) }])); fs.writeFileSync(manifestPath, `${JSON.stringify({ schemaVersion: 1, task: "M15-03C", parentTask: "M15-03B", enablingTask: false, parityStateChange: false, operation: "BLENDER_TASK_GRAPH_CHECK", artifacts, nextTask: "M15-03D" }, null, 2)}\n`); }
|
|
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8")); for (const artifact of Object.values(manifest.artifacts)) assert.equal(fileSha256(path.join(root, artifact.path)), artifact.sha256, artifact.path); process.stdout.write(`blender-task-graph-ok nodes=${report.summary.nodes} active=${report.summary.active} missing=${report.summary.missingDependencies} cycles=${report.summary.cycles} next=${manifest.nextTask}\n`);
|