"""Single-point-of-assignment guard for the TUI syntax-highlighting scheme.
All code rendered in the Navi Code TUI — markdown fenced blocks, code
artifacts, and the filesystem ``read`` tool output — must resolve its
Pygments style from one place: ``Theme.code_theme``. These tests pin that
contract so a future renderer cannot silently re-introduce a hard-coded
``dracula``/``github-light`` copy.
"""
from __future__ import annotations
from pygments.styles import get_style_by_name
from rich.syntax import Syntax
from clients.terminal.tui.renderers.filesystem import FilesystemToolResultRenderer
from clients.terminal.tui.renderers.markdown_content import _theme_aware_code_theme
from clients.terminal.tui.renderers.syntax import highlight_code
from clients.terminal.tui.themes import (
GNEXUS_DARK,
GNEXUS_LIGHT,
ThemeRegistry,
get_active_theme,
set_active_theme,
)
def _pygments_style_name(syntax: Syntax) -> str:
"""The Pygments style class name backing a rich Syntax renderable."""
return syntax._theme._pygments_style_class.__name__ # type: ignore[attr-defined]
def test_theme_code_theme_is_a_real_pygments_style() -> None:
for theme in (GNEXUS_DARK, GNEXUS_LIGHT):
# The configured name resolves to a real Pygments style (no raise),
# and dark/light pick distinct schemes.
get_style_by_name(theme.code_theme)
assert GNEXUS_DARK.code_theme != GNEXUS_LIGHT.code_theme
def test_markdown_code_theme_resolver_reads_from_theme() -> None:
for name in ("gnexus-dark", "gnexus-light"):
assert _theme_aware_code_theme(name) == ThemeRegistry.get(name).code_theme
def test_highlight_code_uses_theme_code_theme() -> None:
set_active_theme("gnexus-dark")
theme = get_active_theme()
syntax = highlight_code("x = 1\n", "python", theme=theme, line_numbers=True)
assert _pygments_style_name(syntax) == get_style_by_name(theme.code_theme).__name__
def test_filesystem_read_uses_theme_code_theme() -> None:
set_active_theme("gnexus-dark")
theme = get_active_theme()
panel = FilesystemToolResultRenderer().render(
{
"type": "tool_call",
"tool": "filesystem",
"args": {"action": "read", "path": "a.py"},
"result": "[a.py | 1 lines | 7B]\n1: x = 1\n",
"success": True,
}
)
group = panel.renderable
syntax = next(r for r in group.renderables if isinstance(r, Syntax))
assert _pygments_style_name(syntax) == get_style_by_name(theme.code_theme).__name__
def test_light_theme_uses_light_code_scheme() -> None:
set_active_theme("gnexus-light")
theme = get_active_theme()
dark = highlight_code("x = 1\n", "python", theme=GNEXUS_DARK, line_numbers=True)
light = highlight_code("x = 1\n", "python", theme=theme, line_numbers=True)
# Same code, different theme field -> different Pygments style class.
assert _pygments_style_name(dark) != _pygments_style_name(light)
assert _pygments_style_name(light) == get_style_by_name(GNEXUS_LIGHT.code_theme).__name__
set_active_theme("gnexus-dark")