Add tests for update-ghes-versions.ts

This commit is contained in:
Michael B. Gale
2026-05-19 14:03:20 +01:00
parent 15f19e1870
commit f9feddd874
+204
View File
@@ -0,0 +1,204 @@
#!/usr/bin/env npx tsx
/*
* Tests for the update-ghes-versions.ts script
*/
import * as assert from "node:assert/strict";
import { describe, it } from "node:test";
import {
addWeeks,
determineSupportedRange,
type EnterpriseReleases,
parseEnterpriseVersion,
printEnterpriseVersion,
} from "./update-ghes-versions";
describe("parseEnterpriseVersion", async () => {
await it("parses a two-component version string", () => {
const ver = parseEnterpriseVersion("3.10");
assert.notEqual(ver, null);
assert.equal(ver!.major, 3);
assert.equal(ver!.minor, 10);
assert.equal(ver!.patch, 0);
});
await it("parses a three-component version string", () => {
const ver = parseEnterpriseVersion("3.10.2");
assert.notEqual(ver, null);
assert.equal(ver!.major, 3);
assert.equal(ver!.minor, 10);
assert.equal(ver!.patch, 2);
});
await it("returns null for invalid input", () => {
assert.equal(parseEnterpriseVersion("not-a-version"), null);
});
});
describe("printEnterpriseVersion", async () => {
await it("prints only major.minor when patch is 0", () => {
const ver = parseEnterpriseVersion("3.10")!;
assert.equal(printEnterpriseVersion(ver), "3.10");
});
await it("includes patch when non-zero", () => {
const ver = parseEnterpriseVersion("3.10.2")!;
assert.equal(printEnterpriseVersion(ver), "3.10.2");
});
});
describe("addWeeks", async () => {
await it("adds weeks to a date", () => {
const date = new Date("2025-01-01T00:00:00Z");
const result = addWeeks(date, 2);
assert.equal(result.toISOString(), "2025-01-15T00:00:00.000Z");
});
await it("does not mutate the original date", () => {
const date = new Date("2025-01-01T00:00:00Z");
addWeeks(date, 2);
assert.equal(date.toISOString(), "2025-01-01T00:00:00.000Z");
});
});
/**
* Helper to build a release entry with a feature freeze and end-of-life date.
* Dates are ISO date strings (e.g. "2025-06-01").
*/
function release(featureFreeze: string, end: string) {
return { feature_freeze: featureFreeze, end };
}
describe("determineSupportedRange", async () => {
// A fixed "today" for deterministic tests.
const today = new Date("2025-06-15");
const farPastEnd = "2020-01-01";
const farFutureEnd = "2099-12-31";
const farPastFreeze = "2020-01-01";
const farFutureFreeze = "2099-12-31";
await it("returns the only supported release as both min and max", () => {
const releases: EnterpriseReleases = {
"3.10": release(farPastFreeze, farFutureEnd),
};
const result = determineSupportedRange(
today,
{ minimumVersion: "3.10", maximumVersion: "3.10" },
releases,
);
assert.equal(result.minimumVersion, "3.10");
assert.equal(result.maximumVersion, "3.10");
});
await it("determines the range from multiple supported releases", () => {
const releases: EnterpriseReleases = {
"3.10": release(farPastFreeze, farFutureEnd),
"3.11": release(farPastFreeze, farFutureEnd),
"3.12": release(farPastFreeze, farFutureEnd),
};
const result = determineSupportedRange(
today,
{ minimumVersion: "3.10", maximumVersion: "3.12" },
releases,
);
assert.equal(result.minimumVersion, "3.10");
assert.equal(result.maximumVersion, "3.12");
});
await it("drops an end-of-life release from the minimum", () => {
const releases: EnterpriseReleases = {
// 3.10 has been end of life for a long time.
"3.10": release(farPastFreeze, farPastEnd),
"3.11": release(farPastFreeze, farFutureEnd),
"3.12": release(farPastFreeze, farFutureEnd),
};
const result = determineSupportedRange(
today,
{ minimumVersion: "3.10", maximumVersion: "3.12" },
releases,
);
assert.equal(result.minimumVersion, "3.11");
assert.equal(result.maximumVersion, "3.12");
});
await it("bumps the maximum when a newer release's feature freeze has passed", () => {
const releases: EnterpriseReleases = {
"3.10": release(farPastFreeze, farFutureEnd),
"3.11": release(farPastFreeze, farFutureEnd),
// 3.12 has a feature freeze far in the past, so it should be picked up.
"3.12": release(farPastFreeze, farFutureEnd),
};
const result = determineSupportedRange(
today,
// The stored maximum is 3.11, but 3.12 should be picked up.
{ minimumVersion: "3.10", maximumVersion: "3.11" },
releases,
);
assert.equal(result.minimumVersion, "3.10");
assert.equal(result.maximumVersion, "3.12");
});
await it("does not bump the maximum when feature freeze is far in the future", () => {
const releases: EnterpriseReleases = {
"3.10": release(farPastFreeze, farFutureEnd),
"3.11": release(farPastFreeze, farFutureEnd),
// 3.12 has a feature freeze far in the future, so it should NOT be picked up.
"3.12": release(farFutureFreeze, farFutureEnd),
};
const result = determineSupportedRange(
today,
{ minimumVersion: "3.10", maximumVersion: "3.11" },
releases,
);
assert.equal(result.minimumVersion, "3.10");
assert.equal(result.maximumVersion, "3.11");
});
await it("ignores releases older than the first supported release (2.22)", () => {
const releases: EnterpriseReleases = {
"2.21": release(farPastFreeze, farFutureEnd),
"3.10": release(farPastFreeze, farFutureEnd),
"3.11": release(farPastFreeze, farFutureEnd),
};
const result = determineSupportedRange(
today,
{ minimumVersion: "3.10", maximumVersion: "3.11" },
releases,
);
// 2.21 is older than 2.22, so it should be ignored — 3.10 remains the minimum.
assert.equal(result.minimumVersion, "3.10");
assert.equal(result.maximumVersion, "3.11");
});
await it("throws when no supported releases remain", () => {
const releases: EnterpriseReleases = {
// All releases are end of life.
"3.10": release(farPastFreeze, farPastEnd),
"3.11": release(farPastFreeze, farPastEnd),
};
assert.throws(
() =>
determineSupportedRange(
today,
{ minimumVersion: "3.10", maximumVersion: "3.11" },
releases,
),
/Could not determine oldest supported release/,
);
});
await it("throws when maximumVersion is not a valid version", () => {
assert.throws(
() =>
determineSupportedRange(
today,
{ minimumVersion: "3.10", maximumVersion: "invalid" },
{},
),
/is not a valid semantic version/,
);
});
});