Files
fusion/scripts/__tests__/release-version-anchor.test.mjs
gsxdsm 330e4970f0 refactor(release): move the version-anchor package.json rewrite into the shared lib
Makes the re-anchor file mutation unit-testable alongside the anchor decision.
2026-07-24 23:01:11 -07:00

107 lines
4.3 KiB
JavaScript

/*
FNXC:UpdateChannels 2026-07-24-09:40:
Guards the release version-anchor contract:
- after a stable ships, the next beta is based on THAT stable version;
- no release (either channel) may number at or below the newest published stable.
Regression context: v0.73.0 was cut on `release` while `main` stayed in the
0.72.0-anchored pre-mode cycle, so the next beta would have been v0.73.0-beta.7
(below the shipped v0.73.0) and `pnpm dev` on main still reported the beta.
*/
import test from "node:test";
import assert from "node:assert/strict";
import { mkdtempSync, readFileSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import {
compareReleaseVersions,
evaluateBetaCycleAnchor,
isVersionAheadOfStable,
latestStableVersionFromTags,
setPackageJsonVersions,
} from "../lib/release-version-anchor.mjs";
test("compareReleaseVersions ranks a prerelease below its stable", () => {
assert.ok(compareReleaseVersions("0.73.0-beta.6", "0.73.0") < 0);
assert.ok(compareReleaseVersions("0.73.0", "0.73.0-beta.6") > 0);
assert.equal(compareReleaseVersions("0.73.0", "0.73.0"), 0);
});
test("compareReleaseVersions compares numeric identifiers numerically", () => {
assert.ok(compareReleaseVersions("0.73.0-beta.9", "0.73.0-beta.10") < 0);
assert.ok(compareReleaseVersions("0.9.0", "0.73.0") < 0);
assert.ok(compareReleaseVersions("0.73.1", "0.73.0") > 0);
});
test("latestStableVersionFromTags ignores prerelease tags", () => {
const tags = [
"v0.72.0",
"v0.73.0",
"v0.73.0-beta.0",
"v0.73.0-beta.6",
"v0.74.0-beta.0",
"not-a-tag",
];
assert.equal(latestStableVersionFromTags(tags), "0.73.0");
assert.equal(latestStableVersionFromTags(tags.join("\n")), "0.73.0");
assert.equal(latestStableVersionFromTags(["v0.73.0-beta.1"]), null);
assert.equal(latestStableVersionFromTags([]), null);
});
test("a beta cycle anchored below a shipped stable is re-anchored on that stable", () => {
// The exact v0.73.0 shape: pre.json still snapshots the 0.72.0 cycle base.
assert.deepEqual(
evaluateBetaCycleAnchor({ cycleBase: "0.72.0", latestStable: "0.73.0" }),
{ stale: true, anchor: "0.73.0" },
);
});
test("a beta cycle already at or above the shipped stable is left alone", () => {
assert.deepEqual(
evaluateBetaCycleAnchor({ cycleBase: "0.73.0", latestStable: "0.73.0" }),
{ stale: false, anchor: "0.73.0" },
);
assert.deepEqual(
evaluateBetaCycleAnchor({ cycleBase: "0.74.0", latestStable: "0.73.0" }),
{ stale: false, anchor: "0.74.0" },
);
});
test("with no stable tag yet, no cycle is considered stale", () => {
assert.deepEqual(
evaluateBetaCycleAnchor({ cycleBase: "0.1.0", latestStable: null }),
{ stale: false, anchor: "0.1.0" },
);
});
test("isVersionAheadOfStable rejects releases at or below the newest stable", () => {
// The bug: the next beta of a stale cycle numbers beneath the shipped stable.
assert.equal(isVersionAheadOfStable("0.73.0-beta.7", "0.73.0"), false);
assert.equal(isVersionAheadOfStable("0.73.0", "0.73.0"), false);
assert.equal(isVersionAheadOfStable("0.72.9", "0.73.0"), false);
// Both channels' healthy shapes stay allowed.
assert.equal(isVersionAheadOfStable("0.73.1-beta.0", "0.73.0"), true);
assert.equal(isVersionAheadOfStable("0.74.0-beta.0", "0.73.0"), true);
assert.equal(isVersionAheadOfStable("0.74.0", "0.73.0"), true);
assert.equal(isVersionAheadOfStable("0.1.0", null), true);
});
test("setPackageJsonVersions re-anchors only the files that need it", () => {
const dir = mkdtempSync(join(tmpdir(), "fusion-anchor-test-"));
const root = join(dir, "package.json");
const cli = join(dir, "cli.package.json");
const missing = join(dir, "nope.package.json");
writeFileSync(root, JSON.stringify({ name: "root", version: "0.73.0-beta.6" }, null, 2) + "\n");
writeFileSync(cli, JSON.stringify({ name: "cli", version: "0.73.0" }, null, 2) + "\n");
const rewritten = setPackageJsonVersions([root, cli, missing], "0.73.0");
// Already-anchored and absent files are left alone; the stale one is rewritten.
assert.deepEqual(rewritten, [root]);
assert.equal(JSON.parse(readFileSync(root, "utf8")).version, "0.73.0");
assert.equal(JSON.parse(readFileSync(cli, "utf8")).version, "0.73.0");
// Unrelated fields survive the rewrite.
assert.equal(JSON.parse(readFileSync(root, "utf8")).name, "root");
});