80 lines
3.2 KiB
Python
80 lines
3.2 KiB
Python
import pytest
|
|
from unittest.mock import MagicMock, patch
|
|
from src.gui_2 import App
|
|
|
|
@pytest.mark.parametrize("role", ["User", "AI"])
|
|
def test_render_discussion_panel_symbol_lookup(mock_app, role):
|
|
# Mock imgui, mcp_client, and project_manager as requested
|
|
with (
|
|
patch('src.gui_2.imgui') as mock_imgui,
|
|
patch('src.gui_2.mcp_client') as mock_mcp,
|
|
patch('src.gui_2.project_manager') as mock_pm
|
|
):
|
|
# Set up App instance state
|
|
mock_app.perf_profiling_enabled = False
|
|
mock_app.ai_status = "idle"
|
|
mock_app.is_viewing_prior_session = False
|
|
mock_app.active_discussion = "Default"
|
|
mock_app.project = {"discussion": {"discussions": {"Default": {}}}}
|
|
mock_app.disc_entries = [{"role": role, "content": "[Definition: MyClass from src/models.py (line 10)]", "collapsed": False, "read_mode": True}]
|
|
mock_app.disc_roles = ["User", "AI"]
|
|
mock_app.ui_files_base_dir = "."
|
|
mock_app.active_track = None
|
|
mock_app.ui_disc_new_name_input = ""
|
|
mock_app.ui_auto_add_history = False
|
|
mock_app.ui_disc_truncate_pairs = 10
|
|
mock_app.ui_disc_new_role_input = ""
|
|
mock_app._disc_entries_lock = MagicMock()
|
|
mock_app._scroll_disc_to_bottom = False
|
|
mock_app.ui_word_wrap = False
|
|
mock_app.show_text_viewer = False
|
|
mock_app.text_viewer_title = ""
|
|
mock_app.text_viewer_content = ""
|
|
|
|
# Mock internal methods to avoid side effects
|
|
mock_app._get_discussion_names = MagicMock(return_value=["Default"])
|
|
mock_app._render_text_viewer = MagicMock()
|
|
|
|
# Mock imgui behavior to reach the entry rendering loop
|
|
mock_imgui.collapsing_header.return_value = True
|
|
mock_imgui.begin_combo.return_value = False
|
|
mock_imgui.begin_child.return_value = True
|
|
mock_imgui.checkbox.return_value = (False, False)
|
|
mock_imgui.input_text.side_effect = lambda label, value, *args, **kwargs: (False, value)
|
|
mock_imgui.input_text_multiline.side_effect = lambda label, value, *args, **kwargs: (False, value)
|
|
mock_imgui.input_int.side_effect = lambda label, value, *args, **kwargs: (False, value)
|
|
|
|
# Mock clipper to process the single entry
|
|
mock_clipper = MagicMock()
|
|
mock_imgui.ListClipper.return_value = mock_clipper
|
|
mock_clipper.step.side_effect = [True, False]
|
|
mock_clipper.display_start = 0
|
|
mock_clipper.display_end = 1
|
|
|
|
# Mock button click for the [Source] button
|
|
# The code renders: if imgui.button(f"[Source]##{i}_{match.start()}"):
|
|
# We want it to return True for our entry at index 0.
|
|
def button_side_effect(label):
|
|
if label == "[Source]##0_0":
|
|
return True
|
|
return False
|
|
mock_imgui.button.side_effect = button_side_effect
|
|
|
|
# Mock mcp_client.read_file return value
|
|
mock_mcp.read_file.return_value = "class MyClass:\n pass"
|
|
|
|
# Execute the panel rendering
|
|
mock_app._render_discussion_panel()
|
|
|
|
# Assertions
|
|
# 1. Assert that the regex correctly identifies the pattern and imgui.button('[Source]##0_0') is called
|
|
mock_imgui.button.assert_any_call("[Source]##0_0")
|
|
|
|
# 2. Verify mcp_client.read_file('src/models.py') is called upon button click
|
|
mock_mcp.read_file.assert_called_with("src/models.py")
|
|
|
|
# 3. Verify the text viewer state is updated correctly
|
|
assert mock_app.text_viewer_title == "src/models.py"
|
|
assert mock_app.text_viewer_content == "class MyClass:\n pass"
|
|
assert mock_app.show_text_viewer is True
|