Files
agentic-dev/scripts/work/decompose.test.mjs
Danijel Martinek 8b114351a8 chore(tooling): port upstream infra/tooling audit fixes
Reconciles the upstream audit-fix PR's infra changes onto the Veect
control-plane fork (kept-file portions only; deleted demo features
skipped):

- resolve the root playwright config in pnpm test:visual (S8)
- prune dead VERCEL_ENV from turbo.json globalEnv (S9)
- drop the duplicate chromium install in the storybook CI job (S10)
- wire scripts/**/*.test.mjs under a dedicated vitest runner
  (vitest.scripts.config.mjs + pnpm test:scripts + CI validate step);
  convert node:test imports to vitest keeping node:assert; fix the
  work-tree fixtures to mirror the docs/work/epics/ layout
- ignore *.tsbuildinfo repo-wide and untrack the committed build state
- align every @trpc/* range on ^11.18.0 so the workspace resolves to a
  single version (peer-warning-free install)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
2026-07-12 23:40:07 +02:00

165 lines
4.6 KiB
JavaScript

// Runs under vitest (pnpm test:scripts picks up scripts/**/*.test.mjs);
// node:assert keeps the original assertion style.
import { test, describe } from "vitest";
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
import os from "node:os";
import { validatePrdForDecompose, runCli } from "./decompose.mjs";
function writePrd(dir, id, status) {
const file = path.join(dir, `${id}.prd.md`);
fs.writeFileSync(
file,
`---
id: ${id}
title: Test PRD
type: prd
status: ${status}
author: tester
created: 2026-05-13
---
body content
`,
);
return file;
}
function setupRepo() {
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "decompose-"));
fs.mkdirSync(path.join(tmp, "prds"), { recursive: true });
return tmp;
}
describe("validatePrdForDecompose", () => {
test("accepts an approved PRD", () => {
const tmp = setupRepo();
try {
const file = writePrd(path.join(tmp, "prds"), "test-1", "approved");
const result = validatePrdForDecompose(file);
assert.equal(result.frontmatter.status, "approved");
assert.ok(result.text.includes("body content"));
} finally {
fs.rmSync(tmp, { recursive: true, force: true });
}
});
test("rejects draft (must go through human review)", () => {
const tmp = setupRepo();
try {
const file = writePrd(path.join(tmp, "prds"), "test-2", "draft");
assert.throws(
() => validatePrdForDecompose(file),
/status is "draft".*Flip status to "approved"/,
);
} finally {
fs.rmSync(tmp, { recursive: true, force: true });
}
});
test("rejects in-review", () => {
const tmp = setupRepo();
try {
const file = writePrd(path.join(tmp, "prds"), "test-3", "in-review");
assert.throws(
() => validatePrdForDecompose(file),
/status is "in-review"/,
);
} finally {
fs.rmSync(tmp, { recursive: true, force: true });
}
});
test("rejects shipped (epic already exists)", () => {
const tmp = setupRepo();
try {
const file = writePrd(path.join(tmp, "prds"), "test-4", "shipped");
assert.throws(() => validatePrdForDecompose(file), /status is "shipped"/);
} finally {
fs.rmSync(tmp, { recursive: true, force: true });
}
});
test("rejects unknown status", () => {
const tmp = setupRepo();
try {
const file = writePrd(path.join(tmp, "prds"), "test-5", "cancelled");
assert.throws(
() => validatePrdForDecompose(file),
/Unexpected PRD status "cancelled"/,
);
} finally {
fs.rmSync(tmp, { recursive: true, force: true });
}
});
test("rejects missing file", () => {
assert.throws(
() => validatePrdForDecompose("/nonexistent/path.prd.md"),
/PRD file not found/,
);
});
});
describe("runCli (print mode)", () => {
test("returns 1 + writes error when PRD id not found", async () => {
const tmp = setupRepo();
const errors = [];
const origError = console.error;
console.error = (m) => errors.push(m);
try {
const code = await runCli(["nonexistent-id"], {
repoRoot: tmp,
workRoot: tmp,
});
assert.equal(code, 1);
assert.ok(errors.some((e) => /not found under docs\/work\/prds/.test(e)));
} finally {
console.error = origError;
fs.rmSync(tmp, { recursive: true, force: true });
}
});
test("returns 1 + writes error when PRD is draft", async () => {
const tmp = setupRepo();
const errors = [];
const origError = console.error;
console.error = (m) => errors.push(m);
try {
writePrd(path.join(tmp, "prds"), "draft-prd", "draft");
const code = await runCli(["draft-prd"], {
repoRoot: tmp,
workRoot: tmp,
});
assert.equal(code, 1);
assert.ok(errors.some((e) => /Cannot decompose/.test(e)));
} finally {
console.error = origError;
fs.rmSync(tmp, { recursive: true, force: true });
}
});
test("prints plan when PRD is approved + returns 0", async () => {
const tmp = setupRepo();
const logs = [];
const origLog = console.log;
console.log = (m) => logs.push(m);
try {
writePrd(path.join(tmp, "prds"), "approved-prd", "approved");
const code = await runCli(["approved-prd"], {
repoRoot: tmp,
workRoot: tmp,
});
assert.equal(code, 0);
const all = logs.join("\n");
assert.match(all, /Decompose plan/);
assert.match(all, /approved-prd/);
assert.match(all, /eligible/);
} finally {
console.log = origLog;
fs.rmSync(tmp, { recursive: true, force: true });
}
});
});