aboutsummaryrefslogtreecommitdiff
path: root/app/tests/test_tui.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/tests/test_tui.py')
-rw-r--r--app/tests/test_tui.py106
1 files changed, 94 insertions, 12 deletions
diff --git a/app/tests/test_tui.py b/app/tests/test_tui.py
index eb6872a..916f434 100644
--- a/app/tests/test_tui.py
+++ b/app/tests/test_tui.py
@@ -267,7 +267,7 @@ class MenuTests(TuiTestCase):
def test_suffix_renders_in_its_theme_color(self):
# default_index=1 keeps the suffixed option unselected, so its
# segments keep their own colors instead of the cursor bar.
- options = [("Build audio.cpp server", "build",
+ options = [("Build audio.cpp Server", "build",
("[recommended]", "warn")), ("other", "other")]
screen = FakeScreen(keys=[10])
tui.menu(screen, "Pick", options, default_index=1)
@@ -276,7 +276,7 @@ class MenuTests(TuiTestCase):
if drawn == text)
self.assertEqual(attr, tui._THEME["warn"])
label_attr = next(a for _, _, drawn, a in screen.strings
- if drawn == "Build audio.cpp server")
+ if drawn == "Build audio.cpp Server")
self.assertEqual(label_attr, tui._THEME["body"])
def test_selected_row_has_arrow_in_the_margin(self):
@@ -317,7 +317,7 @@ class MenuTableTests(TuiTestCase):
def test_name_column_left_aligned_at_margin(self):
screen = FakeScreen(keys=[10])
tui.menu(screen, "Hub", [("Quit", "quit")],
- table_title="Backend status", table_rows=self.ROWS)
+ table_title="Backend Status", table_rows=self.ROWS)
x0, _ = self.dialog_box(screen)
margin = x0 + 1 + tui.Frame.LIST_MARGIN
for name, _, _ in self.ROWS:
@@ -328,7 +328,7 @@ class MenuTableTests(TuiTestCase):
def test_status_column_aligned_at_one_fixed_offset(self):
screen = FakeScreen(keys=[10])
tui.menu(screen, "Hub", [("Quit", "quit")],
- table_title="Backend status", table_rows=self.ROWS)
+ table_title="Backend Status", table_rows=self.ROWS)
x0, _ = self.dialog_box(screen)
margin = x0 + 1 + tui.Frame.LIST_MARGIN
name_w = max(len(name) for name, _, _ in self.ROWS)
@@ -341,7 +341,7 @@ class MenuTableTests(TuiTestCase):
def test_status_text_uses_the_theme_kind_color(self):
screen = FakeScreen(keys=[10])
tui.menu(screen, "Hub", [("Quit", "quit")],
- table_title="Backend status", table_rows=self.ROWS)
+ table_title="Backend Status", table_rows=self.ROWS)
want = {"err": tui._THEME["err"], "warn": tui._THEME["warn"],
"ok": tui._THEME["ok"]}
for _, status, kind in self.ROWS:
@@ -362,7 +362,7 @@ class MenuTableTests(TuiTestCase):
def test_three_element_rows_default_to_body_names(self):
screen = FakeScreen(keys=[10])
tui.menu(screen, "Hub", [("Quit", "quit")],
- table_title="Backend status", table_rows=self.ROWS)
+ table_title="Backend Status", table_rows=self.ROWS)
for name, _, _ in self.ROWS:
attr = next(a for _, _, text, a in screen.strings
if text.rstrip() == name)
@@ -371,24 +371,24 @@ class MenuTableTests(TuiTestCase):
def test_table_title_is_dim_and_left_aligned(self):
screen = FakeScreen(keys=[10])
tui.menu(screen, "Hub", [("Quit", "quit")],
- table_title="Backend status", table_rows=self.ROWS)
+ table_title="Backend Status", table_rows=self.ROWS)
x0, _ = self.dialog_box(screen)
margin = x0 + 1 + tui.Frame.LIST_MARGIN
x, attr = next((x, a) for _, x, text, a in screen.strings
- if text == "Backend status")
+ if text == "Backend Status")
self.assertEqual(x, margin)
self.assertEqual(attr, tui._THEME["dim"])
def test_table_does_not_paint_over_the_border(self):
screen = FakeScreen(keys=[10])
tui.menu(screen, "Hub", [("Quit", "quit")],
- table_title="Backend status", table_rows=self.ROWS)
+ table_title="Backend Status", table_rows=self.ROWS)
self.assert_inside_border(screen)
def test_notice_line_is_red_and_above_the_table(self):
screen = FakeScreen(keys=[10])
tui.menu(screen, "Hub", [("Quit", "quit")],
- table_title="Backend status", table_rows=self.ROWS,
+ table_title="Backend Status", table_rows=self.ROWS,
notice_lines=[("Warning: ffmpeg not installed!", "err")])
x0, _ = self.dialog_box(screen)
margin = x0 + 1 + tui.Frame.LIST_MARGIN
@@ -396,11 +396,11 @@ class MenuTableTests(TuiTestCase):
if text == "Warning: ffmpeg not installed!")
self.assertEqual(x, margin)
self.assertEqual(attr, tui._THEME["err"])
- # The notice sits above the table title ("Backend status").
+ # The notice sits above the table title ("Backend Status").
notice_y = next(y for y, _, text, _ in screen.strings
if text == "Warning: ffmpeg not installed!")
title_y = next(y for y, _, text, _ in screen.strings
- if text == "Backend status")
+ if text == "Backend Status")
self.assertLess(notice_y, title_y)
self.assert_inside_border(screen)
@@ -1283,6 +1283,88 @@ class FlashTests(TuiTestCase):
self.assertIsNone(frame.status)
+class TextViewerTests(TuiTestCase):
+ """tui.text_viewer: a scrollable read-only dialog; Esc/q/Enter closes."""
+
+ LINES = ["first line", "second line", "third line"]
+
+ def test_lines_render_and_enter_closes(self):
+ marker = object()
+ screen = FakeScreen(keys=[10])
+ self.assertIs(
+ tui.text_viewer(screen, "Help", self.LINES, back_value=marker),
+ marker)
+ for line in self.LINES:
+ self.assertTrue(any(text == line for _, _, text, _
+ in screen.strings), line)
+ self.assert_inside_border(screen)
+
+ def test_esc_returns_back_value(self):
+ marker = object()
+ screen = FakeScreen(keys=[27])
+ self.assertIs(
+ tui.text_viewer(screen, "Help", self.LINES, back_value=marker),
+ marker)
+
+ def test_q_returns_back_value_like_esc(self):
+ marker = object()
+ screen = FakeScreen(keys=[ord("q")])
+ self.assertIs(
+ tui.text_viewer(screen, "Help", self.LINES, back_value=marker),
+ marker)
+
+ def test_esc_aborts_without_back_value(self):
+ screen = FakeScreen(keys=[27])
+ with self.assertRaises(tui.WizardCancelled):
+ tui.text_viewer(screen, "Help", self.LINES)
+
+ def test_enter_aborts_without_back_value(self):
+ screen = FakeScreen(keys=[10])
+ with self.assertRaises(tui.WizardCancelled):
+ tui.text_viewer(screen, "Help", self.LINES)
+
+ def test_no_cursor_bar_is_drawn(self):
+ # Read-only: no row is selectable, so even with the cursor on a
+ # line the cyan selection bar never paints.
+ screen = FakeScreen(keys=[FakeCurses.KEY_END, ord("q")])
+ tui.text_viewer(screen, "Help", self.LINES, back_value=object())
+ bars = [s for s in screen.strings
+ if s[3] == tui._THEME["bar"] and not s[2].strip()]
+ self.assertEqual(bars, [])
+
+ def test_end_scrolls_the_last_line_into_view(self):
+ # Content taller than the terminal: End shows the last line and
+ # the frame's scroll indicator appears in the border.
+ lines = [f"line {i}" for i in range(40)]
+ screen = FakeScreen(keys=[FakeCurses.KEY_END, ord("q")])
+ tui.text_viewer(screen, "Help", lines, back_value=object())
+ drawn = [text for _, _, text, _ in screen.strings]
+ self.assertIn("line 39", drawn)
+ self.assertTrue(any("/40" in text for text in drawn))
+
+ def test_home_returns_to_the_top(self):
+ lines = [f"line {i}" for i in range(40)]
+ screen = FakeScreen(keys=[FakeCurses.KEY_END, FakeCurses.KEY_HOME,
+ ord("q")])
+ tui.text_viewer(screen, "Help", lines, back_value=object())
+ drawn = [text for _, _, text, _ in screen.strings]
+ self.assertIn("line 0", drawn)
+
+ def test_page_down_moves_a_full_page(self):
+ # PageDown from the top lands one page (17 visible rows) down:
+ # the first line scrolls off, the next one is at the top.
+ lines = [f"line {i}" for i in range(40)]
+ screen = FakeScreen(keys=[FakeCurses.KEY_NPAGE, ord("q")])
+ tui.text_viewer(screen, "Help", lines, back_value=object())
+ # Only the final frame counts: strings accumulate across redraws.
+ titles = [i for i, entry in enumerate(screen.strings)
+ if entry[2] == " Help "]
+ drawn = [entry[2] for entry in screen.strings[titles[-1]:]]
+ self.assertIn("line 1", drawn)
+ self.assertNotIn("line 0", drawn)
+ self.assertIn(" 2/40 ", drawn)
+
+
class WizardTests(unittest.TestCase):
"""The tui.Wizard screen-stack driver: Esc steps back one screen."""