Private
Public Access
0
0
Files
manual_slop/tests/test_comms_scroll_no_clipping.py
T
ed 96b9b00c97 fix(gui): use imscope.child for comms_scroll (was inside conditional, leaving child open)
ROOT CAUSE: render_comms_history_panel had imgui.end_child() nested INSIDE
an 'if app._scroll_comms_to_bottom:' block at line 3758. When
_scroll_comms_to_bottom was False (the common case), end_child was
NOT called, leaving the comms_scroll child window open. This caused
the imGui state to corrupt: tab_item.end_tab_item, tab_bar.end_tab_bar,
and the outer window.end all saw that the child was still open
(WithinEndChildID was set), triggering 'Must call EndChild() and not
End()!' assertion.

FIX: Convert the entire comms_scroll block to imscope.child (which uses
Python's with statement for exception-safe end_child). The scroll-to-bottom
logic is now correctly nested INSIDE the with block, and there's no
manual end_child to forget.

Tests:
- Updated test_comms_scroll_no_clipping.py to check imscope.child
  instead of begin_child
- 28/28 broad regression pass
2026-06-03 14:53:05 -04:00

51 lines
2.4 KiB
Python

from unittest.mock import patch, MagicMock
from src.gui_2 import render_comms_history_panel
def test_comms_history_renders_all_entries_not_just_early_subset(app_instance):
entries = [{"direction": "in", "kind": "response", "provider": "x", "model": "y", "ts": f"00:00:0{i}", "payload": {"text": f"Entry {i} content"}} for i in range(50)]
app_instance._comms_log_cache = entries
app_instance.is_viewing_prior_session = False
app_instance.perf_profiling_enabled = False
app_instance._scroll_comms_to_bottom = False
with patch("src.gui_2.imgui") as mock_imgui, patch("src.gui_2.imscope") as mock_imscope:
mock_imgui.text_colored = MagicMock()
mock_imgui.text = MagicMock()
mock_imgui.same_line = MagicMock()
mock_imgui.separator = MagicMock()
mock_imgui.begin_child = MagicMock(return_value=True)
mock_imgui.end_child = MagicMock()
mock_imgui.button = MagicMock(return_value=False)
mock_imgui.push_style_color = MagicMock()
mock_imgui.pop_style_color = MagicMock()
mock_imgui.set_scroll_here_y = MagicMock()
mock_imgui.get_content_region_avail = MagicMock(return_value=type("P", (), {"x": 800.0, "y": 600.0})())
def _imvec2(x, y=0):
m = MagicMock(); m.x = float(x); m.y = float(y); return m
mock_imgui.ImVec2 = _imvec2
mock_imgui.ImVec4 = lambda *a: ("ImVec4", a)
mock_imscope.child = MagicMock()
mock_imscope.child.return_value.__enter__ = MagicMock()
mock_imscope.child.return_value.__exit__ = MagicMock()
mock_imscope.style_color = MagicMock()
mock_imscope.style_color.return_value.__enter__ = MagicMock()
mock_imscope.style_color.return_value.__exit__ = MagicMock()
app_instance.controller = MagicMock()
app_instance.controller.event_queue.put = MagicMock()
app_instance.cb_load_prior_log = MagicMock()
try:
render_comms_history_panel(app_instance)
except Exception as e:
import pytest
pytest.fail(f"render_comms_history_panel raised: {e}")
comms_calls = [call for call in mock_imscope.child.call_args_list if call[0][0] == "comms_scroll"]
assert len(comms_calls) == 1, "comms_scroll child should be opened once"
comms_call = comms_calls[0]
args, _ = comms_call
size_arg = args[1] if len(args) > 1 else 0
if hasattr(size_arg, 'x'):
size_x, size_y = size_arg.x, size_arg.y
else:
size_x = size_arg
size_y = 0
assert size_x > 0 and size_y > 0, f"comms_scroll child should use explicit content region size, got ({size_x}, {size_y})"