import unittest from app.features.memoir.chapter_markdown_compose import ( compose_ordered_stories_to_markdown, materialize_chapter_markdown_from_loaded_chapter, ) class ChapterMarkdownComposeTest(unittest.TestCase): def test_orders_and_separates_with_headings(self): md = compose_ordered_stories_to_markdown( [("第一章", "正文A"), ("第二章", "正文B")] ) self.assertIn("## 第一章", md) self.assertIn("正文A", md) self.assertIn("## 第二章", md) self.assertIn("正文B", md) self.assertIn("\n\n---\n\n", md) self.assertTrue(md.index("正文A") < md.index("---")) self.assertTrue(md.index("---") < md.index("第二章")) self.assertTrue(md.index("第一章") < md.index("第二章")) def test_preserves_asset_refs(self): body = "![x](asset://abc-123)" md = compose_ordered_stories_to_markdown([("S", body)]) self.assertIn("asset://abc-123", md) def test_empty_title_uses_fallback(self): md = compose_ordered_stories_to_markdown([("", "仅正文")]) self.assertIn("## 故事", md) def test_empty_body_keeps_heading_only(self): md = compose_ordered_stories_to_markdown([("仅标题", "")]) self.assertEqual(md, "## 仅标题") def test_materialize_respects_order_index(self): class _S: def __init__(self, title: str, body: str): self.title = title self.canonical_markdown = body class _L: def __init__(self, o: int, story: _S): self.order_index = o self.story = story ch = type( "Ch", (), { "story_links": [ _L(1, _S("B", "后")), _L(0, _S("A", "先")), ] }, )() md = materialize_chapter_markdown_from_loaded_chapter(ch) self.assertLess(md.index("先"), md.index("后"))