Skip to content

Commit 88e517c

Browse files
committed
Added unit tests for printing.
1 parent f0060b7 commit 88e517c

File tree

5 files changed

+108
-4
lines changed

5 files changed

+108
-4
lines changed

cmd2/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
)
4545
from .parsing import Statement
4646
from .py_bridge import CommandResult
47+
from .rich_utils import RichPrintKwargs
4748
from .string_utils import stylize
4849
from .styles import Cmd2Style
4950
from .utils import (
@@ -86,6 +87,8 @@
8687
'plugin',
8788
'rich_utils',
8889
'string_utils',
90+
# Rich Utils
91+
'RichPrintKwargs',
8992
# String Utils
9093
'stylize',
9194
# Styles,

cmd2/argparse_custom.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ def __init__(self, value: object, descriptive_data: Sequence[Any], *args: Any) -
399399
renderable_data = [obj if is_renderable(obj) else str(obj) for obj in descriptive_data]
400400

401401
# Convert objects with ANSI styles to Rich Text for correct display width.
402-
self.descriptive_data = ru.prepare_objects_for_rich_rendering(*renderable_data)
402+
self.descriptive_data = ru.prepare_objects_for_rendering(*renderable_data)
403403

404404
# Save the original value to support CompletionItems as argparse choices.
405405
# cmd2 has patched argparse so input is compared to this value instead of the CompletionItem instance.

cmd2/cmd2.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,7 @@ def print_to(
12251225
method and still call `super()` without encountering unexpected keyword argument errors.
12261226
These arguments are not passed to Rich's Console.print().
12271227
"""
1228-
prepared_objects = ru.prepare_objects_for_rich_rendering(*objects)
1228+
prepared_objects = ru.prepare_objects_for_rendering(*objects)
12291229

12301230
try:
12311231
Cmd2GeneralConsole(file).print(
@@ -1469,7 +1469,7 @@ def ppaged(
14691469

14701470
# Check if we are outputting to a pager.
14711471
if functional_terminal and can_block:
1472-
prepared_objects = ru.prepare_objects_for_rich_rendering(*objects)
1472+
prepared_objects = ru.prepare_objects_for_rendering(*objects)
14731473

14741474
# Chopping overrides soft_wrap
14751475
if chop:

cmd2/rich_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ def indent(renderable: RenderableType, level: int) -> Padding:
299299
return Padding.indent(renderable, level)
300300

301301

302-
def prepare_objects_for_rich_rendering(*objects: Any) -> tuple[Any, ...]:
302+
def prepare_objects_for_rendering(*objects: Any) -> tuple[Any, ...]:
303303
"""Prepare a tuple of objects for printing by Rich's Console.print().
304304
305305
This function converts any non-Rich object whose string representation contains

tests/test_cmd2.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
COMMAND_NAME,
2121
Cmd2Style,
2222
Color,
23+
RichPrintKwargs,
2324
clipboard,
2425
constants,
2526
exceptions,
@@ -2133,6 +2134,106 @@ def test_poutput_ansi_terminal(outsim_app) -> None:
21332134
assert out == expected
21342135

21352136

2137+
@with_ansi_style(ru.AllowStyle.ALWAYS)
2138+
def test_poutput_highlight(outsim_app):
2139+
rich_print_kwargs = RichPrintKwargs(highlight=True)
2140+
outsim_app.poutput(
2141+
"My IP Address is 192.168.1.100.",
2142+
rich_print_kwargs=rich_print_kwargs,
2143+
)
2144+
out = outsim_app.stdout.getvalue()
2145+
assert out == "My IP Address is \x1b[1;92m192.168.1.100\x1b[0m.\n"
2146+
2147+
2148+
@with_ansi_style(ru.AllowStyle.ALWAYS)
2149+
def test_poutput_markup(outsim_app):
2150+
rich_print_kwargs = RichPrintKwargs(markup=True)
2151+
outsim_app.poutput(
2152+
"The leaves are [green]green[/green].",
2153+
rich_print_kwargs=rich_print_kwargs,
2154+
)
2155+
out = outsim_app.stdout.getvalue()
2156+
assert out == "The leaves are \x1b[32mgreen\x1b[0m.\n"
2157+
2158+
2159+
@with_ansi_style(ru.AllowStyle.ALWAYS)
2160+
def test_poutput_emoji(outsim_app):
2161+
rich_print_kwargs = RichPrintKwargs(emoji=True)
2162+
outsim_app.poutput(
2163+
"Look at the emoji :1234:.",
2164+
rich_print_kwargs=rich_print_kwargs,
2165+
)
2166+
out = outsim_app.stdout.getvalue()
2167+
assert out == "Look at the emoji 🔢.\n"
2168+
2169+
2170+
@with_ansi_style(ru.AllowStyle.ALWAYS)
2171+
def test_poutput_justify_and_width(outsim_app):
2172+
rich_print_kwargs = RichPrintKwargs(justify="right", width=10)
2173+
2174+
# Use a styled-string when justifying to check if its display width is correct.
2175+
outsim_app.poutput(
2176+
su.stylize("Hello", style="blue"),
2177+
rich_print_kwargs=rich_print_kwargs,
2178+
)
2179+
out = outsim_app.stdout.getvalue()
2180+
assert out == " \x1b[34mHello\x1b[0m\n"
2181+
2182+
2183+
@with_ansi_style(ru.AllowStyle.ALWAYS)
2184+
def test_poutput_no_wrap_and_overflow(outsim_app):
2185+
rich_print_kwargs = RichPrintKwargs(no_wrap=True, overflow="ellipsis", width=10)
2186+
2187+
outsim_app.poutput(
2188+
"This is longer than width.",
2189+
soft_wrap=False,
2190+
rich_print_kwargs=rich_print_kwargs,
2191+
)
2192+
out = outsim_app.stdout.getvalue()
2193+
assert out.startswith("This is l…\n")
2194+
2195+
2196+
@with_ansi_style(ru.AllowStyle.ALWAYS)
2197+
def test_poutput_pretty_print(outsim_app):
2198+
"""Test that cmd2 passes objects through so they can be pretty-printed when highlighting is enabled."""
2199+
rich_print_kwargs = RichPrintKwargs(highlight=True)
2200+
dictionary = {1: 'hello', 2: 'person', 3: 'who', 4: 'codes'}
2201+
2202+
outsim_app.poutput(
2203+
dictionary,
2204+
rich_print_kwargs=rich_print_kwargs,
2205+
)
2206+
out = outsim_app.stdout.getvalue()
2207+
assert out.startswith("\x1b[1m{\x1b[0m\x1b[1;36m1\x1b[0m: \x1b[32m'hello'\x1b[0m")
2208+
2209+
2210+
@with_ansi_style(ru.AllowStyle.ALWAYS)
2211+
def test_poutput_all_keyword_args(outsim_app):
2212+
"""Test that all fields in RichPrintKwargs are recognized by Rich's Console.print()."""
2213+
rich_print_kwargs = RichPrintKwargs(
2214+
justify="center",
2215+
overflow="ellipsis",
2216+
no_wrap=True,
2217+
markup=True,
2218+
emoji=True,
2219+
highlight=True,
2220+
width=40,
2221+
height=50,
2222+
crop=False,
2223+
new_line_start=True,
2224+
)
2225+
2226+
outsim_app.poutput(
2227+
"My string",
2228+
rich_print_kwargs=rich_print_kwargs,
2229+
)
2230+
2231+
# Verify that something printed which means Console.print() didn't
2232+
# raise a TypeError for an unexpected keyword argument.
2233+
out = outsim_app.stdout.getvalue()
2234+
assert "My string" in out
2235+
2236+
21362237
def test_broken_pipe_error(outsim_app, monkeypatch, capsys):
21372238
write_mock = mock.MagicMock()
21382239
write_mock.side_effect = BrokenPipeError

0 commit comments

Comments
 (0)