Skip to content

Commit bd062bc

Browse files
šŸ› Fix newline after header in help text, and add more tests for the behaviour of rich_markup_mode (#964)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 202f55a commit bd062bc

File tree

2 files changed

+251
-0
lines changed

2 files changed

+251
-0
lines changed

ā€Žtests/test_rich_markup_mode.py

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from typing import List
2+
3+
import pytest
14
import typer
25
import typer.completion
36
from typer.testing import CliRunner
@@ -38,3 +41,248 @@ def main(arg: str):
3841

3942
result = runner.invoke(app, ["--help"])
4043
assert any(c in result.stdout for c in rounded)
44+
45+
46+
@pytest.mark.parametrize(
47+
"mode,lines",
48+
[
49+
pytest.param(
50+
"markdown",
51+
["First line", "", "Line 1", "", "Line 2", "", "Line 3", ""],
52+
marks=pytest.mark.xfail,
53+
),
54+
pytest.param(
55+
"rich", ["First line", "", "Line 1", "", "Line 2", "", "Line 3", ""]
56+
),
57+
pytest.param(
58+
None, ["First line", "", "Line 1", "", "Line 2", "", "Line 3", ""]
59+
),
60+
],
61+
)
62+
def test_markup_mode_newline_pr815(mode: str, lines: List[str]):
63+
app = typer.Typer(rich_markup_mode=mode)
64+
65+
@app.command()
66+
def main(arg: str):
67+
"""First line
68+
69+
Line 1
70+
71+
Line 2
72+
73+
Line 3
74+
"""
75+
print(f"Hello {arg}")
76+
77+
assert app.rich_markup_mode == mode
78+
79+
result = runner.invoke(app, ["World"])
80+
assert "Hello World" in result.stdout
81+
82+
result = runner.invoke(app, ["--help"])
83+
result_lines = [line.strip() for line in result.stdout.split("\n")]
84+
if mode:
85+
assert any(c in result.stdout for c in rounded)
86+
help_start = result_lines.index("First line")
87+
arg_start = [i for i, row in enumerate(result_lines) if "Arguments" in row][0]
88+
assert help_start != -1
89+
assert result_lines[help_start:arg_start] == lines
90+
91+
92+
@pytest.mark.parametrize(
93+
"mode,lines",
94+
[
95+
pytest.param("markdown", ["First line", "", "Line 1 Line 2 Line 3", ""]),
96+
pytest.param("rich", ["First line", "", "Line 1", "Line 2", "Line 3", ""]),
97+
pytest.param(None, ["First line", "", "Line 1 Line 2 Line 3", ""]),
98+
],
99+
)
100+
def test_markup_mode_newline_issue447(mode: str, lines: List[str]):
101+
app = typer.Typer(rich_markup_mode=mode)
102+
103+
@app.command()
104+
def main(arg: str):
105+
"""First line
106+
107+
Line 1
108+
Line 2
109+
Line 3
110+
"""
111+
print(f"Hello {arg}")
112+
113+
assert app.rich_markup_mode == mode
114+
115+
result = runner.invoke(app, ["World"])
116+
assert "Hello World" in result.stdout
117+
118+
result = runner.invoke(app, ["--help"])
119+
result_lines = [line.strip() for line in result.stdout.split("\n")]
120+
if mode:
121+
assert any(c in result.stdout for c in rounded)
122+
help_start = result_lines.index("First line")
123+
arg_start = [i for i, row in enumerate(result_lines) if "Arguments" in row][0]
124+
assert help_start != -1
125+
assert result_lines[help_start:arg_start] == lines
126+
127+
128+
@pytest.mark.parametrize(
129+
"mode,lines",
130+
[
131+
pytest.param(
132+
"markdown",
133+
[
134+
"This header is long",
135+
"",
136+
"Line 1",
137+
"",
138+
"Line 2 continues here",
139+
"",
140+
"Line 3",
141+
"",
142+
],
143+
marks=pytest.mark.xfail,
144+
),
145+
pytest.param(
146+
"rich",
147+
[
148+
"This header is long",
149+
"",
150+
"Line 1",
151+
"",
152+
"Line 2",
153+
"continues here",
154+
"",
155+
"Line 3",
156+
"",
157+
],
158+
),
159+
pytest.param(
160+
None,
161+
[
162+
"This header is long",
163+
"",
164+
"Line 1",
165+
"",
166+
"Line 2 continues here",
167+
"",
168+
"Line 3",
169+
"",
170+
],
171+
),
172+
],
173+
)
174+
def test_markup_mode_newline_mixed(mode: str, lines: List[str]):
175+
app = typer.Typer(rich_markup_mode=mode)
176+
177+
@app.command()
178+
def main(arg: str):
179+
"""This header
180+
is long
181+
182+
Line 1
183+
184+
Line 2
185+
continues here
186+
187+
Line 3
188+
"""
189+
print(f"Hello {arg}")
190+
191+
assert app.rich_markup_mode == mode
192+
193+
result = runner.invoke(app, ["World"])
194+
assert "Hello World" in result.stdout
195+
196+
result = runner.invoke(app, ["--help"])
197+
result_lines = [line.strip() for line in result.stdout.split("\n")]
198+
if mode:
199+
assert any(c in result.stdout for c in rounded)
200+
help_start = [i for i, row in enumerate(result_lines) if "This header" in row][0]
201+
arg_start = [i for i, row in enumerate(result_lines) if "Arguments" in row][0]
202+
assert help_start != -1
203+
assert result_lines[help_start:arg_start] == lines
204+
205+
206+
@pytest.mark.parametrize(
207+
"mode,lines",
208+
[
209+
pytest.param(
210+
"markdown",
211+
["First line", "", "• 1", "• 2", "• 3", ""],
212+
marks=pytest.mark.xfail,
213+
),
214+
pytest.param("rich", ["First line", "", "- 1", "- 2", "- 3", ""]),
215+
pytest.param(None, ["First line", "", "- 1 - 2 - 3", ""]),
216+
],
217+
)
218+
def test_markup_mode_bullets_single_newline(mode: str, lines: List[str]):
219+
app = typer.Typer(rich_markup_mode=mode)
220+
221+
@app.command()
222+
def main(arg: str):
223+
"""First line
224+
225+
- 1
226+
- 2
227+
- 3
228+
"""
229+
print(f"Hello {arg}")
230+
231+
assert app.rich_markup_mode == mode
232+
233+
result = runner.invoke(app, ["World"])
234+
assert "Hello World" in result.stdout
235+
236+
result = runner.invoke(app, ["--help"])
237+
result_lines = [line.strip() for line in result.stdout.split("\n")]
238+
if mode:
239+
assert any(c in result.stdout for c in rounded)
240+
help_start = result_lines.index("First line")
241+
arg_start = [i for i, row in enumerate(result_lines) if "Arguments" in row][0]
242+
assert help_start != -1
243+
assert result_lines[help_start:arg_start] == lines
244+
245+
246+
@pytest.mark.parametrize(
247+
"mode,lines",
248+
[
249+
pytest.param(
250+
"markdown",
251+
["First line", "", "• 1", "• 2", "• 3", ""],
252+
marks=pytest.mark.xfail,
253+
),
254+
(
255+
"rich",
256+
["First line", "", "- 1", "", "- 2", "", "- 3", ""],
257+
),
258+
(None, ["First line", "", "- 1", "", "- 2", "", "- 3", ""]),
259+
],
260+
)
261+
def test_markup_mode_bullets_double_newline(mode: str, lines: List[str]):
262+
app = typer.Typer(rich_markup_mode=mode)
263+
264+
@app.command()
265+
def main(arg: str):
266+
"""First line
267+
268+
- 1
269+
270+
- 2
271+
272+
- 3
273+
"""
274+
print(f"Hello {arg}")
275+
276+
assert app.rich_markup_mode == mode
277+
278+
result = runner.invoke(app, ["World"])
279+
assert "Hello World" in result.stdout
280+
281+
result = runner.invoke(app, ["--help"])
282+
result_lines = [line.strip() for line in result.stdout.split("\n")]
283+
if mode:
284+
assert any(c in result.stdout for c in rounded)
285+
help_start = result_lines.index("First line")
286+
arg_start = [i for i, row in enumerate(result_lines) if "Arguments" in row][0]
287+
assert help_start != -1
288+
assert result_lines[help_start:arg_start] == lines

ā€Žtyper/rich_utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ def _get_help_text(
200200
markup_mode=markup_mode,
201201
)
202202

203+
# Add a newline inbetween the header and the remaining paragraphs
204+
yield Text("")
205+
203206
# Get remaining lines, remove single line breaks and format as dim
204207
remaining_paragraphs = help_text.split("\n\n")[1:]
205208
if remaining_paragraphs:

0 commit comments

Comments
Ā (0)