diff --git a/packages/claude-code-plugin/tests/test_tiny_actor_alignment.py b/packages/claude-code-plugin/tests/test_tiny_actor_alignment.py new file mode 100644 index 00000000..636eeebf --- /dev/null +++ b/packages/claude-code-plugin/tests/test_tiny_actor_alignment.py @@ -0,0 +1,348 @@ +#!/usr/bin/env python3 +"""Alignment regression tests for Tiny Actor Grid (#1273). + +Ensures display-width consistency across Unicode faces, ASCII fallback, +CJK labels, emoji, ANSI color codes, and narrow terminal widths. + +Run with: + python3 -m pytest tests/test_tiny_actor_alignment.py -v +""" + +import os +import sys +from pathlib import Path + +# Ensure hooks/lib is importable +_hooks_lib = str(Path(__file__).resolve().parent.parent / "hooks" / "lib") +if _hooks_lib not in sys.path: + sys.path.insert(0, _hooks_lib) + +from buddy_renderer import ( # noqa: E402 + display_width, + pad_to_display_width, + render_box_line, + render_face_banner, + strip_ansi, + truncate_to_display_width, +) + +# --------------------------------------------------------------------------- +# Mock card data (inline — no external fixtures needed) +# --------------------------------------------------------------------------- + +UNICODE_FACES = [ + {"face": "\u25d5\u203f\u25d5", "label": "Security"}, + {"face": "\u2b21\u203f\u2b21", "label": "Architecture"}, + {"face": "\u2299\u203f\u2299", "label": "Performance"}, + {"face": "\u25c9\u203f\u25c9", "label": "Testing"}, + {"face": "\u00b0\u25c7\u00b0", "label": "Code Quality"}, +] + +ASCII_FACES = [ + {"face": "o_o", "label": "Security"}, + {"face": "o.o", "label": "Architecture"}, + {"face": "^_^", "label": "Performance"}, + {"face": ">_<", "label": "Testing"}, + {"face": "=_=", "label": "Code Quality"}, +] + +CJK_LABELS = [ + {"face": "\u25d5\u203f\u25d5", "label": "\ubcf4\uc548"}, # Korean: 보안 + {"face": "\u2b21\u203f\u2b21", "label": "\uc131\ub2a5"}, # Korean: 성능 + {"face": "\u2299\u203f\u2299", "label": "\uc811\uadfc\uc131"}, # Korean: 접근성 + {"face": "\u25c9\u203f\u25c9", "label": "\u5b89\u5168"}, # Chinese: 安全 + {"face": "\u00b0\u25c7\u00b0", "label": "\u6027\u80fd"}, # Chinese: 性能 +] + +EMOJI_FACES = [ + {"face": "\U0001f916", "label": "Bot"}, + {"face": "\U0001f47b", "label": "Ghost"}, + {"face": "\U0001f525\U0001f916", "label": "Fire Bot"}, + {"face": "\u2728", "label": "Sparkle"}, +] + +ANSI_COLORED_FACES = [ + {"face": "\033[31m\u25d5\u203f\u25d5\033[0m", "label": "Red"}, + {"face": "\033[32m\u2b21\u203f\u2b21\033[0m", "label": "Green"}, + {"face": "\033[1;34m\u2299\u203f\u2299\033[0m", "label": "Bold Blue"}, + {"face": "\033[38;5;208m^_^\033[0m", "label": "Orange"}, +] + + +def _make_card_line(face: str, label: str, target_width: int) -> str: + """Simulate a grid cell: '|