gemini quota exhausted: fixing regressions in test suite
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
# Plan: Fix Test Suite Regressions
|
||||
|
||||
## Objective
|
||||
Restore the full test suite to a passing state after the `gui_2.py` refactoring (Phase 2 & Phase 3 of Context Composition Redesign).
|
||||
|
||||
## Key Files & Context
|
||||
- `src/gui_2.py`: The main GUI entry point where methods were moved to module level.
|
||||
- `src/hot_reloader.py`: Handles module registration, currently causing collisions in tests.
|
||||
- `tests/*.py`: Multiple test files referencing deleted/moved methods.
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### Phase 1: Fix HotReloader Collisions
|
||||
- [ ] Modify `src/gui_2.py` to check if `src.gui_2` is already registered before calling `HotReloader.register`. This allows multiple `App()` instances (common in tests) without triggering `ValueError`.
|
||||
- [ ] Revert `src/hot_reloader.py` to its original state (raising `ValueError` on duplicate registration) to satisfy existing tests for that logic.
|
||||
|
||||
### Phase 2: Fix Method Migration Regressions (Batch)
|
||||
- [ ] Identify all test files calling `app._render_*` or checking `hasattr(App, '_render_*')`.
|
||||
- [ ] Use Tier 3 workers to surgically update these tests:
|
||||
- Change `app._render_XYZ()` to `gui_2.render_XYZ(app)`.
|
||||
- Change `hasattr(App, '_render_XYZ')` to `hasattr(gui_2, 'render_XYZ')` (and import `gui_2`).
|
||||
- Note: Some internal helpers might still be prefixed with `_` at the module level.
|
||||
- [ ] Target the following specific files:
|
||||
- `tests/test_ast_inspector_extended.py`
|
||||
- `tests/test_discussion_takes_gui.py`
|
||||
- `tests/test_gui_discussion_tabs.py`
|
||||
- `tests/test_gui_fast_render.py`
|
||||
- `tests/test_gui_phase4.py`
|
||||
- `tests/test_gui_progress.py`
|
||||
- `tests/test_gui_symbol_navigation.py`
|
||||
- `tests/test_gui_synthesis.py`
|
||||
- `tests/test_log_management_ui.py`
|
||||
- `tests/test_mma_approval_indicators.py`
|
||||
- `tests/test_mma_dashboard_streams.py`
|
||||
- `tests/test_project_settings_rename.py`
|
||||
- `tests/test_rag_gui_presence.py`
|
||||
- `tests/test_selectable_ui.py`
|
||||
- `tests/test_session_hub_merge.py`
|
||||
- `tests/test_shader_live_editor.py`
|
||||
- `tests/test_takes_panel.py`
|
||||
- `tests/test_thinking_gui.py`
|
||||
- `tests/test_token_viz.py`
|
||||
- `tests/test_ui_summary_only_removal.py`
|
||||
|
||||
### Phase 3: Address Specific Logic Failures
|
||||
- [ ] `tests/test_py_struct_tools.py`: Investigate and fix why definitions are not found.
|
||||
- [ ] `tests/test_rag_phase4_final_verify.py`: Investigate why RAG context is missing in history.
|
||||
- [ ] `tests/test_rag_phase4_stress.py`: Investigate timing issues (incremental indexing duration).
|
||||
- [ ] `tests/test_gui_kill_button.py`: Investigate missing "Actions" column in ticket queue.
|
||||
|
||||
## Verification & Testing
|
||||
- [ ] Run the full test suite using the batch script: `uv run python scripts/run_tests_batched.py`.
|
||||
- [ ] Ensure all 243 test files pass.
|
||||
+7
-6
@@ -119,12 +119,13 @@ class App:
|
||||
# --- Initialization ---
|
||||
self.controller.init_state()
|
||||
from src.hot_reloader import HotReloader, HotModule
|
||||
HotReloader.register(HotModule(
|
||||
name='src.gui_2',
|
||||
file_path=__file__,
|
||||
state_keys=['active_discussion', 'show_windows', 'ui_file_paths', 'ui_screenshot_paths', 'disc_entries', 'disc_roles'],
|
||||
delegation_targets=['_render_main_interface', '_render_discussion_hub', '_render_files_and_media', '_render_ai_settings_hub', '_render_operations_hub', '_render_mma_dashboard']
|
||||
))
|
||||
if 'src.gui_2' not in HotReloader.HOT_MODULES:
|
||||
HotReloader.register(HotModule(
|
||||
name='src.gui_2',
|
||||
file_path=__file__,
|
||||
state_keys=['active_discussion', 'show_windows', 'ui_file_paths', 'ui_screenshot_paths', 'disc_entries', 'disc_roles'],
|
||||
delegation_targets=['_render_main_interface', '_render_discussion_hub', '_render_files_and_media', '_render_ai_settings_hub', '_render_operations_hub', '_render_mma_dashboard']
|
||||
))
|
||||
self.workspace_manager = workspace_manager.WorkspaceManager(project_root=self.controller.active_project_root)
|
||||
self.disc_entries = self.controller.disc_entries
|
||||
self.disc_roles = self.controller.disc_roles
|
||||
|
||||
@@ -18,6 +18,8 @@ class HotReloader:
|
||||
|
||||
@classmethod
|
||||
def register(cls, module: HotModule) -> None:
|
||||
if module.name in cls.HOT_MODULES:
|
||||
raise ValueError(f"Module {module.name} already registered")
|
||||
cls.HOT_MODULES[module.name] = module
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import unittest.mock
|
||||
from unittest.mock import MagicMock, patch
|
||||
from src.gui_2 import App
|
||||
from src.gui_2 import App, render_ast_inspector_modal
|
||||
from src import models
|
||||
|
||||
def test_ast_inspector_line_range_parsing():
|
||||
@@ -37,7 +37,7 @@ def test_ast_inspector_line_range_parsing():
|
||||
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||
|
||||
# 4. Call the method
|
||||
App._render_ast_inspector_modal(app)
|
||||
render_ast_inspector_modal(app)
|
||||
|
||||
# 5. Assertions
|
||||
assert len(app._cached_ast_nodes) == 2
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch, call
|
||||
from src import gui_2
|
||||
from src.gui_2 import App
|
||||
|
||||
@pytest.fixture
|
||||
@@ -40,66 +41,66 @@ def app_instance():
|
||||
def test_render_discussion_tabs(app_instance):
|
||||
"""Verify that _render_discussion_panel uses tabs for discussions."""
|
||||
with patch('src.gui_2.imgui') as mock_imgui, \
|
||||
patch('src.gui_2.imscope') as mock_imscope:
|
||||
mock_imgui.collapsing_header.return_value = True
|
||||
mock_imgui.begin_combo.return_value = False
|
||||
mock_imgui.input_text.return_value = (False, "")
|
||||
mock_imgui.input_int.return_value = (False, 0)
|
||||
mock_imgui.input_text_multiline.return_value = (False, "")
|
||||
mock_imgui.button.return_value = False
|
||||
mock_imgui.checkbox.return_value = (False, False)
|
||||
mock_imgui.begin_child.return_value = True
|
||||
mock_imgui.selectable.return_value = (False, False)
|
||||
mock_imgui.ListClipper.return_value.step.return_value = False
|
||||
mock_imgui.begin_tab_bar.return_value = True
|
||||
patch('src.gui_2.imscope') as mock_imscope:
|
||||
mock_imgui.collapsing_header.return_value = True
|
||||
mock_imgui.begin_combo.return_value = False
|
||||
mock_imgui.input_text.return_value = (False, "")
|
||||
mock_imgui.input_int.return_value = (False, 0)
|
||||
mock_imgui.input_text_multiline.return_value = (False, "")
|
||||
mock_imgui.button.return_value = False
|
||||
mock_imgui.checkbox.return_value = (False, False)
|
||||
mock_imgui.begin_child.return_value = True
|
||||
mock_imgui.selectable.return_value = (False, False)
|
||||
mock_imgui.ListClipper.return_value.step.return_value = False
|
||||
mock_imgui.begin_tab_bar.return_value = True
|
||||
|
||||
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
||||
mock_imscope.child.return_value.__enter__.return_value = True
|
||||
mock_imscope.table.return_value.__enter__.return_value = True
|
||||
mock_imscope.tree_node_ex.return_value.__enter__.return_value = True
|
||||
mock_imscope.tab_item.return_value.__enter__.return_value = (True, True)
|
||||
mock_imscope.style_color.return_value.__enter__.return_value = None
|
||||
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
||||
mock_imscope.child.return_value.__enter__.return_value = True
|
||||
mock_imscope.table.return_value.__enter__.return_value = True
|
||||
mock_imscope.tree_node_ex.return_value.__enter__.return_value = True
|
||||
mock_imscope.tab_item.return_value.__enter__.return_value = (True, True)
|
||||
mock_imscope.style_color.return_value.__enter__.return_value = None
|
||||
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||
|
||||
mock_imgui.begin_tab_item.return_value = (True, True)
|
||||
mock_imgui.begin_tab_item.return_value = (True, True)
|
||||
|
||||
app_instance._render_discussion_panel()
|
||||
gui_2.render_discussion_panel(app_instance)
|
||||
|
||||
mock_imgui.begin_tab_bar.assert_called_with("discussion_takes_tabs")
|
||||
assert mock_imscope.tab_item.call_count >= 3, f"Expected at least 3 tab items via imscope.tab_item, got {mock_imscope.tab_item.call_count}"
|
||||
mock_imgui.begin_tab_bar.assert_called_with("discussion_takes_tabs")
|
||||
assert mock_imscope.tab_item.call_count >= 3, f"Expected at least 3 tab items via imscope.tab_item, got {mock_imscope.tab_item.call_count}"
|
||||
|
||||
def test_switching_discussion_via_tabs(app_instance):
|
||||
"""Verify that clicking a tab switches the discussion."""
|
||||
with patch('src.gui_2.imgui') as mock_imgui, \
|
||||
patch('src.gui_2.imscope') as mock_imscope, \
|
||||
patch('src.app_controller.AppController._switch_discussion') as mock_switch:
|
||||
mock_imgui.collapsing_header.return_value = True
|
||||
mock_imgui.begin_combo.return_value = False
|
||||
mock_imgui.input_text.return_value = (False, "")
|
||||
mock_imgui.input_int.return_value = (False, 0)
|
||||
mock_imgui.input_text_multiline.return_value = (False, "")
|
||||
mock_imgui.button.return_value = False
|
||||
mock_imgui.checkbox.return_value = (False, False)
|
||||
mock_imgui.begin_child.return_value = True
|
||||
mock_imgui.selectable.return_value = (False, False)
|
||||
mock_imgui.ListClipper.return_value.step.return_value = False
|
||||
mock_imgui.begin_tab_bar.return_value = True
|
||||
patch('src.gui_2.imscope') as mock_imscope, \
|
||||
patch('src.app_controller.AppController._switch_discussion') as mock_switch:
|
||||
mock_imgui.collapsing_header.return_value = True
|
||||
mock_imgui.begin_combo.return_value = False
|
||||
mock_imgui.input_text.return_value = (False, "")
|
||||
mock_imgui.input_int.return_value = (False, 0)
|
||||
mock_imgui.input_text_multiline.return_value = (False, "")
|
||||
mock_imgui.button.return_value = False
|
||||
mock_imgui.checkbox.return_value = (False, False)
|
||||
mock_imgui.begin_child.return_value = True
|
||||
mock_imgui.selectable.return_value = (False, False)
|
||||
mock_imgui.ListClipper.return_value.step.return_value = False
|
||||
mock_imgui.begin_tab_bar.return_value = True
|
||||
|
||||
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
||||
mock_imscope.child.return_value.__enter__.return_value = True
|
||||
mock_imscope.table.return_value.__enter__.return_value = True
|
||||
mock_imscope.tree_node_ex.return_value.__enter__.return_value = True
|
||||
mock_imscope.tab_item.return_value.__enter__.return_value = (True, True)
|
||||
mock_imscope.style_color.return_value.__enter__.return_value = None
|
||||
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
||||
mock_imscope.child.return_value.__enter__.return_value = True
|
||||
mock_imscope.table.return_value.__enter__.return_value = True
|
||||
mock_imscope.tree_node_ex.return_value.__enter__.return_value = True
|
||||
mock_imscope.tab_item.return_value.__enter__.return_value = (True, True)
|
||||
mock_imscope.style_color.return_value.__enter__.return_value = None
|
||||
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||
|
||||
def begin_tab_item_side_effect(label, p_open=None, flags=None):
|
||||
if "main_take_1" in label:
|
||||
return (True, True)
|
||||
return (False, True)
|
||||
def begin_tab_item_side_effect(label, p_open=None, flags=None):
|
||||
if "main_take_1" in label:
|
||||
return (True, True)
|
||||
return (False, True)
|
||||
|
||||
mock_imgui.begin_tab_item.side_effect = begin_tab_item_side_effect
|
||||
mock_imgui.begin_tab_item.side_effect = begin_tab_item_side_effect
|
||||
|
||||
app_instance._render_discussion_panel()
|
||||
gui_2.render_discussion_panel(app_instance)
|
||||
|
||||
assert mock_switch.called, f"Expected _switch_discussion to be called"
|
||||
assert mock_switch.called, f"Expected _switch_discussion to be called"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock, PropertyMock
|
||||
|
||||
from src import gui_2
|
||||
|
||||
@pytest.fixture
|
||||
@@ -27,7 +26,7 @@ def test_discussion_tabs_rendered(mock_gui):
|
||||
patch('src.gui_2.imscope') as mock_imscope, \
|
||||
patch('src.imgui_scopes.imgui', new=mock_imgui), \
|
||||
patch('src.app_controller.AppController.active_project_root', new_callable=PropertyMock, return_value='.'):
|
||||
|
||||
|
||||
# Setup imscope mocks
|
||||
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
||||
mock_imscope.child.return_value.__enter__.return_value = True
|
||||
@@ -40,7 +39,7 @@ def test_discussion_tabs_rendered(mock_gui):
|
||||
# We expect a combo box for base discussion
|
||||
mock_imgui.begin_combo.return_value = True
|
||||
mock_imgui.selectable.return_value = (False, False)
|
||||
|
||||
|
||||
# We expect a tab bar for takes
|
||||
mock_imgui.begin_tab_bar.return_value = True
|
||||
mock_imgui.begin_tab_item.return_value = (True, True)
|
||||
@@ -48,16 +47,16 @@ def test_discussion_tabs_rendered(mock_gui):
|
||||
mock_imgui.input_text_multiline.return_value = (False, "")
|
||||
mock_imgui.checkbox.return_value = (False, False)
|
||||
mock_imgui.input_int.return_value = (False, 0)
|
||||
|
||||
|
||||
mock_clipper = MagicMock()
|
||||
mock_clipper.step.return_value = False
|
||||
mock_imgui.ListClipper.return_value = mock_clipper
|
||||
|
||||
mock_gui._render_discussion_panel()
|
||||
|
||||
|
||||
gui_2.render_discussion_panel(mock_gui)
|
||||
|
||||
mock_imgui.begin_combo.assert_called_once_with("##disc_sel", 'main')
|
||||
mock_imgui.begin_tab_bar.assert_called_once_with('discussion_takes_tabs')
|
||||
|
||||
|
||||
calls = [c[0][0] for c in mock_imscope.tab_item.call_args_list]
|
||||
assert 'Original###main' in calls
|
||||
assert 'Take 1###main_take_1' in calls
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
from src.gui_2 import App
|
||||
from src import gui_2
|
||||
|
||||
def test_render_context_composition_panel_fast(app_instance: App):
|
||||
"""Verifies that the context composition panel rendering path executes without exceptions."""
|
||||
@@ -18,9 +19,9 @@ def test_render_context_composition_panel_fast(app_instance: App):
|
||||
mock_imscope.tab_item.return_value.__enter__.return_value = (True, True)
|
||||
|
||||
try:
|
||||
app_instance._render_context_composition_panel()
|
||||
gui_2.render_context_composition_panel(app_instance)
|
||||
except Exception as e:
|
||||
pytest.fail(f"_render_context_composition_panel raised an exception: {e}")
|
||||
pytest.fail(f"render_context_composition_panel raised an exception: {e}")
|
||||
|
||||
def test_render_discussion_panel_fast(app_instance: App):
|
||||
"""Verifies that the discussion panel rendering path executes without exceptions."""
|
||||
@@ -37,10 +38,15 @@ def test_render_discussion_panel_fast(app_instance: App):
|
||||
mock_imgui.ListClipper.return_value.step.return_value = False
|
||||
mock_imscope.tab_item.return_value.__enter__.return_value = (True, True)
|
||||
|
||||
# Mocks for complex imgui logic in render_discussion_tab
|
||||
mock_imgui.is_item_active.return_value = False
|
||||
mock_imgui.begin_tab_bar.return_value = False
|
||||
mock_imgui.begin_tab_item.return_value = (False, False)
|
||||
|
||||
try:
|
||||
app_instance._render_discussion_panel()
|
||||
gui_2.render_discussion_hub(app_instance)
|
||||
except Exception as e:
|
||||
pytest.fail(f"_render_discussion_panel raised an exception: {e}")
|
||||
pytest.fail(f"render_discussion_hub raised an exception: {e}")
|
||||
|
||||
def test_render_files_and_media_fast(app_instance: App):
|
||||
"""Verifies that the files and media panel rendering path executes without exceptions."""
|
||||
@@ -58,6 +64,6 @@ def test_render_files_and_media_fast(app_instance: App):
|
||||
mock_imscope.tab_item.return_value.__enter__.return_value = (True, True)
|
||||
|
||||
try:
|
||||
app_instance._render_files_and_media()
|
||||
gui_2.render_files_and_media(app_instance)
|
||||
except Exception as e:
|
||||
pytest.fail(f"_render_files_and_media raised an exception: {e}")
|
||||
pytest.fail(f"render_files_and_media raised an exception: {e}")
|
||||
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
from src import gui_2
|
||||
from src.gui_2 import App
|
||||
from src.models import Track
|
||||
|
||||
@@ -70,6 +71,8 @@ def test_delete_ticket_logic(mock_app: App):
|
||||
def test_track_discussion_toggle(mock_app: App):
|
||||
with (
|
||||
patch('src.gui_2.imgui') as mock_imgui,
|
||||
patch('src.theme_2.imgui', new=mock_imgui),
|
||||
patch('src.imgui_scopes.imgui', new=mock_imgui),
|
||||
patch('src.gui_2.imscope') as mock_imscope,
|
||||
patch('src.gui_2.project_manager.load_track_history', return_value=["@2026-03-01 12:00:00\n[User]\nTrack Hello"]) as mock_load,
|
||||
patch('src.gui_2.project_manager.str_to_entry', side_effect=lambda s, roles: {"ts": "12:00", "role": "User", "content": s.split("\n")[-1]}),
|
||||
@@ -97,11 +100,19 @@ def test_track_discussion_toggle(mock_app: App):
|
||||
mock_imgui.begin_combo.return_value = False
|
||||
mock_imgui.selectable.return_value = (False, False)
|
||||
mock_imgui.button.return_value = False
|
||||
mock_imgui.collapsing_header.return_value = True # For Discussions header
|
||||
mock_imgui.combo.return_value = (False, 0)
|
||||
mock_imgui.begin_tab_bar.return_value = True
|
||||
mock_imgui.collapsing_header.return_value = True # For Discussions header
|
||||
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_imgui.begin_child.return_value = True
|
||||
mock_imgui.get_window_height.return_value = 800.0
|
||||
mock_imgui.get_io.return_value.mouse_delta.y = 0.0
|
||||
mock_imgui.is_item_active.return_value = False
|
||||
mock_imgui.get_style.return_value.color_.return_value = (1, 1, 1, 1)
|
||||
mock_imgui.Col_ = MagicMock()
|
||||
mock_imgui.set_scroll_here_y.return_value = None
|
||||
# Mock clipper to avoid the while loop hang
|
||||
mock_clipper = MagicMock()
|
||||
mock_clipper.step.side_effect = [True, False]
|
||||
@@ -109,7 +120,7 @@ def test_track_discussion_toggle(mock_app: App):
|
||||
mock_clipper.display_end = 0
|
||||
mock_imgui.ListClipper.return_value = mock_clipper
|
||||
|
||||
mock_app._render_discussion_panel()
|
||||
gui_2.render_discussion_hub(mock_app)
|
||||
|
||||
assert mock_app._track_discussion_active
|
||||
mock_flush.assert_called()
|
||||
@@ -127,7 +138,7 @@ def test_track_discussion_toggle(mock_app: App):
|
||||
mock_imgui.checkbox.side_effect = checkbox_off_side_effect
|
||||
mock_clipper.step.side_effect = [True, False] # Reset clipper
|
||||
|
||||
mock_app._render_discussion_panel()
|
||||
gui_2.render_discussion_hub(mock_app)
|
||||
|
||||
assert not mock_app._track_discussion_active
|
||||
mock_switch.assert_called_with(mock_app.active_discussion)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
from src import gui_2
|
||||
from src.gui_2 import App, C_LBL, C_VAL
|
||||
from src.models import Ticket
|
||||
|
||||
@@ -60,16 +61,16 @@ def test_render_mma_dashboard_progress():
|
||||
|
||||
# Call the method
|
||||
# Dashboard now delegates to sub-methods, so we wire them up to execute their real logic on the mock instance.
|
||||
app._render_mma_focus_selector.side_effect = lambda: App._render_mma_focus_selector(app)
|
||||
app._render_mma_track_summary.side_effect = lambda: App._render_mma_track_summary(app)
|
||||
app._render_mma_epic_planner.side_effect = lambda: App._render_mma_epic_planner(app)
|
||||
app._render_mma_conductor_setup.side_effect = lambda: App._render_mma_conductor_setup(app)
|
||||
app._render_mma_track_browser.side_effect = lambda: App._render_mma_track_browser(app)
|
||||
app._render_mma_global_controls.side_effect = lambda: App._render_mma_global_controls(app)
|
||||
app._render_mma_usage_section.side_effect = lambda: App._render_mma_usage_section(app)
|
||||
app._render_mma_agent_streams.side_effect = lambda: App._render_mma_agent_streams(app)
|
||||
app._render_mma_focus_selector.side_effect = lambda: gui_2.render_mma_focus_selector(app)
|
||||
app._render_mma_track_summary.side_effect = lambda: gui_2.render_mma_track_summary(app)
|
||||
app._render_mma_epic_planner.side_effect = lambda: gui_2.render_mma_epic_planner(app)
|
||||
app._render_mma_conductor_setup.side_effect = lambda: gui_2.render_mma_conductor_setup(app)
|
||||
app._render_mma_track_browser.side_effect = lambda: gui_2.render_mma_track_browser(app)
|
||||
app._render_mma_global_controls.side_effect = lambda: gui_2.render_mma_global_controls(app)
|
||||
app._render_mma_usage_section.side_effect = lambda: gui_2.render_mma_usage_section(app)
|
||||
app._render_mma_agent_streams.side_effect = lambda: gui_2.render_mma_agent_streams(app)
|
||||
|
||||
App._render_mma_dashboard(app)
|
||||
gui_2.render_mma_dashboard(app)
|
||||
# Assertions
|
||||
# 1 completed out of 4 tickets = 25.0% progress
|
||||
# Update assertions: imgui.progress_bar is called with (0.25, (-1.0, 0.0), '25.0%')
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
from src import gui_2
|
||||
from src.gui_2 import App
|
||||
|
||||
@pytest.mark.parametrize("role", ["User", "AI"])
|
||||
@@ -75,7 +76,7 @@ def test_render_discussion_panel_symbol_lookup(mock_app, role):
|
||||
mock_mcp.read_file.return_value = "class MyClass:\n pass"
|
||||
|
||||
# Execute the panel rendering
|
||||
mock_app._render_discussion_panel()
|
||||
gui_2.render_discussion_panel(mock_app)
|
||||
|
||||
# Assertions
|
||||
# 1. Assert that the regex correctly identifies the pattern and imgui.button('[Source]##0_0') is called
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch, ANY
|
||||
from src import gui_2
|
||||
from src.gui_2 import App
|
||||
|
||||
@pytest.fixture
|
||||
@@ -35,7 +36,7 @@ def app_instance():
|
||||
yield app
|
||||
|
||||
def test_render_synthesis_panel(app_instance):
|
||||
"""Verify that _render_synthesis_panel renders checkboxes for takes and input for prompt."""
|
||||
"""Verify that render_synthesis_panel renders checkboxes for takes and input for prompt."""
|
||||
with patch('src.gui_2.imgui') as mock_imgui, \
|
||||
patch('src.gui_2.imscope') as mock_imscope:
|
||||
mock_imgui.checkbox.return_value = (False, False)
|
||||
@@ -52,7 +53,7 @@ def test_render_synthesis_panel(app_instance):
|
||||
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||
|
||||
# Call the method we are testing
|
||||
app_instance._render_synthesis_panel()
|
||||
gui_2.render_synthesis_panel(app_instance)
|
||||
|
||||
# 1. Assert imgui.checkbox is called for each take in project_dict['discussion']['discussions']
|
||||
discussions = app_instance.project['discussion']['discussions']
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
from pathlib import Path
|
||||
|
||||
# We can safely import gui_2 if we don't instantiate App without mocking its threads
|
||||
from src import gui_2
|
||||
from src.gui_2 import App
|
||||
|
||||
@pytest.fixture
|
||||
@@ -60,8 +59,8 @@ def test_log_management_init(app_instance: App) -> None:
|
||||
app = app_instance
|
||||
assert "Log Management" in app.show_windows
|
||||
assert app.show_windows["Log Management"] is False
|
||||
assert hasattr(app, "_render_log_management")
|
||||
assert callable(app._render_log_management)
|
||||
assert hasattr(gui_2, "render_log_management")
|
||||
assert callable(gui_2.render_log_management)
|
||||
|
||||
def test_render_log_management_logic(app_instance: App) -> None:
|
||||
app = app_instance
|
||||
@@ -98,7 +97,7 @@ def test_render_log_management_logic(app_instance: App) -> None:
|
||||
mock_imscope.window.return_value = mock_window_cm
|
||||
|
||||
mock_begin_table.return_value = True
|
||||
app._render_log_management()
|
||||
gui_2.render_log_management(app)
|
||||
mock_imscope.window.assert_called_with("Log Management", app.show_windows["Log Management"])
|
||||
mock_begin_table.assert_called()
|
||||
mock_text.assert_any_call("session_1")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from src import gui_2
|
||||
from src.gui_2 import App
|
||||
|
||||
|
||||
@@ -63,18 +64,18 @@ def _make_app(**kwargs):
|
||||
app.controller = mock_controller
|
||||
|
||||
# Ensure real methods are called for the dashboard rendering components
|
||||
app._render_mma_dashboard = lambda: App._render_mma_dashboard(app)
|
||||
app._render_mma_focus_selector = lambda: App._render_mma_focus_selector(app)
|
||||
app._render_mma_track_summary = lambda: App._render_mma_track_summary(app)
|
||||
app._render_mma_epic_planner = lambda: App._render_mma_epic_planner(app)
|
||||
app._render_mma_conductor_setup = lambda: App._render_mma_conductor_setup(app)
|
||||
app._render_mma_track_browser = lambda: App._render_mma_track_browser(app)
|
||||
app._render_mma_global_controls = lambda: App._render_mma_global_controls(app)
|
||||
app._render_mma_usage_section = lambda: App._render_mma_usage_section(app)
|
||||
app._render_ticket_queue = lambda: App._render_ticket_queue(app)
|
||||
app._render_mma_dashboard = lambda: gui_2.render_mma_dashboard(app)
|
||||
app._render_mma_focus_selector = lambda: gui_2.render_mma_focus_selector(app)
|
||||
app._render_mma_track_summary = lambda: gui_2.render_mma_track_summary(app)
|
||||
app._render_mma_epic_planner = lambda: gui_2.render_mma_epic_planner(app)
|
||||
app._render_mma_conductor_setup = lambda: gui_2.render_mma_conductor_setup(app)
|
||||
app._render_mma_track_browser = lambda: gui_2.render_mma_track_browser(app)
|
||||
app._render_mma_global_controls = lambda: gui_2.render_mma_global_controls(app)
|
||||
app._render_mma_usage_section = lambda: gui_2.render_mma_usage_section(app)
|
||||
app._render_ticket_queue = lambda: gui_2.render_ticket_queue(app)
|
||||
app._render_window_if_open = lambda name, func, condition=True: func() if condition else None
|
||||
app._render_mma_ticket_editor = lambda: App._render_mma_ticket_editor(app)
|
||||
app._render_mma_agent_streams = lambda: App._render_mma_agent_streams(app)
|
||||
app._render_mma_ticket_editor = lambda: gui_2.render_mma_ticket_editor(app)
|
||||
app._render_mma_agent_streams = lambda: gui_2.render_mma_agent_streams(app)
|
||||
|
||||
return app
|
||||
|
||||
@@ -126,7 +127,7 @@ class TestMMAApprovalIndicators:
|
||||
mock_imscope.style_color.return_value.__enter__.return_value = None
|
||||
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||
|
||||
App._render_mma_dashboard(app)
|
||||
gui_2.render_mma_dashboard(app)
|
||||
combined = _collect_text_colored_args(imgui_mock)
|
||||
assert "APPROVAL PENDING" not in combined, (
|
||||
"text_colored called with 'APPROVAL PENDING' when no approval is pending"
|
||||
@@ -147,7 +148,7 @@ class TestMMAApprovalIndicators:
|
||||
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||
|
||||
mock_math.sin.return_value = 0.8
|
||||
App._render_mma_dashboard(app)
|
||||
gui_2.render_mma_dashboard(app)
|
||||
combined = _collect_text_colored_args(imgui_mock)
|
||||
assert "APPROVAL PENDING" in combined, (
|
||||
"text_colored not called with 'APPROVAL PENDING' when _pending_mma_spawn is set"
|
||||
@@ -168,7 +169,7 @@ class TestMMAApprovalIndicators:
|
||||
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||
|
||||
mock_math.sin.return_value = 0.8
|
||||
App._render_mma_dashboard(app)
|
||||
gui_2.render_mma_dashboard(app)
|
||||
combined = _collect_text_colored_args(imgui_mock)
|
||||
assert "APPROVAL PENDING" in combined, (
|
||||
"text_colored not called with 'APPROVAL PENDING' when _pending_mma_approval is set"
|
||||
@@ -189,7 +190,7 @@ class TestMMAApprovalIndicators:
|
||||
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||
|
||||
mock_math.sin.return_value = 0.8
|
||||
App._render_mma_dashboard(app)
|
||||
gui_2.render_mma_dashboard(app)
|
||||
combined = _collect_text_colored_args(imgui_mock)
|
||||
assert "APPROVAL PENDING" in combined, (
|
||||
"text_colored not called with 'APPROVAL PENDING' when _pending_ask_dialog is True"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from src import gui_2
|
||||
from src.gui_2 import App
|
||||
|
||||
|
||||
@@ -64,7 +65,9 @@ class TestMMADashboardStreams:
|
||||
app = _make_app(mma_streams={"Tier 1": "hello"})
|
||||
imgui_mock = _make_imgui_mock()
|
||||
imgui_mock.begin_child.return_value = True
|
||||
with patch("src.gui_2.imgui", imgui_mock), patch("src.gui_2.imscope") as mock_imscope:
|
||||
with patch("src.gui_2.imgui", imgui_mock), \
|
||||
patch("src.gui_2.imscope") as mock_imscope, \
|
||||
patch("src.gui_2.render_selectable_label") as mock_render:
|
||||
# Setup imscope mocks
|
||||
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
||||
mock_imscope.child.return_value.__enter__.return_value = True
|
||||
@@ -74,9 +77,9 @@ class TestMMADashboardStreams:
|
||||
mock_imscope.style_color.return_value.__enter__.return_value = None
|
||||
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||
|
||||
App._render_tier_stream_panel(app, "Tier 1", "Tier 1")
|
||||
gui_2.render_tier_stream_panel(app, "Tier 1", "Tier 1")
|
||||
|
||||
app._render_selectable_label.assert_called_with('stream_Tier 1', 'hello', width=-1, multiline=True, height=0)
|
||||
mock_render.assert_called_with(app, 'stream_Tier 1', 'hello', width=-1, multiline=True, height=0)
|
||||
|
||||
def test_tier3_renders_worker_subheaders(self):
|
||||
"""_render_tier_stream_panel for Tier 3 must render a sub-header for each worker stream key."""
|
||||
@@ -86,7 +89,9 @@ class TestMMADashboardStreams:
|
||||
})
|
||||
imgui_mock = _make_imgui_mock()
|
||||
imgui_mock.begin_child.return_value = True
|
||||
with patch("src.gui_2.imgui", imgui_mock), patch("src.gui_2.imscope") as mock_imscope:
|
||||
with patch("src.gui_2.imgui", imgui_mock), \
|
||||
patch("src.gui_2.imscope") as mock_imscope, \
|
||||
patch("src.gui_2.render_selectable_label"):
|
||||
# Setup imscope mocks
|
||||
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
||||
mock_imscope.child.return_value.__enter__.return_value = True
|
||||
@@ -96,7 +101,7 @@ class TestMMADashboardStreams:
|
||||
mock_imscope.style_color.return_value.__enter__.return_value = None
|
||||
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||
|
||||
App._render_tier_stream_panel(app, "Tier 3", None)
|
||||
gui_2.render_tier_stream_panel(app, "Tier 3", None)
|
||||
text_args = " ".join(str(c) for c in imgui_mock.text.call_args_list)
|
||||
assert "T-001" in text_args, "imgui.text not called with 'T-001' worker sub-header"
|
||||
assert "T-002" in text_args, "imgui.text not called with 'T-002' worker sub-header"
|
||||
@@ -1,42 +1,32 @@
|
||||
import pytest
|
||||
import inspect
|
||||
|
||||
|
||||
def test_session_hub_window_removed():
|
||||
import src.gui_2 as gui_2
|
||||
|
||||
source = inspect.getsource(gui_2.App._render_main_interface)
|
||||
assert "Session Hub" not in source, "Session Hub window should be removed"
|
||||
|
||||
import src.gui_2 as gui_2
|
||||
source = inspect.getsource(gui_2.render_main_interface)
|
||||
assert "Session Hub" not in source, "Session Hub window should be removed"
|
||||
|
||||
def test_discussion_hub_has_snapshot_tab():
|
||||
import src.gui_2 as gui_2
|
||||
|
||||
source = inspect.getsource(gui_2.App._render_discussion_hub)
|
||||
assert "Snapshot" in source, "Discussion Hub should have Snapshot tab"
|
||||
assert "_render_snapshot_tab" in source, "Discussion Hub should call _render_snapshot_tab"
|
||||
|
||||
import src.gui_2 as gui_2
|
||||
source = inspect.getsource(gui_2.render_discussion_hub)
|
||||
assert "Snapshot" in source, "Discussion Hub should have Snapshot tab"
|
||||
assert "render_snapshot_tab" in source, "Discussion Hub should call render_snapshot_tab"
|
||||
|
||||
def test_discussion_hub_has_context_composition_placeholder():
|
||||
import src.gui_2 as gui_2
|
||||
|
||||
source = inspect.getsource(gui_2.App._render_discussion_hub)
|
||||
assert "Context Composition" in source, (
|
||||
"Discussion Hub should have Context Composition tab placeholder"
|
||||
)
|
||||
|
||||
import src.gui_2 as gui_2
|
||||
source = inspect.getsource(gui_2.render_discussion_hub)
|
||||
assert "Context Composition" in source, (
|
||||
"Discussion Hub should have Context Composition tab placeholder"
|
||||
)
|
||||
|
||||
def test_discussion_hub_has_takes_tab():
|
||||
import src.gui_2 as gui_2
|
||||
|
||||
source = inspect.getsource(gui_2.App._render_discussion_hub)
|
||||
assert "Takes" in source, "Discussion Hub should have Takes tab"
|
||||
|
||||
import src.gui_2 as gui_2
|
||||
source = inspect.getsource(gui_2.render_discussion_hub)
|
||||
assert "Takes" in source, "Discussion Hub should have Takes tab"
|
||||
|
||||
def test_show_windows_no_session_hub():
|
||||
import src.app_controller as app_controller
|
||||
|
||||
source = inspect.getsource(app_controller.AppController)
|
||||
assert "Session Hub" not in source, (
|
||||
"Session Hub should be removed from show_windows"
|
||||
)
|
||||
import src.app_controller as app_controller
|
||||
source = inspect.getsource(app_controller.AppController)
|
||||
assert "Session Hub" not in source, (
|
||||
"Session Hub should be removed from show_windows"
|
||||
)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
from src import gui_2
|
||||
from src.gui_2 import App
|
||||
|
||||
def test_shader_live_editor_renders():
|
||||
from src.gui_2 import App
|
||||
app = App()
|
||||
app.show_windows["Shader Editor"] = True
|
||||
|
||||
@@ -20,5 +21,5 @@ def test_shader_live_editor_renders():
|
||||
mock_imscope.style_color.return_value.__enter__.return_value = None
|
||||
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||
|
||||
app._render_shader_live_editor()
|
||||
gui_2.render_shader_live_editor(app)
|
||||
assert mock_imscope.window.called
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import pytest
|
||||
import inspect
|
||||
|
||||
from src import gui_2
|
||||
|
||||
def test_takes_tab_replaces_placeholder():
|
||||
import src.gui_2 as gui_2
|
||||
|
||||
source = inspect.getsource(gui_2.App._gui_func)
|
||||
assert "_render_takes_placeholder" not in source, "Placeholder should be replaced"
|
||||
import src.gui_2 as gui_2
|
||||
|
||||
source = inspect.getsource(gui_2.App._gui_func)
|
||||
assert "_render_takes_placeholder" not in source, "Placeholder should be replaced"
|
||||
|
||||
def test_takes_panel_has_synthesis():
|
||||
import src.gui_2 as gui_2
|
||||
import src.gui_2 as gui_2
|
||||
|
||||
source = inspect.getsource(gui_2.App._render_takes_panel)
|
||||
assert "synthesis" in source.lower(), "Should have synthesis functionality"
|
||||
source = inspect.getsource(gui_2.render_takes_panel)
|
||||
assert "synthesis" in source.lower(), "Should have synthesis functionality"
|
||||
|
||||
Reference in New Issue
Block a user