aboutsummaryrefslogtreecommitdiff
path: root/app/tests/test_tui.py
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-08-30 04:29:13 -0400
committerhistoria <historiavg@proton.me>2026-08-30 04:29:13 -0400
commitd31e9149c7f141b2d3c14a79e9f067d524c8c420 (patch)
tree89b2232facac9cbe06cb17e279e664e9a3a37284 /app/tests/test_tui.py
parentdf4a81c6101d33fe745b6ac249c736e088760c85 (diff)
downloadtts-audiobook-generator-d31e9149c7f141b2d3c14a79e9f067d524c8c420.tar.gz
fix: menu highlight numbering in tui
Diffstat (limited to 'app/tests/test_tui.py')
-rw-r--r--app/tests/test_tui.py79
1 files changed, 79 insertions, 0 deletions
diff --git a/app/tests/test_tui.py b/app/tests/test_tui.py
index 72465c1..085a1f1 100644
--- a/app/tests/test_tui.py
+++ b/app/tests/test_tui.py
@@ -306,6 +306,21 @@ class MenuTests(TuiTestCase):
if text == "second option")
self.assertEqual(arrows, [y_first, y_second])
+ def test_corner_indicator_counts_highlighted_options(self):
+ # The corner " n/n " names the highlighted option, not the
+ # first visible line: with the list still scrolled to the top,
+ # two Downs must read 2/20 then 3/20 (the old label stayed at
+ # 1/<total lines> until entries scrolled off-screen).
+ options = [(f"option {i}", i) for i in range(20)]
+ screen = FakeScreen(keys=[FakeCurses.KEY_DOWN, FakeCurses.KEY_DOWN,
+ 10])
+ value = tui.menu(screen, "Pick one", options,
+ help_lines=["Help text"])
+ self.assertEqual(value, 2)
+ labels = [text for _, _, text, _ in screen.strings
+ if text in (" 1/20 ", " 2/20 ", " 3/20 ")]
+ self.assertEqual(labels, [" 1/20 ", " 2/20 ", " 3/20 "])
+
class MenuTableTests(TuiTestCase):
"""The optional status table: aligned columns and colored statuses."""
@@ -1103,6 +1118,20 @@ class BrowseDirectoryTests(TuiTestCase):
self.assertEqual(chosen, (self.root / "alpha").resolve())
self.assert_inside_border(screen)
+ def test_corner_indicator_counts_use_and_parent_rows(self):
+ # "[ Use this directory ]" and ".." are selectable rows like
+ # any other: with the 23 subdirectories (3 from setUp + 20),
+ # moving onto the first one ("alpha/") reads 3/25 in the corner.
+ for i in range(20):
+ (self.root / f"dir{i:02d}").mkdir()
+ screen = FakeScreen(keys=[FakeCurses.KEY_DOWN, FakeCurses.KEY_DOWN,
+ 27])
+ with self.assertRaises(tui.WizardCancelled):
+ tui.browse_directory(screen, "Pick", start=self.root)
+ labels = [text for _, _, text, _ in screen.strings
+ if text in (" 1/25 ", " 2/25 ", " 3/25 ")]
+ self.assertEqual(labels, [" 1/25 ", " 2/25 ", " 3/25 "])
+
def test_esc_returns_back_value(self):
marker = object()
screen = FakeScreen(keys=[27])
@@ -1407,6 +1436,56 @@ class FrameStatusTests(TuiTestCase):
self.assertEqual(footer_y, status_y + 1)
+class FrameIndicatorTests(TuiTestCase):
+ """The corner overflow label's default reading.
+
+ With a cursor the " n/n " counts selectable rows (which entry is
+ highlighted); without one it keeps the first-visible-line reading.
+ The Help screen's viewer overrides the label entirely, so nothing
+ here touches its " lines x-y of z " counter.
+ """
+
+ def _frame(self):
+ frame = tui.Frame(self.screen, "Title", "footer")
+ for i in range(30):
+ frame.mark(f"row {i}", selectable=True, align="left")
+ return frame
+
+ def test_label_counts_selectable_rows_with_a_cursor(self):
+ # 30 rows with 17 visible: the cursor on the third row reads
+ # 3/30 wherever the viewport sits.
+ frame = self._frame()
+ frame.cursor = 2
+ frame.draw()
+ self.assertIn(" 3/30 ",
+ [t for _, _, t, _ in self.screen.strings])
+
+ def test_label_falls_back_to_visible_lines_without_a_cursor(self):
+ # Frames without a cursor (e.g. focus on a form's buttons)
+ # keep the old first-visible-line reading.
+ frame = self._frame()
+ frame.draw()
+ self.assertIn(" 1/30 ",
+ [t for _, _, t, _ in self.screen.strings])
+ frame.scroll = 10
+ frame.draw()
+ self.assertIn(" 11/30 ",
+ [t for _, _, t, _ in self.screen.strings])
+
+ def test_non_selectable_rows_are_not_numbered(self):
+ # Help/note rows do not shift the count: two unselectable rows
+ # above 20 selectable ones put the third entry at 3/20.
+ frame = tui.Frame(self.screen, "Title", "footer")
+ frame.mark("note one")
+ frame.mark("note two")
+ for i in range(20):
+ frame.mark(f"row {i}", selectable=True, align="left")
+ frame.cursor = 4 # the third selectable row
+ frame.draw()
+ self.assertIn(" 3/20 ",
+ [t for _, _, t, _ in self.screen.strings])
+
+
class TextViewerTests(TuiTestCase):
"""tui.text_viewer: a scrollable read-only dialog; Esc/q/Enter closes."""