项目文件夹

文件
2026-07-13 13:12:33 +08:00

225 行
7.7 KiB
Python

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
from __future__ import annotations
import re
from tui_real_terminal.driver import TerminalFrame
_ANSI_RE = re.compile(
r"\x1b(?:"
r"\[[0-?]*[ -/]*[@-~]"
r"|\][^\x07\x1b]*(?:\x07|\x1b\\)"
r"|P[^\x1b]*\x1b\\"
r"|[@-Z\\-_]"
r")"
)
_PROMPT_PLACEHOLDERS = ("send a message", "send a massage")
_COMPLETION_TITLES = ("commands", "files")
_COMPLETION_BACKGROUND_MARKERS = (
"OPEN_SQUILLA_TUI_READY",
"fake-response:",
"stream-token-",
"intermediate-before-tool",
"second-intermediate-line",
"complex-state-complete",
"terminal-change-response",
"architecture-analysis-complete",
"fake_tool",
"approval requested",
"Traceback (most recent call last)",
)
def assert_visible_text(frame: TerminalFrame, expected: str) -> None:
if expected not in frame.text:
raise AssertionError(
f"{frame.checkpoint}: expected visible text {expected!r}; screen was:\n"
f"{frame.text}"
)
def assert_prompt_ready(frame: TerminalFrame) -> None:
if "you" not in frame.text and not any(
placeholder in frame.text for placeholder in _PROMPT_PLACEHOLDERS
):
raise AssertionError(f"{frame.checkpoint}: prompt is not visibly ready:\n{frame.text}")
def assert_no_inline_prompt_chrome_collision(frame: TerminalFrame) -> None:
for line in frame.text.splitlines():
if re.match(r"^\s*│\s+s(?:[#|*⠋✓✗]|[\u4e00-\u9fff])", line):
raise AssertionError(
f"{frame.checkpoint}: inline prompt chrome overlapped output:\n{frame.text}"
)
resize_checkpoint = "narrow" in frame.checkpoint or "wide" in frame.checkpoint
if (
sum(line.count(placeholder) for placeholder in _PROMPT_PLACEHOLDERS) > 1
and not resize_checkpoint
):
raise AssertionError(
f"{frame.checkpoint}: inline prompt chrome was duplicated:\n{frame.text}"
)
def assert_no_completion_menu_overlap(frame: TerminalFrame) -> None:
"""Reject completion-menu rectangles whose border area is polluted.
The OpenTUI completion menu is a rounded rectangle with a ``commands`` or
``files`` title; clean top/bottom border spans contain only border fill and
that title, and the rectangle body must not contain known conversation text.
"""
text = _ANSI_RE.sub("", frame.text)
lines = _screen_lines(frame, text)
for top_index, left, right in _completion_top_spans(lines):
top_segment = _line_span(lines[top_index], left, right)
if not _is_completion_border_segment(top_segment, top=True):
_raise_completion_assertion(
frame,
"completion menu overlap: dirty top border",
)
bottom = _find_completion_bottom(lines, top_index, left, right)
if bottom is None:
_raise_completion_assertion(
frame,
"completion menu overlap: incomplete menu border",
)
bottom_index, body_right = bottom
bottom_segment = _line_span(lines[bottom_index], left, body_right)
if not _is_completion_border_segment(bottom_segment, top=False):
_raise_completion_assertion(
frame,
"completion menu overlap: dirty bottom border",
)
for body_index in range(top_index + 1, bottom_index):
line = lines[body_index]
segment = _line_span(line, left, body_right)
if any(marker in segment for marker in _COMPLETION_BACKGROUND_MARKERS):
_raise_completion_assertion(
frame,
"completion menu overlap: conversation text inside menu",
)
if (
not _has_completion_vertical_edges(line, left, body_right)
and segment.strip()
):
_raise_completion_assertion(
frame,
"completion menu overlap: broken vertical border",
)
def assert_no_stale_completion_menu(frame: TerminalFrame) -> None:
"""Reject completion-menu remnants after a close or clear operation.
A cleared frame should not contain a ``commands``/``files`` rounded title
border, nor a selected completion row left behind with rounded menu chrome.
"""
text = _ANSI_RE.sub("", frame.text)
lines = _screen_lines(frame, text)
if list(_completion_top_spans(lines)):
raise AssertionError(f"{frame.checkpoint}: stale completion menu:\n{frame.text}")
has_rounded_chrome = any(char in text for char in "╭╮╰╯")
for line in lines:
if has_rounded_chrome and " " in line and "│" in line:
raise AssertionError(f"{frame.checkpoint}: stale completion menu:\n{frame.text}")
def assert_no_traceback(frame: TerminalFrame) -> None:
forbidden = (
"Traceback (most recent call last)",
"RuntimeError:",
"Unhandled exception",
)
for marker in forbidden:
if marker in frame.text:
raise AssertionError(f"{frame.checkpoint}: unexpected error marker {marker!r}")
def assert_no_raw_ansi_leakage(frame: TerminalFrame) -> None:
match = _ANSI_RE.search(frame.text)
if match:
raise AssertionError(
f"{frame.checkpoint}: raw terminal escape leaked at offset {match.start()}"
)
def _completion_top_spans(lines: list[str]) -> list[tuple[int, int, int]]:
spans: list[tuple[int, int, int]] = []
for index, line in enumerate(lines):
search_at = 0
while True:
left = line.find("╭", search_at)
if left < 0:
break
right = line.find("╮", left + 1)
if right < 0:
break
segment = line[left : right + 1]
if _has_completion_title(segment):
spans.append((index, left, right))
search_at = right + 1
return spans
def _screen_lines(frame: TerminalFrame, text: str) -> list[str]:
lines: list[str] = []
cols = frame.size.cols
for line in text.splitlines():
if cols > 0 and len(line) > cols:
lines.extend(
line[index : index + cols] for index in range(0, len(line), cols)
)
else:
lines.append(line)
return lines
def _find_completion_bottom(
lines: list[str],
top_index: int,
left: int,
right: int,
) -> tuple[int, int] | None:
for index in range(top_index + 1, len(lines)):
line = lines[index]
if len(line) <= right:
continue
bottom_right = line.find("╯", left + 1)
if line[left] == "╰" and bottom_right >= right:
return index, bottom_right
return None
def _line_span(line: str, left: int, right: int) -> str:
if len(line) <= left:
return ""
return line[left : min(len(line), right + 1)]
def _has_completion_title(segment: str) -> bool:
return any(f" {title} " in segment for title in _COMPLETION_TITLES)
def _is_completion_border_segment(segment: str, *, top: bool) -> bool:
if len(segment) < 2:
return False
expected_left, expected_right = ("╭", "╮") if top else ("╰", "╯")
if segment[0] != expected_left or segment[-1] != expected_right:
return False
inner = segment[1:-1]
for title in _COMPLETION_TITLES:
inner = inner.replace(title, "")
return all(char in {" ", "─"} for char in inner)
def _has_completion_vertical_edges(line: str, left: int, right: int) -> bool:
return len(line) > right and line[left] == "│" and line[right] == "│"
def _raise_completion_assertion(frame: TerminalFrame, reason: str) -> None:
raise AssertionError(f"{frame.checkpoint}: {reason}:\n{frame.text}")