Private
Public Access
0
0
Files
manual_slop/tests/test_markdown_table_wrapped.py
T
Conductor feed18eb0f fix(markdown): remove table double-header + add imgui_md bullet workaround
Table fix (src/markdown_table.py):
- Add TableColumnFlags_.width_stretch to each table_setup_column call
  (was missing — columns had no width to wrap against, so text_wrapped
  couldn't grow row height → all rows squished together)
- Remove the explicit for-h-in-headers: table_next_column + text_wrapped(h)
  loop. table_headers_row() already renders the header from the
  table_setup_column() names; the explicit loop was drawing it AGAIN on
  top → double-rendered header rows.

Bullet fix (src/markdown_helper.py):
- Revert _render_md_no_bullet_overlap → simple imgui_md.render(chunk);
  imgui.spacing() (the original af0bbe97 approach). The complex
  workaround was stripping '- ' and rendering stripped text to imgui_md,
  which double-rendered '- 1. ...' content (imgui.bullet from my code +
  numbered list marker from imgui_md).
- Add MarkdownRenderer._normalize_bullet_delimiters: regex-converts
  '* ' markers to '- ' before passing to imgui_md. This works around
  the upstream bug in mekhontsev/imgui_md BLOCK_LI where the '*' case
  calls ImGui::Bullet() without ImGui::SameLine(), causing the bullet
  to render on its own Y with the text on the next Y. The '-' case
  uses Text+SameLine which is correct. Cannot fix from Python (we
  can't subclass the C++ class) — pre-conversion is the cheapest fix.

Tests:
- test_markdown_table_wrapped.py: updated to assert new behavior
  (text_wrapped count == cell count, not header+cell).
- test_markdown_table_columns.py: updated to assert exactly 6
  table_next_column calls (cells only, not 9).
- test_markdown_helper_bullets.py: rewrote for new public-API behavior
  (imgui_md.render called with the unstripped chunk).

16/16 markdown unit tests pass.
2026-06-03 21:14:16 -04:00

58 lines
2.7 KiB
Python

from unittest.mock import patch, MagicMock
from src.markdown_table import render_table, TableBlock
def _setup_mocks(mock_imgui):
mock_imgui.TableFlags_ = type("T", (), {"borders": 1, "row_bg": 2, "resizable": 4})()
mock_imgui.TableColumnFlags_ = type("C", (), {"width_stretch": 8, "width_fixed": 16})()
mock_imgui.begin_table.return_value = True
mock_imgui.table_next_column = MagicMock()
mock_imgui.table_next_row = MagicMock()
mock_imgui.table_headers_row = MagicMock()
mock_imgui.text_wrapped = MagicMock()
mock_imgui.text = MagicMock()
mock_imgui.end_table = MagicMock()
def test_render_table_uses_text_wrapped_for_cells():
block = TableBlock(headers=["A"], rows=[["hello"]], span=(0, 2))
with patch("src.markdown_table.imgui") as mock_imgui:
_setup_mocks(mock_imgui)
render_table(block)
mock_imgui.text_wrapped.assert_any_call("hello")
def test_render_table_uses_table_headers_row_for_headers():
block = TableBlock(headers=["A"], rows=[["hello"]], span=(0, 2))
with patch("src.markdown_table.imgui") as mock_imgui:
_setup_mocks(mock_imgui)
render_table(block)
assert mock_imgui.table_headers_row.called, "table_headers_row must be called exactly once to render the header row"
assert mock_imgui.table_headers_row.call_count == 1, f"table_headers_row must be called exactly once (not {mock_imgui.table_headers_row.call_count} — would cause double-header bug)"
def test_render_table_does_not_use_text_for_cells():
block = TableBlock(headers=["A"], rows=[["hello"]], span=(0, 2))
with patch("src.markdown_table.imgui") as mock_imgui:
_setup_mocks(mock_imgui)
render_table(block)
assert not mock_imgui.text.called, "imgui.text should not be called for table cells"
def test_render_table_uses_width_stretch_for_columns():
block = TableBlock(headers=["A", "B"], rows=[["1", "2"]], span=(0, 3))
with patch("src.markdown_table.imgui") as mock_imgui:
_setup_mocks(mock_imgui)
render_table(block)
assert mock_imgui.table_setup_column.call_count == 2
for call in mock_imgui.table_setup_column.call_args_list:
args, _ = call
assert imgui_flags_passed(args), f"table_setup_column must include width_stretch flag, got args={args}"
def imgui_flags_passed(args) -> bool:
if len(args) < 2: return False
return bool(args[1] & 8)
def test_render_table_text_wrapped_count_matches_cell_count():
block = TableBlock(headers=["A", "B"], rows=[["1", "2"], ["3", "4"], ["5", "6"]], span=(0, 5))
with patch("src.markdown_table.imgui") as mock_imgui:
_setup_mocks(mock_imgui)
render_table(block)
cell_count = 6
assert mock_imgui.text_wrapped.call_count == cell_count, f"text_wrapped must be called exactly {cell_count} times (cells only, not headers), got {mock_imgui.text_wrapped.call_count}"