"""Tests for `agent.markdown_tables.realign_markdown_tables`. These cover the alignment guarantee on CJK / wide-character tables and the conservative no-op behaviour on non-table input. """ from __future__ import annotations from textwrap import dedent from wcwidth import wcswidth from agent.markdown_tables import ( is_table_divider, looks_like_table_row, realign_markdown_tables, split_table_row, ) def _column_offsets(line: str) -> list[int]: """Return the display-cell index of every ``|`` in ``line``.""" cells: list[int] = [] width = 0 for ch in line: if ch == "|": cells.append(width) # wcswidth on a single char; clamp negatives. w = wcswidth(ch) width += w if w > 0 else 1 return cells # --------------------------------------------------------------------------- # split_table_row / is_table_divider / looks_like_table_row # --------------------------------------------------------------------------- def test_split_strips_outer_pipes_and_trims(): assert split_table_row("| a | b | c |") == ["a", "b", "c"] assert split_table_row("|配置|状态|") == ["配置", "状态"] assert split_table_row("a | b | c") == ["a", "b", "c"] def test_looks_like_table_row(): assert looks_like_table_row("| a | b |") assert looks_like_table_row("a | b | c") # no leading pipe, ≥2 pipes assert not looks_like_table_row("not a table") assert not looks_like_table_row("a | b") # one pipe, no leading pipe assert not looks_like_table_row("") # --------------------------------------------------------------------------- # realign_markdown_tables # --------------------------------------------------------------------------- # --------------------------------------------------------------------------- # Vertical fallback for tables wider than the terminal # --------------------------------------------------------------------------- def test_horizontal_kept_when_table_fits(): """A table that fits the terminal must keep the horizontal pipe-bordered rendering — vertical fallback only kicks in when soft-wrap is unavoidable.""" src = dedent( """\ | Name | Age | |------|-----| | Alice | 30 | | Bob | 25 | """ ) out = realign_markdown_tables(src, available_width=100) # Pipe-bordered rendering survives. body_rows = [ln for ln in out.split("\n") if ln.strip().startswith("|")] assert len(body_rows) == 4 offsets = [_column_offsets(r) for r in body_rows] assert all(o == offsets[0] for o in offsets) def test_vertical_fallback_wraps_long_cell_text_with_indent(): src = dedent( """\ | Key | Value | |-----|-------| | x | this value is long enough that wrapping the value to fit a narrow terminal width is required even in vertical mode | """ ) out = realign_markdown_tables(src, available_width=60) lines = out.split("\n") assert lines[0].startswith("Key: x") # First "Value:" line + at least one continuation indented by 2 spaces. value_idx = next(i for i, l in enumerate(lines) if l.startswith("Value:")) assert lines[value_idx + 1].startswith(" ") # Every line still fits the budget. for line in lines: assert wcswidth(line) <= 60 def test_multiple_tables_in_one_text(): src = dedent( """\ First: | 配置 | 值 | |------|----| | 通义 | 1 | Second: | model | n | |-------|---| | gpt | 2 | """ ) out = realign_markdown_tables(src) # Each table block individually aligns. blocks: list[list[str]] = [] current: list[str] = [] for line in out.split("\n"): if "|" in line: current.append(line) elif current: blocks.append(current) current = [] if current: blocks.append(current) assert len(blocks) == 2 for block in blocks: offsets = [_column_offsets(row) for row in block] assert all(o == offsets[0] for o in offsets), ( "block did not align:\n" + "\n".join(block) )