























@@ -47,4 +47,103 @@ describe("replaceManagedMarkdownBlock", () => {
4747}),
4848).toBe("alpha\n\n<!-- start -->\nbeta\n<!-- end -->\n");
4949});
50+51+it("replaces headed blocks with CRLF line endings in place", () => {
52+expect(
53+replaceManagedMarkdownBlock({
54+original: "# Title\r\n\r\n## Generated\r\n<!-- start -->\r\n- old\r\n<!-- end -->\r\n",
55+heading: "## Generated",
56+startMarker: "<!-- start -->",
57+endMarker: "<!-- end -->",
58+body: "- new",
59+}),
60+).toBe("# Title\r\n\r\n## Generated\n<!-- start -->\n- new\n<!-- end -->\r\n");
61+});
62+63+it("collapses pre-existing duplicate managed blocks into one", () => {
64+const original = [
65+"# Title",
66+"",
67+"## Generated",
68+"<!-- start -->",
69+"- run-1",
70+"<!-- end -->",
71+"",
72+"## Generated",
73+"<!-- start -->",
74+"- run-2",
75+"<!-- end -->",
76+"",
77+"## Generated",
78+"<!-- start -->",
79+"- run-3",
80+"<!-- end -->",
81+"",
82+].join("\n");
83+84+const updated = replaceManagedMarkdownBlock({
85+ original,
86+heading: "## Generated",
87+startMarker: "<!-- start -->",
88+endMarker: "<!-- end -->",
89+body: "- latest",
90+});
91+92+expect(updated).toBe("# Title\n\n## Generated\n<!-- start -->\n- latest\n<!-- end -->\n");
93+expect(updated.match(/<!-- start -->/g)?.length).toBe(1);
94+expect(updated).not.toContain("run-");
95+});
96+97+it("preserves unmanaged markdown while removing duplicate blocks", () => {
98+const original = [
99+"# Title",
100+"",
101+"Paragraph A",
102+"",
103+"",
104+"Paragraph B",
105+"",
106+"## Generated",
107+"<!-- start -->",
108+"- old",
109+"<!-- end -->",
110+"",
111+"## Generated",
112+"<!-- start -->",
113+"- stale",
114+"<!-- end -->",
115+"",
116+"## Notes",
117+"kept",
118+"",
119+"",
120+].join("\n");
121+122+expect(
123+replaceManagedMarkdownBlock({
124+ original,
125+heading: "## Generated",
126+startMarker: "<!-- start -->",
127+endMarker: "<!-- end -->",
128+body: "- new",
129+}),
130+).toBe(
131+"# Title\n\nParagraph A\n\n\nParagraph B\n\n## Generated\n<!-- start -->\n- new\n<!-- end -->\n\n## Notes\nkept\n\n",
132+);
133+});
134+135+it("is idempotent across repeated calls with the same body", () => {
136+const params = {
137+heading: "## Generated",
138+startMarker: "<!-- start -->",
139+endMarker: "<!-- end -->",
140+body: "- only",
141+} as const;
142+const first = replaceManagedMarkdownBlock({ original: "# Title\n", ...params });
143+const second = replaceManagedMarkdownBlock({ original: first, ...params });
144+const third = replaceManagedMarkdownBlock({ original: second, ...params });
145+146+expect(second).toBe(first);
147+expect(third).toBe(first);
148+});
50149});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。