Files
fusion/scripts/__tests__/extract-version-notes.test.mjs
gsxdsm 7911fdb9b1 fix(release): preserve distilled changelog summaries across releases
syncRootChangelog rewrote every prior release from raw package notes, so only
the latest distilled Highlights view survived. Re-emit already-distilled bodies
on sync, keep the archive pointer outside version sections, and restore wiped
summaries from release history.
2026-07-21 20:29:46 -07:00

142 lines
4.2 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import { extractVersionNotes, replaceVersionSection } from "../lib/extract-version-notes.mjs";
const changelog = `# Fusion changelog
## 1.2.0
### @runfusion/fusion
#### Patch Changes
- Added release integration.
## 1.1.0
### @runfusion/fusion
#### Patch Changes
- Fixed parser bug.
## 1.0.0
### @runfusion/fusion
#### Patch Changes
- Initial release.
`;
test("extracts correct section for known version", () => {
const notes = extractVersionNotes(changelog, "1.1.0");
assert.match(notes, /Fixed parser bug\./);
assert.doesNotMatch(notes, /Added release integration\./);
});
test("returns full multiline body including sub-headings", () => {
const notes = extractVersionNotes(changelog, "1.2.0");
assert.match(notes, /^### @runfusion\/fusion/m);
assert.match(notes, /^#### Patch Changes/m);
assert.match(notes, /- Added release integration\./);
});
test("returns fallback when version not found", () => {
const notes = extractVersionNotes(changelog, "9.9.9");
assert.equal(notes, "Release v9.9.9");
});
test("returns fallback when changelog content is empty", () => {
const notes = extractVersionNotes("", "1.2.0");
assert.equal(notes, "Release v1.2.0");
});
test("handles version as last section with no trailing heading", () => {
const notes = extractVersionNotes(changelog, "1.0.0");
assert.match(notes, /Initial release\./);
});
test("handles single-version changelog", () => {
const single = `# Changelog\n\n## 2.0.0\n\n### pkg\n\n#### Patch Changes\n\n- Solo entry.\n`;
const notes = extractVersionNotes(single, "2.0.0");
assert.match(notes, /Solo entry\./);
});
test("does not bleed into adjacent version sections", () => {
const notes = extractVersionNotes(changelog, "1.1.0");
assert.doesNotMatch(notes, /Initial release\./);
assert.doesNotMatch(notes, /Added release integration\./);
});
// --- replaceVersionSection ---
test("replaces version section with distilled notes", () => {
const result = replaceVersionSection(changelog, "1.2.0", "### New\n\n- Distilled entry.");
assert.match(result, /### New/);
assert.match(result, /Distilled entry\./);
// Other versions preserved.
assert.match(result, /Fixed parser bug\./);
assert.match(result, /Initial release\./);
// Old content removed.
assert.doesNotMatch(result, /Added release integration\./);
});
test("returns original content when version not found", () => {
const result = replaceVersionSection(changelog, "9.9.9", "### New\n\n- Entry.");
assert.equal(result, changelog);
});
test("preserves version heading", () => {
const result = replaceVersionSection(changelog, "1.1.0", "### Fixed\n\n- New fix.");
assert.match(result, /## 1\.1\.0/);
assert.match(result, /## 1\.2\.0/);
assert.match(result, /## 1\.0\.0/);
});
test("replaces last version section correctly", () => {
const result = replaceVersionSection(changelog, "1.0.0", "### Fixed\n\n- Replaced.");
assert.match(result, /Replaced\./);
// Versions above 1.0.0 are preserved.
assert.match(result, /## 1\.1\.0/);
});
test("handles null content gracefully", () => {
const result = replaceVersionSection(null, "1.0.0", "Body.");
assert.equal(result, null);
});
const withArchivePointer = `# Fusion changelog
## 1.0.0
### Highlights
- One thing
> Older releases (before 0.60.0) are archived in [\`CHANGELOG-archive.md\`](./CHANGELOG-archive.md).
`;
test("extractVersionNotes excludes trailing archive pointer from last section", () => {
const notes = extractVersionNotes(withArchivePointer, "1.0.0");
assert.match(notes, /### Highlights/);
assert.match(notes, /One thing/);
assert.doesNotMatch(notes, /Older releases/);
assert.doesNotMatch(notes, /CHANGELOG-archive/);
});
test("replaceVersionSection preserves trailing archive pointer after last version", () => {
const result = replaceVersionSection(
withArchivePointer,
"1.0.0",
"### New\n\n- Distilled only.",
);
assert.match(result, /### New/);
assert.match(result, /Distilled only\./);
assert.doesNotMatch(result, /One thing/);
assert.match(
result,
/Older releases \(before 0\.60\.0\) are archived in \[`CHANGELOG-archive\.md`\]\(\.\/CHANGELOG-archive\.md\)\./,
);
});