Skip to content

Commit 996be9c

Browse files
committed
test(cli): normalize typer's rich output before asserting
- typer forces colour on when GITHUB_ACTIONS is set - rich styles an option's leading dash separately, so "--jsondata" is no longer a plain substring - rich wraps at the real terminal width, 80 in CI, 79 on Windows - strip the escape sequences and panel borders, then join the lines
1 parent 2db7c1e commit 996be9c

1 file changed

Lines changed: 25 additions & 3 deletions

File tree

‎tests/test_cli.py‎

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import io
1111
import json
1212
import logging
13+
import re
1314
from unittest.mock import MagicMock
1415

1516
import click
@@ -87,6 +88,27 @@ def _error_lines(stderr: str) -> list[str]:
8788
]
8889

8990

91+
_ANSI = re.compile(r"\x1b\[[0-9;]*m")
92+
_BOX = re.compile(r"[─-╿]") # the Box Drawing block, rich's panel
93+
94+
95+
def _usage_error(result) -> str:
96+
"""``result``'s whole output as one line, without styling or box drawing.
97+
98+
typer renders a usage error through rich, and two parts of that rendering
99+
depend on the environment. typer forces colour on when GITHUB_ACTIONS is
100+
set (typer/rich_utils.py), and rich wraps at the width of the real
101+
terminal. Colour breaks an option name into separate escape sequences,
102+
because rich styles the leading dash on its own, and wrapping breaks it
103+
across two lines. Either one defeats a plain substring check, which is why
104+
these assertions passed on a developer machine and failed in CI. Removing
105+
the escape sequences and the panel borders, then joining the lines, leaves
106+
the words the assertions are about.
107+
"""
108+
text = _ANSI.sub("", result.stdout + result.stderr)
109+
return " ".join(_BOX.sub(" ", text).split())
110+
111+
90112
def _banner_lines(stderr: str) -> list[str]:
91113
"""The ``[osw]`` configuration lines of ``stderr``, in the order printed."""
92114
return [line for line in stderr.strip().splitlines() if line.startswith("[osw] ")]
@@ -624,7 +646,7 @@ def test_root_option_after_command_names_the_correct_form(runner):
624646
result = runner.invoke(app, ["status", "--instance", "wiki-dev.example.org"])
625647

626648
assert result.exit_code != 0
627-
combined = result.stdout + result.stderr
649+
combined = _usage_error(result)
628650
assert "--instance <iri>" in combined
629651
assert "before the command" in combined
630652

@@ -633,7 +655,7 @@ def test_root_option_after_grouped_command_names_the_correct_form(runner):
633655
result = runner.invoke(app, ["entity", "--instance", "x", "get", "T"])
634656

635657
assert result.exit_code != 0
636-
combined = result.stdout + result.stderr
658+
combined = _usage_error(result)
637659
assert "--instance <iri>" in combined
638660
assert "before the command" in combined
639661

@@ -666,6 +688,6 @@ def test_misspelled_command_option_keeps_clicks_suggestion(runner):
666688
result = runner.invoke(app, ["entity", "put", "--json", "{}"])
667689

668690
assert result.exit_code != 0
669-
combined = result.stdout + result.stderr
691+
combined = _usage_error(result)
670692
assert "--jsondata" in combined
671693
assert "before the command" not in combined

0 commit comments

Comments
 (0)