Files
shellmate/tests/test_ui_render.py
2026-01-27 20:49:46 +00:00

167 lines
5.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Tests for UI rendering - catches Rich markup errors before deployment."""
import pytest
from io import StringIO
from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.text import Text
from rich.align import Align
from rich.box import ROUNDED
def test_menu_render_no_markup_errors():
"""Test that the main menu renders without Rich markup errors."""
# Simulate the menu rendering code
output = StringIO()
console = Console(file=output, width=80, height=24, force_terminal=True, color_system="truecolor")
username = "testuser"
width = 80
height = 24
pieces = "♔ ♕ ♖ ♗ ♘ ♙"
# Title section
console.print(Align.center(Text(pieces, style="dim white")))
console.print()
console.print(Align.center(Text("S H E L L M A T E", style="bold bright_green")))
console.print(Align.center(Text("" * 20, style="green")))
console.print(Align.center(Text("SSH into Chess Mastery", style="italic bright_black")))
console.print(Align.center(Text(pieces[::-1], style="dim white")))
console.print()
# Menu table - this is where markup errors often occur
menu_table = Table(show_header=False, box=None, padding=(0, 2))
menu_table.add_column(justify="center")
menu_table.add_row(Text(f"Welcome, {username}!", style="cyan"))
menu_table.add_row("")
menu_table.add_row("[bright_white on blue] 1 [/bright_white on blue] Play vs AI [dim]♔ vs ♚[/dim]")
menu_table.add_row("[bright_white on magenta] 2 [/bright_white on magenta] Play vs Human [dim]♔ vs ♔[/dim]")
menu_table.add_row("[bright_white on green] 3 [/bright_white on green] Learn & Practice [dim]📖[/dim]")
menu_table.add_row("[bright_white on red] q [/bright_white on red] Quit [dim]👋[/dim]")
menu_table.add_row("")
menu_table.add_row(Text("Press a key to select...", style="dim italic"))
panel_width = min(45, width - 4)
panel = Panel(
Align.center(menu_table),
box=ROUNDED,
border_style="bright_blue",
width=panel_width,
padding=(1, 2),
)
console.print(Align.center(panel))
# Footer
console.print()
console.print(Align.center(Text(f"Terminal: {width}×{height}", style="dim")))
# If we got here without exception, markup is valid
rendered = output.getvalue()
# Check key content is present (content may have ANSI codes)
assert "S H E L L M A T E" in rendered or "SHELLMATE" in rendered
assert "Welcome" in rendered
assert "Play vs AI" in rendered
def test_game_status_render():
"""Test that game status panel renders correctly."""
output = StringIO()
console = Console(file=output, width=80, height=24, force_terminal=True)
status_lines = []
status_lines.append("[bold white]White ♔ to move[/bold white]")
status_lines.append("[dim]Moves: e2e4 e7e5 g1f3[/dim]")
status_lines.append("")
status_lines.append("[dim]Enter move (e.g. e2e4) │ [q]uit │ [r]esign[/dim]")
panel = Panel(
"\n".join(status_lines),
box=ROUNDED,
border_style="blue",
width=50,
title="[bold]Game Status[/bold]"
)
console.print(panel)
rendered = output.getvalue()
assert "White" in rendered
assert "Game Status" in rendered
def test_chess_board_render():
"""Test that chess board renders without errors."""
output = StringIO()
PIECES = {
'K': '', 'Q': '', 'R': '', 'B': '', 'N': '', 'P': '',
'k': '', 'q': '', 'r': '', 'b': '', 'n': '', 'p': '',
}
# Simplified board rendering (plain text)
lines = []
lines.append(" a b c d e f g h")
lines.append(" +---+---+---+---+---+---+---+---+")
# Render rank 8 with pieces
pieces_row = ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r']
row = " 8 |"
for file, piece_char in enumerate(pieces_row):
char = PIECES.get(piece_char, '?')
row += f" {char} |"
row += " 8"
lines.append(row)
lines.append(" +---+---+---+---+---+---+---+---+")
for line in lines:
output.write(line + "\n")
rendered = output.getvalue()
assert "a b c" in rendered
assert "" in rendered # Black rook
assert "+---+" in rendered
def test_narrow_terminal_render():
"""Test that menu renders correctly on narrow terminals."""
output = StringIO()
console = Console(file=output, width=40, height=20, force_terminal=True)
# Small terminal fallback
console.print(Align.center(Text("♟ SHELLMATE ♟", style="bold green")))
console.print()
menu_table = Table(show_header=False, box=None)
menu_table.add_column(justify="center")
menu_table.add_row(Text("Welcome!", style="cyan"))
menu_table.add_row("[dim]1. Play[/dim]")
menu_table.add_row("[dim]q. Quit[/dim]")
console.print(Align.center(menu_table))
rendered = output.getvalue()
assert "SHELLMATE" in rendered
def test_markup_escape_special_chars():
"""Test that usernames with special chars don't break markup."""
output = StringIO()
console = Console(file=output, width=80, height=24, force_terminal=True)
# Usernames that could break markup
test_usernames = [
"normal_user",
"user[with]brackets",
"user<with>angles",
"[admin]",
"test/path",
]
for username in test_usernames:
# Using Text() object safely escapes special characters
console.print(Text(f"Welcome, {username}!", style="cyan"))
rendered = output.getvalue()
assert "normal_user" in rendered
# Text() should have escaped the brackets safely