repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
.pi/skills/modernize/scripts/audit.test.mjs
Rawimport assert from "node:assert/strict";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import test from "node:test";
import { checkedSpawn } from "./audit.bench.mjs";
import {
assertLatest,
collectPackageVersions,
compareVersions,
createReport,
extractCandidates,
parseChangelog,
resolvePiInstallation,
} from "./audit.mjs";
const changelog = `# Changelog
## [2.0.0] - 2026-07-13
### Added
- Added harmless sparkle output.
### Changed
- Renamed \`oldCall()\` to \`newCall()\`.
### Fixed
- Removed the obsolete \`legacyOption\` request field.
- Fixed ordinary rendering noise.
## [1.5.0] - 2026-07-01
### Breaking Changes
- Replace \`alpha()\` with \`beta()\`.
## [1.0.0] - 2026-06-01
### Added
- Initial release.
`;
test("parses release sections newest first", () => {
assert.deepEqual(
parseChangelog(changelog).map(({ version }) => version),
["2.0.0", "1.5.0", "1.0.0"],
);
});
test("extracts migration sections and keyword bullets in the version interval", () => {
assert.deepEqual(
extractCandidates(changelog, {
afterVersion: "1.5.0",
throughVersion: "2.0.0",
}).map(({ section, text }) => [section, text]),
[
["Changed", "Renamed `oldCall()` to `newCall()`."],
["Fixed", "Removed the obsolete `legacyOption` request field."],
],
);
});
test("rejects changelogs without release sections", () => {
assert.throws(() => parseChangelog("# Changelog\n\nNothing yet."), /release/);
});
test("compares semantic versions numerically", () => {
assert.equal(compareVersions("0.80.10", "0.80.6"), 1);
assert.equal(compareVersions("0.80.6", "0.80.6"), 0);
assert.equal(compareVersions("0.79.9", "0.80.1"), -1);
});
test("fails when installed Pi is not latest", () => {
assert.doesNotThrow(() => assertLatest("0.80.6", "0.80.6"));
assert.throws(() => assertLatest("0.80.5", "0.80.6"), /not latest/);
});
test("resolves the installed Pi package from launcher and CLI paths", (context) => {
const directory = mkdtempSync(path.join(tmpdir(), "pi-modernize-"));
context.after(() => rmSync(directory, { recursive: true, force: true }));
const packageRoot = path.join(
directory,
"node_modules",
"@earendil-works",
"pi-coding-agent",
);
const cli = path.join(packageRoot, "dist", "cli.js");
const changelog = path.join(packageRoot, "CHANGELOG.md");
const launcher = path.join(directory, "pi.CMD");
mkdirSync(path.dirname(cli), { recursive: true });
writeFileSync(
path.join(packageRoot, "package.json"),
JSON.stringify({
name: "@earendil-works/pi-coding-agent",
version: "0.85.0",
bin: { pi: "dist/cli.js" },
}),
);
writeFileSync(cli, "");
writeFileSync(changelog, "");
writeFileSync(launcher, "");
const expected = { cli, changelog, version: "0.85.0" };
assert.deepEqual(resolvePiInstallation(launcher), expected);
assert.deepEqual(resolvePiInstallation(cli), expected);
});
test("fails when no installed Pi package is near the launcher", (context) => {
const directory = mkdtempSync(path.join(tmpdir(), "pi-modernize-"));
context.after(() => rmSync(directory, { recursive: true, force: true }));
const launcher = path.join(directory, "pi");
writeFileSync(launcher, "");
assert.throws(
() => resolvePiInstallation(launcher),
/installed @earendil-works\/pi-coding-agent package not found/,
);
});
test("reports inherited-stdio child failures by exit code", () => {
assert.throws(
() =>
checkedSpawn(process.execPath, ["-e", "process.exit(7)"], {
stdio: "inherit",
}),
/exited with code 7/,
);
});
test("collects resolved earendil Pi package versions", () => {
assert.deepEqual(
collectPackageVersions({
packages: {
"node_modules/@earendil-works/pi-ai": { version: "0.80.4" },
"extensions/x/node_modules/@earendil-works/pi-ai": {
version: "0.80.4",
},
"node_modules/@earendil-works/pi-coding-agent": {
version: "0.80.6",
},
"node_modules/@earendil-works/pi-coding-agent/node_modules/partial-json":
{
version: "0.1.7",
},
"node_modules/vitest": { version: "4.1.9" },
},
}),
[
{ name: "@earendil-works/pi-ai", version: "0.80.4" },
{ name: "@earendil-works/pi-coding-agent", version: "0.80.6" },
],
);
});
test("reports only evidence needed before tool-driven inspection", () => {
assert.deepEqual(
createReport({
piVersion: "2.0.0",
candidatesAfterVersion: "1.5.0",
localChangelogPath: "/pi/CHANGELOG.md",
remoteChangelogUrl: "https://example.test/CHANGELOG.md",
candidates: [{ version: "2.0.0", text: "Replace alpha." }],
}),
{
schemaVersion: 2,
status: "ok",
piVersion: "2.0.0",
candidatesAfterVersion: "1.5.0",
changelogs: {
installed: "/pi/CHANGELOG.md",
remote: "https://example.test/CHANGELOG.md",
},
candidates: [{ version: "2.0.0", text: "Replace alpha." }],
},
);
});