import { describe, expect, it } from "vite-plus/test";
import { normalizeDesktopUpdateReleaseNotes } from "./releaseNotes.ts";
describe("normalizeDesktopUpdateReleaseNotes", () => {
it("shows the newest changes and counts all real changes", () => {
const result = normalizeDesktopUpdateReleaseNotes(
[
"- feat: first change",
"- fix: second change",
"- fix: third change",
"- fix: fourth change",
"- fix: fifth change",
"- fix: sixth change",
"- fix: seventh change",
"- fix: eighth change",
"- fix(web): keep long task drawers usable on small screens by @human in #8313",
"- fix(opencode): handle child approvals, stops, and model catalogs by @human in #8480",
"## New Contributors",
"- @human made their first contribution in #8435",
"**Full Changelog**: https://github.com/pingdotgg/t3code/compare/old...new",
].join("\n"),
"0.0.36-nightly.20260828.1213",
);
expect(result).toEqual({
releaseNotes: [
{
version: "0.0.36-nightly.20260828.1213",
items: [
"fix(opencode): handle child approvals, stops, and model catalogs by @human in #8480",
"fix(web): keep long task drawers usable on small screens by @human in #8313",
"fix: eighth change",
"fix: seventh change",
"fix: sixth change",
"fix: fifth change",
"fix: fourth change",
"fix: third change",
],
totalItems: 10,
},
],
omittedReleaseCount: 0,
});
});
it("excludes a GitHub HTML contributor section", () => {
const result = normalizeDesktopUpdateReleaseNotes(
"
What's Changed
" +
"New Contributors
- @human made their first contribution
" +
"Full Changelog
",
"1.2.3",
);
expect(result).toEqual({
releaseNotes: [{ version: "1.2.3", items: ["Newer fix", "Older fix"], totalItems: 2 }],
omittedReleaseCount: 0,
});
});
it("does not count Markdown or HTML section headings as changes", () => {
const changes = Array.from({ length: 8 }, (_, index) => `Change ${index + 1}`);
const result = normalizeDesktopUpdateReleaseNotes(
[
{ version: "1.2.4", note: ["### Features", ...changes].join("\n- ") },
{
version: "1.2.3",
note: `Fixes
${changes.map((change) => `- ${change}
`).join("")}
`,
},
],
"1.2.4",
);
expect(result.releaseNotes).toEqual([
{ version: "1.2.4", items: changes.toReversed(), totalItems: 8 },
{ version: "1.2.3", items: changes.toReversed(), totalItems: 8 },
]);
});
it("keeps per-version order and drops empty groups", () => {
const result = normalizeDesktopUpdateReleaseNotes(
[
{ version: "1.2.3", note: "- Newer release" },
{ version: "1.2.2", note: "Full changelog: https://example.com/compare/x...y" },
{ version: "1.2.1", note: "- Older release" },
],
"1.2.3",
);
expect(result).toEqual({
releaseNotes: [
{ version: "1.2.3", items: ["Newer release"], totalItems: 1 },
{ version: "1.2.1", items: ["Older release"], totalItems: 1 },
],
omittedReleaseCount: 0,
});
});
it("counts valid groups before applying the six-release limit", () => {
const releaseNotes = [
{ version: "1.3.9", note: "- Change 9" },
{ version: "1.3.8", note: "Full changelog: https://example.com/compare/x...y" },
{ version: "1.3.7", note: "- Change 7" },
{ version: "1.3.6", note: "- Change 6" },
{ version: "1.3.5", note: "- Change 5" },
{ version: "1.3.4", note: "- Change 4" },
{ version: "1.3.3", note: "- Change 3" },
{ version: "1.3.2", note: "- Change 2" },
];
const result = normalizeDesktopUpdateReleaseNotes(releaseNotes, "1.3.9");
expect(result.releaseNotes.map(({ version }) => version)).toEqual([
"1.3.9",
"1.3.7",
"1.3.6",
"1.3.5",
"1.3.4",
"1.3.3",
]);
expect(result.omittedReleaseCount).toBe(1);
});
it("decodes valid HTML entities", () => {
const result = normalizeDesktopUpdateReleaseNotes("- Fix & polish 😀", "1.0.0");
expect(result).toEqual({
releaseNotes: [{ version: "1.0.0", items: ["Fix & polish 😀"], totalItems: 1 }],
omittedReleaseCount: 0,
});
});
it("ignores malformed and empty entries instead of throwing", () => {
const result = normalizeDesktopUpdateReleaseNotes(
[
{ version: "1.2.3", note: "- Valid change" },
{ version: "1.2.2", note: "" },
{ version: 42, note: "- Bad version type" },
{ version: "1.2.1", note: { html: "object note
" } },
"not an object",
null,
],
"1.2.3",
);
expect(result).toEqual({
releaseNotes: [{ version: "1.2.3", items: ["Valid change"], totalItems: 1 }],
omittedReleaseCount: 0,
});
});
it("returns an empty result for an invalid payload", () => {
expect(normalizeDesktopUpdateReleaseNotes({ note: "- Invalid" }, "1.0.0")).toEqual({
releaseNotes: [],
omittedReleaseCount: 0,
});
});
it("does not throw on out-of-range numeric entities and keeps the literal", () => {
const result = normalizeDesktopUpdateReleaseNotes("- Broken entity ", "1.0.0");
expect(result).toEqual({
releaseNotes: [{ version: "1.0.0", items: ["Broken entity "], totalItems: 1 }],
omittedReleaseCount: 0,
});
});
});