Coverage for tests / test_rich_markup_mode.py: 100%
122 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-03-26 21:46 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-03-26 21:46 +0000
1import os 1abcdefg
2import subprocess 1abcdefg
3import sys 1abcdefg
5import pytest 1abcdefg
6import typer 1abcdefg
7import typer.completion 1abcdefg
8from typer.testing import CliRunner 1abcdefg
10runner = CliRunner() 1abcdefg
11rounded = ["╭", "─", "┬", "╮", "│", "├", "┼", "┤", "╰", "┴", "╯"] 1abcdefg
14def test_rich_markup_mode_none(): 1abcdefg
15 app = typer.Typer(rich_markup_mode=None) 1abcdefg
17 @app.command() 1abcdefg
18 def main(arg: str): 1abcdefg
19 """Main function"""
20 print(f"Hello {arg}") 1abcdefg
22 assert app.rich_markup_mode is None 1abcdefg
24 result = runner.invoke(app, ["World"]) 1abcdefg
25 assert "Hello World" in result.stdout 1abcdefg
27 result = runner.invoke(app, ["--help"]) 1abcdefg
28 assert "ARG [required]" in result.stdout 1abcdefg
29 assert all(c not in result.stdout for c in rounded) 1abcdefg
32def test_rich_markup_mode_rich(): 1abcdefg
33 app = typer.Typer(rich_markup_mode="rich") 1abcdefg
35 @app.command() 1abcdefg
36 def main(arg: str): 1abcdefg
37 """Main function"""
38 print(f"Hello {arg}") 1abcdefg
40 assert app.rich_markup_mode == "rich" 1abcdefg
42 result = runner.invoke(app, ["World"]) 1abcdefg
43 assert "Hello World" in result.stdout 1abcdefg
45 result = runner.invoke(app, ["--help"]) 1abcdefg
46 assert any(c in result.stdout for c in rounded) 1abcdefg
49@pytest.mark.parametrize( 1abcdefg
50 "env_var_value, expected_result",
51 [
52 ("1", True),
53 ("True", True),
54 ("TRUE", True),
55 ("true", True),
56 ("0", False),
57 ("False", False),
58 ("FALSE", False),
59 ("false", False),
60 ("somerandomvalue", True),
61 ],
62)
63def test_rich_markup_mode_envvar(env_var_value: str, expected_result: bool): 1abcdefg
64 result = subprocess.run( 1abcdefg
65 [
66 sys.executable,
67 "-m",
68 "coverage",
69 "run",
70 "-m",
71 "typer",
72 "tests/assets/cli/sample.py",
73 "--help",
74 ],
75 capture_output=True,
76 env={
77 **os.environ,
78 "TYPER_USE_RICH": env_var_value,
79 "PYTHONIOENCODING": "utf-8",
80 },
81 encoding="utf-8",
82 )
83 assert any(c in result.stdout for c in rounded) == expected_result 1abcdefg
86@pytest.mark.parametrize( 1abcdefg
87 "mode,lines",
88 [
89 pytest.param(
90 "markdown",
91 ["First line", "", "Line 1", "", "Line 2", "", "Line 3", ""],
92 ),
93 pytest.param(
94 "rich", ["First line", "", "Line 1", "", "Line 2", "", "Line 3", ""]
95 ),
96 pytest.param(
97 None, ["First line", "", "Line 1", "", "Line 2", "", "Line 3", ""]
98 ),
99 ],
100)
101def test_markup_mode_newline_pr815(mode: str, lines: list[str]): 1abcdefg
102 app = typer.Typer(rich_markup_mode=mode) 1abcdefg
104 @app.command() 1abcdefg
105 def main(arg: str): 1abcdefg
106 """First line
108 Line 1
110 Line 2
112 Line 3
113 """
114 print(f"Hello {arg}") 1abcdefg
116 assert app.rich_markup_mode == mode 1abcdefg
118 result = runner.invoke(app, ["World"]) 1abcdefg
119 assert "Hello World" in result.stdout 1abcdefg
121 result = runner.invoke(app, ["--help"]) 1abcdefg
122 result_lines = [line.strip() for line in result.stdout.split("\n")] 1abcdefg
123 if mode: 1abcdefg
124 assert any(c in result.stdout for c in rounded) 1abcdefg
125 help_start = result_lines.index("First line") 1abcdefg
126 arg_start = [i for i, row in enumerate(result_lines) if "Arguments" in row][0] 1abcdefg
127 assert help_start != -1 1abcdefg
128 assert result_lines[help_start:arg_start] == lines 1abcdefg
131@pytest.mark.parametrize( 1abcdefg
132 "mode,lines",
133 [
134 pytest.param("markdown", ["First line", "", "Line 1 Line 2 Line 3", ""]),
135 pytest.param("rich", ["First line", "", "Line 1", "Line 2", "Line 3", ""]),
136 pytest.param(None, ["First line", "", "Line 1 Line 2 Line 3", ""]),
137 ],
138)
139def test_markup_mode_newline_issue447(mode: str, lines: list[str]): 1abcdefg
140 app = typer.Typer(rich_markup_mode=mode) 1abcdefg
142 @app.command() 1abcdefg
143 def main(arg: str): 1abcdefg
144 """First line
146 Line 1
147 Line 2
148 Line 3
149 """
150 print(f"Hello {arg}") 1abcdefg
152 assert app.rich_markup_mode == mode 1abcdefg
154 result = runner.invoke(app, ["World"]) 1abcdefg
155 assert "Hello World" in result.stdout 1abcdefg
157 result = runner.invoke(app, ["--help"]) 1abcdefg
158 result_lines = [line.strip() for line in result.stdout.split("\n")] 1abcdefg
159 if mode: 1abcdefg
160 assert any(c in result.stdout for c in rounded) 1abcdefg
161 help_start = result_lines.index("First line") 1abcdefg
162 arg_start = [i for i, row in enumerate(result_lines) if "Arguments" in row][0] 1abcdefg
163 assert help_start != -1 1abcdefg
164 assert result_lines[help_start:arg_start] == lines 1abcdefg
167@pytest.mark.parametrize( 1abcdefg
168 "mode,lines",
169 [
170 pytest.param(
171 "markdown",
172 [
173 "This header is long",
174 "",
175 "Line 1",
176 "",
177 "Line 2 continues here",
178 "",
179 "Line 3",
180 "",
181 ],
182 ),
183 pytest.param(
184 "rich",
185 [
186 "This header is long",
187 "",
188 "Line 1",
189 "",
190 "Line 2",
191 "continues here",
192 "",
193 "Line 3",
194 "",
195 ],
196 ),
197 pytest.param(
198 None,
199 [
200 "This header is long",
201 "",
202 "Line 1",
203 "",
204 "Line 2 continues here",
205 "",
206 "Line 3",
207 "",
208 ],
209 ),
210 ],
211)
212def test_markup_mode_newline_mixed(mode: str, lines: list[str]): 1abcdefg
213 app = typer.Typer(rich_markup_mode=mode) 1abcdefg
215 @app.command() 1abcdefg
216 def main(arg: str): 1abcdefg
217 """This header
218 is long
220 Line 1
222 Line 2
223 continues here
225 Line 3
226 """
227 print(f"Hello {arg}") 1abcdefg
229 assert app.rich_markup_mode == mode 1abcdefg
231 result = runner.invoke(app, ["World"]) 1abcdefg
232 assert "Hello World" in result.stdout 1abcdefg
234 result = runner.invoke(app, ["--help"]) 1abcdefg
235 result_lines = [line.strip() for line in result.stdout.split("\n")] 1abcdefg
236 if mode: 1abcdefg
237 assert any(c in result.stdout for c in rounded) 1abcdefg
238 help_start = [i for i, row in enumerate(result_lines) if "This header" in row][0] 1abcdefg
239 arg_start = [i for i, row in enumerate(result_lines) if "Arguments" in row][0] 1abcdefg
240 assert help_start != -1 1abcdefg
241 assert result_lines[help_start:arg_start] == lines 1abcdefg
244@pytest.mark.parametrize( 1abcdefg
245 "mode,lines",
246 [
247 pytest.param(
248 "markdown",
249 ["First line", "", "• 1", "• 2", "• 3", ""],
250 marks=pytest.mark.xfail,
251 ),
252 pytest.param("rich", ["First line", "", "- 1", "- 2", "- 3", ""]),
253 pytest.param(None, ["First line", "", "- 1 - 2 - 3", ""]),
254 ],
255)
256def test_markup_mode_bullets_single_newline(mode: str, lines: list[str]): 1abcdefg
257 app = typer.Typer(rich_markup_mode=mode) 1abcdefg
259 @app.command() 1abcdefg
260 def main(arg: str): 1abcdefg
261 """First line
263 - 1
264 - 2
265 - 3
266 """
267 print(f"Hello {arg}") 1abcdefg
269 assert app.rich_markup_mode == mode 1abcdefg
271 result = runner.invoke(app, ["World"]) 1abcdefg
272 assert "Hello World" in result.stdout 1abcdefg
274 result = runner.invoke(app, ["--help"]) 1abcdefg
275 result_lines = [line.strip() for line in result.stdout.split("\n")] 1abcdefg
276 if mode: 1abcdefg
277 assert any(c in result.stdout for c in rounded) 1abcdefg
278 help_start = result_lines.index("First line") 1abcdefg
279 arg_start = [i for i, row in enumerate(result_lines) if "Arguments" in row][0] 1abcdefg
280 assert help_start != -1 1abcdefg
281 assert result_lines[help_start:arg_start] == lines 1abcdefg
284@pytest.mark.parametrize( 1abcdefg
285 "mode,lines",
286 [
287 pytest.param(
288 "markdown",
289 ["First line", "", "• 1", "• 2", "• 3", ""],
290 marks=pytest.mark.xfail,
291 ),
292 (
293 "rich",
294 ["First line", "", "- 1", "", "- 2", "", "- 3", ""],
295 ),
296 (None, ["First line", "", "- 1", "", "- 2", "", "- 3", ""]),
297 ],
298)
299def test_markup_mode_bullets_double_newline(mode: str, lines: list[str]): 1abcdefg
300 app = typer.Typer(rich_markup_mode=mode) 1abcdefg
302 @app.command() 1abcdefg
303 def main(arg: str): 1abcdefg
304 """First line
306 - 1
308 - 2
310 - 3
311 """
312 print(f"Hello {arg}") 1abcdefg
314 assert app.rich_markup_mode == mode 1abcdefg
316 result = runner.invoke(app, ["World"]) 1abcdefg
317 assert "Hello World" in result.stdout 1abcdefg
319 result = runner.invoke(app, ["--help"]) 1abcdefg
320 result_lines = [line.strip() for line in result.stdout.split("\n")] 1abcdefg
321 if mode: 1abcdefg
322 assert any(c in result.stdout for c in rounded) 1abcdefg
323 help_start = result_lines.index("First line") 1abcdefg
324 arg_start = [i for i, row in enumerate(result_lines) if "Arguments" in row][0] 1abcdefg
325 assert help_start != -1 1abcdefg
326 assert result_lines[help_start:arg_start] == lines 1abcdefg
329def test_markup_mode_default(): 1abcdefg
330 # We're assuming the test suite is run with rich installed
331 app = typer.Typer() 1abcdefg
332 assert app.rich_markup_mode == "rich" 1abcdefg