"""用户版更新日志:CHANGELOG.md 解析器(web/app.py::_parse_changelog)。""" import unittest from web.app import _CHANGELOG_PATH, _parse_changelog SAMPLE = """# 更新日志 > 导语在首个条目前,应被丢弃。 ## 0.55.0 — 2026-07-09 - 条目 A ## v0.54.1 - 2026-07-09 - 条目 B - 条目 C ## 0.53.0 - 无日期条目 """ class ChangelogParseTests(unittest.TestCase): def test_sample_parses_versions_dates_and_bodies(self) -> None: es = _parse_changelog(SAMPLE) self.assertEqual([e["version"] for e in es], ["0.55.0", "0.54.1", "0.53.0"]) self.assertEqual(es[0]["date"], "2026-07-09") self.assertEqual(es[1]["date"], "2026-07-09") # v 前缀 + 单横线也认 self.assertIsNone(es[2]["date"]) # 日期可省 self.assertEqual(es[0]["body_md"], "- 条目 A") self.assertIn("条目 C", es[1]["body_md"]) def test_preamble_before_first_entry_is_dropped(self) -> None: es = _parse_changelog(SAMPLE) self.assertNotIn("导语", es[0]["body_md"]) def test_real_changelog_file_parses(self) -> None: # 仓库里的真文件:格式坏了(条目头打错 / 空正文)在 CI 就翻车,不等用户点开才发现 es = _parse_changelog(_CHANGELOG_PATH.read_text(encoding="utf-8")) self.assertGreater(len(es), 0) for e in es: self.assertRegex(e["version"], r"^\d+\.\d+") self.assertTrue(e["body_md"], f"empty body for {e['version']}") if __name__ == "__main__": unittest.main()