Files
sbp/tests/test_frame.py
T

116 lines
3.1 KiB
Python

import unittest
from unittest import mock
from sbp.tui import frame
from sbp.tui.term import Term
class FakeScreen:
def __init__(self, height: int = 24, width: int = 80) -> None:
self.height = height
self.width = width
self.writes: list[tuple[int, int, str]] = []
def getmaxyx(self):
return self.height, self.width
def addstr(self, y, x, text, attr=0):
if y >= self.height or x + len(text) > self.width:
raise AssertionError(f"write out of bounds: y={y} x={x} len={len(text)}")
self.writes.append((y, x, text))
def erase(self):
self.writes.clear()
def refresh(self):
pass
def keypad(self, flag):
pass
def getch(self):
return -1
def text(self) -> str:
return "\n".join(text for _, _, text in self.writes)
def make_term(screen: FakeScreen) -> Term:
with mock.patch.object(frame_term_curses(), "has_colors", return_value=False), \
mock.patch.object(frame_term_curses(), "curs_set", return_value=None):
return Term(screen)
def frame_term_curses():
import sbp.tui.term as module
return module.curses
class WindowOffsetTest(unittest.TestCase):
def test_no_scroll_when_everything_fits(self) -> None:
self.assertEqual(frame.window_offset(3, 5, 10), 0)
def test_keeps_selection_visible(self) -> None:
self.assertEqual(frame.window_offset(7, 20, 5), 3)
def test_clamps_to_last_page(self) -> None:
self.assertEqual(frame.window_offset(19, 20, 5), 15)
class SidebarWidthTest(unittest.TestCase):
def test_minimum(self) -> None:
self.assertEqual(frame.sidebar_width(["A"]), frame.SIDEBAR_MIN)
def test_grows_with_titles(self) -> None:
self.assertGreater(
frame.sidebar_width(["VeryLongSectionName"]), frame.sidebar_width(["A"])
)
def test_capped(self) -> None:
self.assertEqual(frame.sidebar_width(["x" * 100]), frame.SIDEBAR_MAX)
class DrawTest(unittest.TestCase):
def setUp(self) -> None:
self.screen = FakeScreen()
self.term = make_term(self.screen)
def draw(self, rows=None, index=0, width=80):
rows = rows or [frame.Row("first", action=lambda app: None), frame.Row("second")]
frame.draw(
self.term,
title="sbp 2.0.0",
subtitle="host active",
sidebar=["Dashboard", "Protocols", "Users", "Settings", "Logs"],
sidebar_index=1,
sidebar_focused=False,
content_title="Protocols",
rows=rows,
index=index,
content_focused=True,
footer="keys",
)
def test_draws_both_panes(self) -> None:
self.draw()
text = self.screen.text()
for word in ("Dashboard", "Protocols", "Users", "Settings", "Logs", "first", "second", "keys"):
self.assertIn(word, text)
def test_selected_row_is_padded_for_highlight(self) -> None:
self.draw(index=1)
row = [text for y, _, text in self.screen.writes if text.startswith("second")]
self.assertTrue(row)
self.assertGreater(len(row[0]), len("second"))
def test_small_terminal_shows_hint(self) -> None:
self.screen = FakeScreen(height=8, width=40)
self.term.screen = self.screen
self.draw()
self.assertIn("terminal too small", self.screen.text())
if __name__ == "__main__":
unittest.main()