test_cli_markdown_rendering.py
1 from io import StringIO 2 3 from rich.console import Console 4 from rich.markdown import Markdown 5 6 from cli import _render_final_assistant_content 7 8 9 def _render_to_text(renderable) -> str: 10 buf = StringIO() 11 Console(file=buf, width=80, force_terminal=False, color_system=None).print(renderable) 12 return buf.getvalue() 13 14 15 def test_final_assistant_content_uses_markdown_renderable(): 16 renderable = _render_final_assistant_content("# Title\n\n- one\n- two") 17 18 assert isinstance(renderable, Markdown) 19 output = _render_to_text(renderable) 20 assert "Title" in output 21 assert "one" in output 22 assert "two" in output 23 24 25 def test_final_assistant_content_preserves_windows_hidden_dir_paths(): 26 renderable = _render_final_assistant_content( 27 r"D:\Projects\SourceCode\hermes-agent\.ai\skills" + "\\" 28 ) 29 30 output = _render_to_text(renderable) 31 assert r"D:\Projects\SourceCode\hermes-agent\.ai\skills" + "\\" in output 32 33 34 def test_final_assistant_content_keeps_non_path_markdown_escapes(): 35 renderable = _render_final_assistant_content(r"1\. Not an ordered list") 36 37 output = _render_to_text(renderable) 38 assert "1. Not an ordered list" in output 39 assert r"1\." not in output 40 41 42 def test_final_assistant_content_strips_ansi_before_markdown_rendering(): 43 renderable = _render_final_assistant_content("\x1b[31m# Title\x1b[0m") 44 45 output = _render_to_text(renderable) 46 assert "Title" in output 47 assert "\x1b" not in output 48 49 50 def test_final_assistant_content_can_strip_markdown_syntax(): 51 renderable = _render_final_assistant_content( 52 "***Bold italic***\n~~Strike~~\n- item\n# Title\n`code`", 53 mode="strip", 54 ) 55 56 output = _render_to_text(renderable) 57 assert "Bold italic" in output 58 assert "Strike" in output 59 assert "item" in output 60 assert "Title" in output 61 assert "code" in output 62 assert "***" not in output 63 assert "~~" not in output 64 assert "`" not in output 65 66 67 def test_strip_mode_preserves_lists(): 68 renderable = _render_final_assistant_content( 69 "**Formatting**\n- Ran prettier\n- Files changed\n- Verified clean", 70 mode="strip", 71 ) 72 73 output = _render_to_text(renderable) 74 assert "- Ran prettier" in output 75 assert "- Files changed" in output 76 assert "- Verified clean" in output 77 assert "**" not in output 78 79 80 def test_strip_mode_preserves_ordered_lists(): 81 renderable = _render_final_assistant_content( 82 "1. First item\n2. Second item\n3. Third item", 83 mode="strip", 84 ) 85 86 output = _render_to_text(renderable) 87 assert "1. First" in output 88 assert "2. Second" in output 89 assert "3. Third" in output 90 91 92 def test_strip_mode_preserves_blockquotes(): 93 renderable = _render_final_assistant_content( 94 "> This is quoted text\n> Another quoted line", 95 mode="strip", 96 ) 97 98 output = _render_to_text(renderable) 99 assert "> This is quoted" in output 100 assert "> Another quoted" in output 101 102 103 def test_strip_mode_preserves_checkboxes(): 104 renderable = _render_final_assistant_content( 105 "- [ ] Todo item\n- [x] Done item", 106 mode="strip", 107 ) 108 109 output = _render_to_text(renderable) 110 assert "- [ ] Todo" in output 111 assert "- [x] Done" in output 112 113 114 def test_strip_mode_preserves_table_structure_while_cleaning_cell_markdown(): 115 renderable = _render_final_assistant_content( 116 "| Syntax | Example |\n|---|---|\n| Bold | `**bold**` |\n| Strike | `~~strike~~` |", 117 mode="strip", 118 ) 119 120 output = _render_to_text(renderable) 121 assert "| Syntax | Example |" in output 122 assert "|---|---|" in output 123 assert "| Bold | bold |" in output 124 assert "| Strike | strike |" in output 125 assert "**" not in output 126 assert "~~" not in output 127 assert "`" not in output 128 129 130 def test_final_assistant_content_can_leave_markdown_raw(): 131 renderable = _render_final_assistant_content("***Bold italic***", mode="raw") 132 133 output = _render_to_text(renderable) 134 assert "***Bold italic***" in output 135 136 137 def test_strip_mode_preserves_intraword_underscores_in_snake_case_identifiers(): 138 renderable = _render_final_assistant_content( 139 "Let me look at test_case_with_underscores and SOME_CONST " 140 "then /tmp/snake_case_dir/file_with_name.py", 141 mode="strip", 142 ) 143 144 output = _render_to_text(renderable) 145 assert "test_case_with_underscores" in output 146 assert "SOME_CONST" in output 147 assert "snake_case_dir" in output 148 assert "file_with_name" in output 149 150 151 def test_strip_mode_still_strips_boundary_underscore_emphasis(): 152 renderable = _render_final_assistant_content( 153 "say _hi_ and __bold__ now", 154 mode="strip", 155 ) 156 157 output = _render_to_text(renderable) 158 assert "say hi and bold now" in output