From 41af4896482ca76ea150aa58a869e75f24bb661c Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 5 Apr 2023 10:10:43 +0100 Subject: [PATCH] title descriptors (#2213) * title descriptors * add extra line around titles * changelog * snapshots * comment * Fix border refresh * simplify typing * test for None case --- CHANGELOG.md | 7 + src/textual/_border.py | 12 +- src/textual/_styles_cache.py | 15 +- src/textual/app.py | 2 + src/textual/widget.py | 54 +- .../__snapshots__/test_snapshots.ambr | 478 +++++++++--------- tests/test_border.py | 28 +- 7 files changed, 318 insertions(+), 278 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aba3ff935..153928d2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## Unreleased + +### Changed + +- Allowed border_title and border_subtitle to accept Text objects +- Added additional line around titles + ## [0.18.0] - 2023-04-04 ### Added diff --git a/src/textual/_border.py b/src/textual/_border.py index 5fe76cc3b..3b3bf2670 100644 --- a/src/textual/_border.py +++ b/src/textual/_border.py @@ -283,7 +283,7 @@ def get_box( def render_border_label( - label: str, + label: Text, is_title: bool, name: EdgeType, width: int, @@ -323,12 +323,10 @@ def render_border_label( # How many cells do we need to reserve for surrounding blanks and corners? corners_needed = has_left_corner + has_right_corner cells_reserved = 2 * corners_needed - if not label or width <= cells_reserved: + if not label.cell_len or width <= cells_reserved: return - text_label = Text.from_markup(label) - if not text_label.cell_len: - return + text_label = label.copy() text_label.truncate(width - cells_reserved, overflow="ellipsis") segments = text_label.render(console) @@ -401,13 +399,15 @@ def render_row( elif not label_length: yield Segment(box2.text * space_available, box2.style) elif label_alignment == "left" or label_alignment == "right": - edge = Segment(box2.text * space_available, box2.style) + edge = Segment(box2.text * (space_available - 1), box2.style) if label_alignment == "left": + yield Segment(box2.text, box2.style) yield from label_segments_list yield edge else: yield edge yield from label_segments_list + yield Segment(box2.text, box2.style) elif label_alignment == "center": length_on_left = space_available // 2 length_on_right = space_available - length_on_left diff --git a/src/textual/_styles_cache.py b/src/textual/_styles_cache.py index c66149717..8092f0c45 100644 --- a/src/textual/_styles_cache.py +++ b/src/textual/_styles_cache.py @@ -7,6 +7,7 @@ from typing import TYPE_CHECKING, Callable, Iterable from rich.console import Console from rich.segment import Segment from rich.style import Style +from rich.text import Text from ._border import get_box, render_border_label, render_row from ._opacity import _apply_opacity @@ -115,8 +116,8 @@ class StylesCache: background, widget.render_line, widget.app.console, - widget.border_title, - widget.border_subtitle, + widget._border_title, + widget._border_subtitle, content_size=widget.content_region.size, padding=styles.padding, crop=crop, @@ -146,8 +147,8 @@ class StylesCache: background: Color, render_content_line: RenderLineCallback, console: Console, - border_title: str, - border_subtitle: str, + border_title: Text | None, + border_subtitle: Text | None, content_size: Size | None = None, padding: Spacing | None = None, crop: Region | None = None, @@ -228,8 +229,8 @@ class StylesCache: background: Color, render_content_line: Callable[[int], Strip], console: Console, - border_title: str, - border_subtitle: str, + border_title: Text | None, + border_subtitle: Text | None, ) -> Strip: """Render a styled line. @@ -310,7 +311,7 @@ class StylesCache: border_label, is_top, border_edge_type, - width, + width - 2, inner, outer, border_color_as_style, diff --git a/src/textual/app.py b/src/textual/app.py index aeba923df..647a805f7 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -1011,6 +1011,8 @@ class App(Generic[ReturnType], DOMNode): ) try: + app._loop = asyncio.get_running_loop() + app._thread_id = threading.get_ident() await app._process_messages( ready_callback=None if auto_pilot is None else app_ready, headless=headless, diff --git a/src/textual/widget.py b/src/textual/widget.py index d387523cb..fc5c8fb62 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -188,6 +188,34 @@ class PseudoClasses(NamedTuple): hover: bool +class _BorderTitle: + """Descriptor to set border titles.""" + + def __set_name__(self, owner: Widget, name: str) -> None: + # The private name where we store the real data. + self._internal_name = f"_{name}" + + def __set__(self, obj: Widget, title: str | Text | None) -> None: + """Setting a title accepts a str, Text, or None.""" + if title is None: + setattr(obj, self._internal_name, None) + else: + # We store the title as Text + new_title = obj.render_str(title) + new_title.expand_tabs(4) + new_title = new_title.split()[0] + setattr(obj, self._internal_name, new_title) + obj.refresh() + + def __get__(self, obj: Widget, objtype: type[Widget] | None = None) -> str | None: + """Getting a title will return None or a str as console markup.""" + title: Text | None = getattr(obj, self._internal_name, None) + if title is None: + return None + # If we have a title, convert from Text to console markup + return title.markup + + @rich.repr.auto class Widget(DOMNode): """ @@ -241,10 +269,6 @@ class Widget(DOMNode): """Widget will highlight links automatically.""" disabled = Reactive(False) """The disabled state of the widget. `True` if disabled, `False` if not.""" - border_title = Reactive("") - """The one-line border title, which may contain markup to be parsed.""" - border_subtitle = Reactive("") - """The one-line border subtitle, which may contain markup to be parsed.""" hover_style: Reactive[Style] = Reactive(Style, repaint=False) highlight_link_id: Reactive[str] = Reactive("") @@ -270,6 +294,9 @@ class Widget(DOMNode): self._horizontal_scrollbar: ScrollBar | None = None self._scrollbar_corner: ScrollBarCorner | None = None + self._border_title: Text | None = None + self._border_subtitle: Text | None = None + self._render_cache = RenderCache(Size(0, 0), []) # Regions which need to be updated (in Widget) self._dirty_regions: set[Region] = set() @@ -321,6 +348,11 @@ class Widget(DOMNode): show_vertical_scrollbar = Reactive(False, layout=True) show_horizontal_scrollbar = Reactive(False, layout=True) + border_title = _BorderTitle() + """A title to show in the top border (if there is one).""" + border_subtitle = _BorderTitle() + """A title to show in the bottom border (if there is one).""" + @property def siblings(self) -> list[Widget]: """Get the widget's siblings (self is removed from the return list). @@ -2429,20 +2461,6 @@ class Widget(DOMNode): """Update the styles of the widget and its children when disabled is toggled.""" self._update_styles() - def validate_border_title(self, title: str) -> str: - """Ensure we only use a single line for the border title.""" - if not title: - return title - first, *_ = title.splitlines() - return first - - def validate_border_subtitle(self, subtitle: str) -> str: - """Ensure we only use a single line for the border subtitle.""" - if not subtitle: - return subtitle - first, *_ = subtitle.splitlines() - return first - def _size_updated( self, size: Size, virtual_size: Size, container_size: Size, layout: bool = True ) -> bool: diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr index 49bcb024b..11b326d4f 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -3113,141 +3113,141 @@ font-weight: 700; } - .terminal-3789115238-matrix { + .terminal-3714773288-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3789115238-title { + .terminal-3714773288-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3789115238-r1 { fill: #e1e1e1 } - .terminal-3789115238-r2 { fill: #c5c8c6 } - .terminal-3789115238-r3 { fill: #fea62b } - .terminal-3789115238-r4 { fill: #fea62b;font-weight: bold } - .terminal-3789115238-r5 { fill: #fea62b;font-weight: bold;font-style: italic; } - .terminal-3789115238-r6 { fill: #cc555a;font-weight: bold } - .terminal-3789115238-r7 { fill: #1e1e1e } - .terminal-3789115238-r8 { fill: #1e1e1e;text-decoration: underline; } - .terminal-3789115238-r9 { fill: #fea62b;text-decoration: underline; } - .terminal-3789115238-r10 { fill: #4b4e55;text-decoration: underline; } - .terminal-3789115238-r11 { fill: #4ebf71 } - .terminal-3789115238-r12 { fill: #b93c5b } + .terminal-3714773288-r1 { fill: #e1e1e1 } + .terminal-3714773288-r2 { fill: #c5c8c6 } + .terminal-3714773288-r3 { fill: #fea62b } + .terminal-3714773288-r4 { fill: #fea62b;font-weight: bold } + .terminal-3714773288-r5 { fill: #fea62b;font-weight: bold;font-style: italic; } + .terminal-3714773288-r6 { fill: #cc555a;font-weight: bold } + .terminal-3714773288-r7 { fill: #1e1e1e } + .terminal-3714773288-r8 { fill: #1e1e1e;text-decoration: underline; } + .terminal-3714773288-r9 { fill: #fea62b;text-decoration: underline; } + .terminal-3714773288-r10 { fill: #4b4e55;text-decoration: underline; } + .terminal-3714773288-r11 { fill: #4ebf71 } + .terminal-3714773288-r12 { fill: #b93c5b } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - BorderSubTitleAlignAll + BorderSubTitleAlignAll - - - - - - Border titleLeft,…▁▁▁▁Left▁▁▁▁ - This is the story ofa Pythondeveloper that - Border subtitleCente…▔▔▔▔@@@▔▔▔▔▔ - - - - - - +--------------+Title────────────────── - |had to fill up|nine labelsand ended up redoing it - +Left--------+───────────────Subtitle - - - - - Title, but really looooo… - Title, but rea…Title, but really … - because the first tryhad some labelsthat were too long. - Subtitle, but …Subtitle, but real… - Subtitle, but really loo… - + + + + + + Border titleLef…▁▁▁▁Left▁▁▁▁ + This is the story ofa Pythondeveloper that + Border subtitleCen…▔▔▔▔@@@▔▔▔▔▔ + + + + + + +--------------+Title───────────────── + |had to fill up|nine labelsand ended up redoing it + +-Left-------+──────────────Subtitle + + + + + Title, but really looo… + Title, but r…Title, but reall… + because the first tryhad some labelsthat were too long. + Subtitle, bu…Subtitle, but re… + Subtitle, but really l… + @@ -3278,134 +3278,134 @@ font-weight: 700; } - .terminal-1944504807-matrix { + .terminal-1044533580-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1944504807-title { + .terminal-1044533580-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1944504807-r1 { fill: #e1e1e1 } - .terminal-1944504807-r2 { fill: #c5c8c6 } - .terminal-1944504807-r3 { fill: #fea62b } - .terminal-1944504807-r4 { fill: #ffffff } - .terminal-1944504807-r5 { fill: #1e1e1e } + .terminal-1044533580-r1 { fill: #e1e1e1 } + .terminal-1044533580-r2 { fill: #c5c8c6 } + .terminal-1044533580-r3 { fill: #fea62b } + .terminal-1044533580-r4 { fill: #ffffff } + .terminal-1044533580-r5 { fill: #1e1e1e } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - BorderSubtitleAlignApp + BorderSubtitleAlignApp - - - - - ──────────────────────────────────────────────────────────────────────────── - - My subtitle is on the left. - - < Left──────────────────────────────────────────────────────────────────── - - ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ - - My subtitle is centered - - ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍Centered!╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - My subtitle is on the right - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Right > - - - - - + + + + + ──────────────────────────────────────────────────────────────────────────── + + My subtitle is on the left. + + < Left─────────────────────────────────────────────────────────────────── + + ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ + + My subtitle is centered + + ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍Centered!╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + My subtitle is on the right + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Right > + + + + + @@ -3436,134 +3436,134 @@ font-weight: 700; } - .terminal-1060422964-matrix { + .terminal-304237721-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1060422964-title { + .terminal-304237721-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1060422964-r1 { fill: #e1e1e1 } - .terminal-1060422964-r2 { fill: #c5c8c6 } - .terminal-1060422964-r3 { fill: #fea62b } - .terminal-1060422964-r4 { fill: #ffffff } - .terminal-1060422964-r5 { fill: #1e1e1e } + .terminal-304237721-r1 { fill: #e1e1e1 } + .terminal-304237721-r2 { fill: #c5c8c6 } + .terminal-304237721-r3 { fill: #fea62b } + .terminal-304237721-r4 { fill: #ffffff } + .terminal-304237721-r5 { fill: #1e1e1e } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - BorderTitleAlignApp + BorderTitleAlignApp - - - - - < Left──────────────────────────────────────────────────────────────────── - - My title is on the left. - - ──────────────────────────────────────────────────────────────────────────── - - ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍Centered!╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ - - My title is centered - - ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Right > - - My title is on the right - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - + + + + + < Left─────────────────────────────────────────────────────────────────── + + My title is on the left. + + ──────────────────────────────────────────────────────────────────────────── + + ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍Centered!╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ + + My title is centered + + ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔Right > + + My title is on the right + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + @@ -19539,134 +19539,134 @@ font-weight: 700; } - .terminal-1364835124-matrix { + .terminal-2452225303-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1364835124-title { + .terminal-2452225303-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1364835124-r1 { fill: #c5c8c6 } - .terminal-1364835124-r2 { fill: #e3e3e3 } - .terminal-1364835124-r3 { fill: #ff0000 } - .terminal-1364835124-r4 { fill: #dde2e8 } - .terminal-1364835124-r5 { fill: #ddedf9 } + .terminal-2452225303-r1 { fill: #c5c8c6 } + .terminal-2452225303-r2 { fill: #e3e3e3 } + .terminal-2452225303-r3 { fill: #ff0000 } + .terminal-2452225303-r4 { fill: #dde2e8 } + .terminal-2452225303-r5 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - ScrollViewTester + ScrollViewTester - - - - ScrollViewTester - 1─────────────────────────────────────────────────────────────────────────── - Welcome to line 980 - Welcome to line 981 - Welcome to line 982 - Welcome to line 983 - Welcome to line 984 - Welcome to line 985 - Welcome to line 986 - Welcome to line 987 - Welcome to line 988 - Welcome to line 989 - Welcome to line 990 - Welcome to line 991 - Welcome to line 992 - Welcome to line 993 - Welcome to line 994 - Welcome to line 995 - Welcome to line 996 - Welcome to line 997 - Welcome to line 998 - Welcome to line 999 - ────────────────────────────────────────────────────────────────────────────── + + + + ScrollViewTester + 1────────────────────────────────────────────────────────────────────────── + Welcome to line 980 + Welcome to line 981 + Welcome to line 982 + Welcome to line 983 + Welcome to line 984 + Welcome to line 985 + Welcome to line 986 + Welcome to line 987 + Welcome to line 988 + Welcome to line 989 + Welcome to line 990 + Welcome to line 991 + Welcome to line 992 + Welcome to line 993 + Welcome to line 994 + Welcome to line 995 + Welcome to line 996 + Welcome to line 997 + Welcome to line 998 + Welcome to line 999 + ────────────────────────────────────────────────────────────────────────────── diff --git a/tests/test_border.py b/tests/test_border.py index 5cae0d0aa..fe02d5e28 100644 --- a/tests/test_border.py +++ b/tests/test_border.py @@ -2,6 +2,7 @@ import pytest from rich.console import Console from rich.segment import Segment from rich.style import Style +from rich.text import Text from textual._border import render_border_label, render_row from textual.widget import Widget @@ -37,6 +38,11 @@ def test_border_title_single_line(): """The border_title gets set to a single line even when multiple lines are provided.""" widget = Widget() + assert widget.border_title is None + + widget.border_title = None + assert widget.border_title == None + widget.border_title = "" assert widget.border_title == "" @@ -50,7 +56,10 @@ def test_border_title_single_line(): assert widget.border_title == "Sorry you " widget.border_title = "[red]This also \n works with markup \n involved.[/]" - assert widget.border_title == "[red]This also " + assert widget.border_title == "[red]This also [/red]" + + widget.border_title = Text.from_markup("[bold]Hello World") + assert widget.border_title == "[bold]Hello World[/bold]" def test_border_subtitle_single_line(): @@ -70,7 +79,10 @@ def test_border_subtitle_single_line(): assert widget.border_subtitle == "Sorry you " widget.border_subtitle = "[red]This also \n works with markup \n involved.[/]" - assert widget.border_subtitle == "[red]This also " + assert widget.border_subtitle == "[red]This also [/red]" + + widget.border_subtitle = Text.from_markup("[bold]Hello World") + assert widget.border_subtitle == "[bold]Hello World[/bold]" @pytest.mark.parametrize( @@ -93,7 +105,7 @@ def test_render_border_label_empty_label_skipped( assert [] == list( render_border_label( - "", + Text(""), True, "round", width, @@ -130,7 +142,7 @@ def test_render_border_label_skipped_if_narrow( assert [] == list( render_border_label( - label, + Text.from_markup(label), True, "round", width, @@ -168,7 +180,7 @@ def test_render_border_label_wide_plain(label: str): True, True, ) - left, original_text, right = render_border_label(label, *args) + left, original_text, right = render_border_label(Text.from_markup(label), *args) assert left == _BLANK_SEGMENT assert right == _BLANK_SEGMENT @@ -188,7 +200,7 @@ def test_render_border_empty_text_with_markup(label: str): """Test label rendering if there is no text but some markup.""" assert [] == list( render_border_label( - label, + Text.from_markup(label), True, "round", 999, @@ -210,7 +222,7 @@ def test_render_border_label(): # Implicit test on the number of segments returned: blank1, what, is_up, with_you, blank2 = render_border_label( - label, + Text.from_markup(label), True, "round", 9999, @@ -239,7 +251,7 @@ def test_render_border_label(): assert with_you == expected_with_you blank1, what, blank2 = render_border_label( - label, + Text.from_markup(label), True, "round", 5 + 4, # 5 where "What…" fits + 2 for the blank spaces + 2 for the corners.