From 9caa43f8d28f0fc644c0e81c9c205689d1b8c332 Mon Sep 17 00:00:00 2001 From: JeremyDev87 Date: Sat, 4 Apr 2026 11:08:44 +0900 Subject: [PATCH] test(plugin): add alignment regression coverage for Tiny Actor Grid (#1273) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add 23 regression tests verifying display-width consistency across: - Unicode faces (◕‿◕, ⬡‿⬡, ⊙‿⊙) - ASCII fallback mode (o_o, ^_^) - CJK labels (Korean 보안/성능, Chinese 安全/性能) - Emoji faces (🤖, 👻, 🔥) - ANSI color codes (zero-width verification) - Narrow terminal widths (40/80 columns) - Mixed content grid rows Closes #1273 --- .../tests/test_tiny_actor_alignment.py | 348 ++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 packages/claude-code-plugin/tests/test_tiny_actor_alignment.py 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: '|