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 ---
|
# --- Initialization ---
|
||||||
self.controller.init_state()
|
self.controller.init_state()
|
||||||
from src.hot_reloader import HotReloader, HotModule
|
from src.hot_reloader import HotReloader, HotModule
|
||||||
HotReloader.register(HotModule(
|
if 'src.gui_2' not in HotReloader.HOT_MODULES:
|
||||||
name='src.gui_2',
|
HotReloader.register(HotModule(
|
||||||
file_path=__file__,
|
name='src.gui_2',
|
||||||
state_keys=['active_discussion', 'show_windows', 'ui_file_paths', 'ui_screenshot_paths', 'disc_entries', 'disc_roles'],
|
file_path=__file__,
|
||||||
delegation_targets=['_render_main_interface', '_render_discussion_hub', '_render_files_and_media', '_render_ai_settings_hub', '_render_operations_hub', '_render_mma_dashboard']
|
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.workspace_manager = workspace_manager.WorkspaceManager(project_root=self.controller.active_project_root)
|
||||||
self.disc_entries = self.controller.disc_entries
|
self.disc_entries = self.controller.disc_entries
|
||||||
self.disc_roles = self.controller.disc_roles
|
self.disc_roles = self.controller.disc_roles
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ class HotReloader:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def register(cls, module: HotModule) -> None:
|
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
|
cls.HOT_MODULES[module.name] = module
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import unittest.mock
|
import unittest.mock
|
||||||
from unittest.mock import MagicMock, patch
|
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
|
from src import models
|
||||||
|
|
||||||
def test_ast_inspector_line_range_parsing():
|
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
|
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||||
|
|
||||||
# 4. Call the method
|
# 4. Call the method
|
||||||
App._render_ast_inspector_modal(app)
|
render_ast_inspector_modal(app)
|
||||||
|
|
||||||
# 5. Assertions
|
# 5. Assertions
|
||||||
assert len(app._cached_ast_nodes) == 2
|
assert len(app._cached_ast_nodes) == 2
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from unittest.mock import MagicMock, patch, call
|
from unittest.mock import MagicMock, patch, call
|
||||||
|
from src import gui_2
|
||||||
from src.gui_2 import App
|
from src.gui_2 import App
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@@ -40,66 +41,66 @@ def app_instance():
|
|||||||
def test_render_discussion_tabs(app_instance):
|
def test_render_discussion_tabs(app_instance):
|
||||||
"""Verify that _render_discussion_panel uses tabs for discussions."""
|
"""Verify that _render_discussion_panel uses tabs for discussions."""
|
||||||
with patch('src.gui_2.imgui') as mock_imgui, \
|
with patch('src.gui_2.imgui') as mock_imgui, \
|
||||||
patch('src.gui_2.imscope') as mock_imscope:
|
patch('src.gui_2.imscope') as mock_imscope:
|
||||||
mock_imgui.collapsing_header.return_value = True
|
mock_imgui.collapsing_header.return_value = True
|
||||||
mock_imgui.begin_combo.return_value = False
|
mock_imgui.begin_combo.return_value = False
|
||||||
mock_imgui.input_text.return_value = (False, "")
|
mock_imgui.input_text.return_value = (False, "")
|
||||||
mock_imgui.input_int.return_value = (False, 0)
|
mock_imgui.input_int.return_value = (False, 0)
|
||||||
mock_imgui.input_text_multiline.return_value = (False, "")
|
mock_imgui.input_text_multiline.return_value = (False, "")
|
||||||
mock_imgui.button.return_value = False
|
mock_imgui.button.return_value = False
|
||||||
mock_imgui.checkbox.return_value = (False, False)
|
mock_imgui.checkbox.return_value = (False, False)
|
||||||
mock_imgui.begin_child.return_value = True
|
mock_imgui.begin_child.return_value = True
|
||||||
mock_imgui.selectable.return_value = (False, False)
|
mock_imgui.selectable.return_value = (False, False)
|
||||||
mock_imgui.ListClipper.return_value.step.return_value = False
|
mock_imgui.ListClipper.return_value.step.return_value = False
|
||||||
mock_imgui.begin_tab_bar.return_value = True
|
mock_imgui.begin_tab_bar.return_value = True
|
||||||
|
|
||||||
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
||||||
mock_imscope.child.return_value.__enter__.return_value = True
|
mock_imscope.child.return_value.__enter__.return_value = True
|
||||||
mock_imscope.table.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.tree_node_ex.return_value.__enter__.return_value = True
|
||||||
mock_imscope.tab_item.return_value.__enter__.return_value = (True, 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_color.return_value.__enter__.return_value = None
|
||||||
mock_imscope.style_var.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")
|
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}"
|
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):
|
def test_switching_discussion_via_tabs(app_instance):
|
||||||
"""Verify that clicking a tab switches the discussion."""
|
"""Verify that clicking a tab switches the discussion."""
|
||||||
with patch('src.gui_2.imgui') as mock_imgui, \
|
with patch('src.gui_2.imgui') as mock_imgui, \
|
||||||
patch('src.gui_2.imscope') as mock_imscope, \
|
patch('src.gui_2.imscope') as mock_imscope, \
|
||||||
patch('src.app_controller.AppController._switch_discussion') as mock_switch:
|
patch('src.app_controller.AppController._switch_discussion') as mock_switch:
|
||||||
mock_imgui.collapsing_header.return_value = True
|
mock_imgui.collapsing_header.return_value = True
|
||||||
mock_imgui.begin_combo.return_value = False
|
mock_imgui.begin_combo.return_value = False
|
||||||
mock_imgui.input_text.return_value = (False, "")
|
mock_imgui.input_text.return_value = (False, "")
|
||||||
mock_imgui.input_int.return_value = (False, 0)
|
mock_imgui.input_int.return_value = (False, 0)
|
||||||
mock_imgui.input_text_multiline.return_value = (False, "")
|
mock_imgui.input_text_multiline.return_value = (False, "")
|
||||||
mock_imgui.button.return_value = False
|
mock_imgui.button.return_value = False
|
||||||
mock_imgui.checkbox.return_value = (False, False)
|
mock_imgui.checkbox.return_value = (False, False)
|
||||||
mock_imgui.begin_child.return_value = True
|
mock_imgui.begin_child.return_value = True
|
||||||
mock_imgui.selectable.return_value = (False, False)
|
mock_imgui.selectable.return_value = (False, False)
|
||||||
mock_imgui.ListClipper.return_value.step.return_value = False
|
mock_imgui.ListClipper.return_value.step.return_value = False
|
||||||
mock_imgui.begin_tab_bar.return_value = True
|
mock_imgui.begin_tab_bar.return_value = True
|
||||||
|
|
||||||
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
||||||
mock_imscope.child.return_value.__enter__.return_value = True
|
mock_imscope.child.return_value.__enter__.return_value = True
|
||||||
mock_imscope.table.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.tree_node_ex.return_value.__enter__.return_value = True
|
||||||
mock_imscope.tab_item.return_value.__enter__.return_value = (True, 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_color.return_value.__enter__.return_value = None
|
||||||
mock_imscope.style_var.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):
|
def begin_tab_item_side_effect(label, p_open=None, flags=None):
|
||||||
if "main_take_1" in label:
|
if "main_take_1" in label:
|
||||||
return (True, True)
|
return (True, True)
|
||||||
return (False, 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
|
import pytest
|
||||||
from unittest.mock import patch, MagicMock, PropertyMock
|
from unittest.mock import patch, MagicMock, PropertyMock
|
||||||
|
|
||||||
from src import gui_2
|
from src import gui_2
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@@ -27,7 +26,7 @@ def test_discussion_tabs_rendered(mock_gui):
|
|||||||
patch('src.gui_2.imscope') as mock_imscope, \
|
patch('src.gui_2.imscope') as mock_imscope, \
|
||||||
patch('src.imgui_scopes.imgui', new=mock_imgui), \
|
patch('src.imgui_scopes.imgui', new=mock_imgui), \
|
||||||
patch('src.app_controller.AppController.active_project_root', new_callable=PropertyMock, return_value='.'):
|
patch('src.app_controller.AppController.active_project_root', new_callable=PropertyMock, return_value='.'):
|
||||||
|
|
||||||
# Setup imscope mocks
|
# Setup imscope mocks
|
||||||
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
||||||
mock_imscope.child.return_value.__enter__.return_value = 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
|
# We expect a combo box for base discussion
|
||||||
mock_imgui.begin_combo.return_value = True
|
mock_imgui.begin_combo.return_value = True
|
||||||
mock_imgui.selectable.return_value = (False, False)
|
mock_imgui.selectable.return_value = (False, False)
|
||||||
|
|
||||||
# We expect a tab bar for takes
|
# We expect a tab bar for takes
|
||||||
mock_imgui.begin_tab_bar.return_value = True
|
mock_imgui.begin_tab_bar.return_value = True
|
||||||
mock_imgui.begin_tab_item.return_value = (True, 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.input_text_multiline.return_value = (False, "")
|
||||||
mock_imgui.checkbox.return_value = (False, False)
|
mock_imgui.checkbox.return_value = (False, False)
|
||||||
mock_imgui.input_int.return_value = (False, 0)
|
mock_imgui.input_int.return_value = (False, 0)
|
||||||
|
|
||||||
mock_clipper = MagicMock()
|
mock_clipper = MagicMock()
|
||||||
mock_clipper.step.return_value = False
|
mock_clipper.step.return_value = False
|
||||||
mock_imgui.ListClipper.return_value = mock_clipper
|
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_combo.assert_called_once_with("##disc_sel", 'main')
|
||||||
mock_imgui.begin_tab_bar.assert_called_once_with('discussion_takes_tabs')
|
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]
|
calls = [c[0][0] for c in mock_imscope.tab_item.call_args_list]
|
||||||
assert 'Original###main' in calls
|
assert 'Original###main' in calls
|
||||||
assert 'Take 1###main_take_1' in calls
|
assert 'Take 1###main_take_1' in calls
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from unittest.mock import patch, MagicMock
|
from unittest.mock import patch, MagicMock
|
||||||
from src.gui_2 import App
|
from src.gui_2 import App
|
||||||
|
from src import gui_2
|
||||||
|
|
||||||
def test_render_context_composition_panel_fast(app_instance: App):
|
def test_render_context_composition_panel_fast(app_instance: App):
|
||||||
"""Verifies that the context composition panel rendering path executes without exceptions."""
|
"""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)
|
mock_imscope.tab_item.return_value.__enter__.return_value = (True, True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
app_instance._render_context_composition_panel()
|
gui_2.render_context_composition_panel(app_instance)
|
||||||
except Exception as e:
|
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):
|
def test_render_discussion_panel_fast(app_instance: App):
|
||||||
"""Verifies that the discussion panel rendering path executes without exceptions."""
|
"""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_imgui.ListClipper.return_value.step.return_value = False
|
||||||
mock_imscope.tab_item.return_value.__enter__.return_value = (True, True)
|
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:
|
try:
|
||||||
app_instance._render_discussion_panel()
|
gui_2.render_discussion_hub(app_instance)
|
||||||
except Exception as e:
|
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):
|
def test_render_files_and_media_fast(app_instance: App):
|
||||||
"""Verifies that the files and media panel rendering path executes without exceptions."""
|
"""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)
|
mock_imscope.tab_item.return_value.__enter__.return_value = (True, True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
app_instance._render_files_and_media()
|
gui_2.render_files_and_media(app_instance)
|
||||||
except Exception as e:
|
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
|
import pytest
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
from src import gui_2
|
||||||
from src.gui_2 import App
|
from src.gui_2 import App
|
||||||
from src.models import Track
|
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):
|
def test_track_discussion_toggle(mock_app: App):
|
||||||
with (
|
with (
|
||||||
patch('src.gui_2.imgui') as mock_imgui,
|
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.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.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]}),
|
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.begin_combo.return_value = False
|
||||||
mock_imgui.selectable.return_value = (False, False)
|
mock_imgui.selectable.return_value = (False, False)
|
||||||
mock_imgui.button.return_value = 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.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_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.input_int.side_effect = lambda label, value, *args, **kwargs: (False, value)
|
||||||
mock_imgui.begin_child.return_value = True
|
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 to avoid the while loop hang
|
||||||
mock_clipper = MagicMock()
|
mock_clipper = MagicMock()
|
||||||
mock_clipper.step.side_effect = [True, False]
|
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_clipper.display_end = 0
|
||||||
mock_imgui.ListClipper.return_value = mock_clipper
|
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
|
assert mock_app._track_discussion_active
|
||||||
mock_flush.assert_called()
|
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_imgui.checkbox.side_effect = checkbox_off_side_effect
|
||||||
mock_clipper.step.side_effect = [True, False] # Reset clipper
|
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
|
assert not mock_app._track_discussion_active
|
||||||
mock_switch.assert_called_with(mock_app.active_discussion)
|
mock_switch.assert_called_with(mock_app.active_discussion)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
from src import gui_2
|
||||||
from src.gui_2 import App, C_LBL, C_VAL
|
from src.gui_2 import App, C_LBL, C_VAL
|
||||||
from src.models import Ticket
|
from src.models import Ticket
|
||||||
|
|
||||||
@@ -60,16 +61,16 @@ def test_render_mma_dashboard_progress():
|
|||||||
|
|
||||||
# Call the method
|
# Call the method
|
||||||
# Dashboard now delegates to sub-methods, so we wire them up to execute their real logic on the mock instance.
|
# 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_focus_selector.side_effect = lambda: gui_2.render_mma_focus_selector(app)
|
||||||
app._render_mma_track_summary.side_effect = lambda: App._render_mma_track_summary(app)
|
app._render_mma_track_summary.side_effect = lambda: gui_2.render_mma_track_summary(app)
|
||||||
app._render_mma_epic_planner.side_effect = lambda: App._render_mma_epic_planner(app)
|
app._render_mma_epic_planner.side_effect = lambda: gui_2.render_mma_epic_planner(app)
|
||||||
app._render_mma_conductor_setup.side_effect = lambda: App._render_mma_conductor_setup(app)
|
app._render_mma_conductor_setup.side_effect = lambda: gui_2.render_mma_conductor_setup(app)
|
||||||
app._render_mma_track_browser.side_effect = lambda: App._render_mma_track_browser(app)
|
app._render_mma_track_browser.side_effect = lambda: gui_2.render_mma_track_browser(app)
|
||||||
app._render_mma_global_controls.side_effect = lambda: App._render_mma_global_controls(app)
|
app._render_mma_global_controls.side_effect = lambda: gui_2.render_mma_global_controls(app)
|
||||||
app._render_mma_usage_section.side_effect = lambda: App._render_mma_usage_section(app)
|
app._render_mma_usage_section.side_effect = lambda: gui_2.render_mma_usage_section(app)
|
||||||
app._render_mma_agent_streams.side_effect = lambda: App._render_mma_agent_streams(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
|
# Assertions
|
||||||
# 1 completed out of 4 tickets = 25.0% progress
|
# 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%')
|
# Update assertions: imgui.progress_bar is called with (0.25, (-1.0, 0.0), '25.0%')
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
from src import gui_2
|
||||||
from src.gui_2 import App
|
from src.gui_2 import App
|
||||||
|
|
||||||
@pytest.mark.parametrize("role", ["User", "AI"])
|
@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"
|
mock_mcp.read_file.return_value = "class MyClass:\n pass"
|
||||||
|
|
||||||
# Execute the panel rendering
|
# Execute the panel rendering
|
||||||
mock_app._render_discussion_panel()
|
gui_2.render_discussion_panel(mock_app)
|
||||||
|
|
||||||
# Assertions
|
# Assertions
|
||||||
# 1. Assert that the regex correctly identifies the pattern and imgui.button('[Source]##0_0') is called
|
# 1. Assert that the regex correctly identifies the pattern and imgui.button('[Source]##0_0') is called
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from unittest.mock import MagicMock, patch, ANY
|
from unittest.mock import MagicMock, patch, ANY
|
||||||
|
from src import gui_2
|
||||||
from src.gui_2 import App
|
from src.gui_2 import App
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@@ -35,7 +36,7 @@ def app_instance():
|
|||||||
yield app
|
yield app
|
||||||
|
|
||||||
def test_render_synthesis_panel(app_instance):
|
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, \
|
with patch('src.gui_2.imgui') as mock_imgui, \
|
||||||
patch('src.gui_2.imscope') as mock_imscope:
|
patch('src.gui_2.imscope') as mock_imscope:
|
||||||
mock_imgui.checkbox.return_value = (False, False)
|
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
|
mock_imscope.style_var.return_value.__enter__.return_value = None
|
||||||
|
|
||||||
# Call the method we are testing
|
# 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']
|
# 1. Assert imgui.checkbox is called for each take in project_dict['discussion']['discussions']
|
||||||
discussions = app_instance.project['discussion']['discussions']
|
discussions = app_instance.project['discussion']['discussions']
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from src import gui_2
|
||||||
# We can safely import gui_2 if we don't instantiate App without mocking its threads
|
|
||||||
from src.gui_2 import App
|
from src.gui_2 import App
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@@ -60,8 +59,8 @@ def test_log_management_init(app_instance: App) -> None:
|
|||||||
app = app_instance
|
app = app_instance
|
||||||
assert "Log Management" in app.show_windows
|
assert "Log Management" in app.show_windows
|
||||||
assert app.show_windows["Log Management"] is False
|
assert app.show_windows["Log Management"] is False
|
||||||
assert hasattr(app, "_render_log_management")
|
assert hasattr(gui_2, "render_log_management")
|
||||||
assert callable(app._render_log_management)
|
assert callable(gui_2.render_log_management)
|
||||||
|
|
||||||
def test_render_log_management_logic(app_instance: App) -> None:
|
def test_render_log_management_logic(app_instance: App) -> None:
|
||||||
app = app_instance
|
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_imscope.window.return_value = mock_window_cm
|
||||||
|
|
||||||
mock_begin_table.return_value = True
|
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_imscope.window.assert_called_with("Log Management", app.show_windows["Log Management"])
|
||||||
mock_begin_table.assert_called()
|
mock_begin_table.assert_called()
|
||||||
mock_text.assert_any_call("session_1")
|
mock_text.assert_any_call("session_1")
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from unittest.mock import patch, MagicMock
|
from unittest.mock import patch, MagicMock
|
||||||
|
|
||||||
|
from src import gui_2
|
||||||
from src.gui_2 import App
|
from src.gui_2 import App
|
||||||
|
|
||||||
|
|
||||||
@@ -63,18 +64,18 @@ def _make_app(**kwargs):
|
|||||||
app.controller = mock_controller
|
app.controller = mock_controller
|
||||||
|
|
||||||
# Ensure real methods are called for the dashboard rendering components
|
# Ensure real methods are called for the dashboard rendering components
|
||||||
app._render_mma_dashboard = lambda: App._render_mma_dashboard(app)
|
app._render_mma_dashboard = lambda: gui_2.render_mma_dashboard(app)
|
||||||
app._render_mma_focus_selector = lambda: App._render_mma_focus_selector(app)
|
app._render_mma_focus_selector = lambda: gui_2.render_mma_focus_selector(app)
|
||||||
app._render_mma_track_summary = lambda: App._render_mma_track_summary(app)
|
app._render_mma_track_summary = lambda: gui_2.render_mma_track_summary(app)
|
||||||
app._render_mma_epic_planner = lambda: App._render_mma_epic_planner(app)
|
app._render_mma_epic_planner = lambda: gui_2.render_mma_epic_planner(app)
|
||||||
app._render_mma_conductor_setup = lambda: App._render_mma_conductor_setup(app)
|
app._render_mma_conductor_setup = lambda: gui_2.render_mma_conductor_setup(app)
|
||||||
app._render_mma_track_browser = lambda: App._render_mma_track_browser(app)
|
app._render_mma_track_browser = lambda: gui_2.render_mma_track_browser(app)
|
||||||
app._render_mma_global_controls = lambda: App._render_mma_global_controls(app)
|
app._render_mma_global_controls = lambda: gui_2.render_mma_global_controls(app)
|
||||||
app._render_mma_usage_section = lambda: App._render_mma_usage_section(app)
|
app._render_mma_usage_section = lambda: gui_2.render_mma_usage_section(app)
|
||||||
app._render_ticket_queue = lambda: App._render_ticket_queue(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_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_ticket_editor = lambda: gui_2.render_mma_ticket_editor(app)
|
||||||
app._render_mma_agent_streams = lambda: App._render_mma_agent_streams(app)
|
app._render_mma_agent_streams = lambda: gui_2.render_mma_agent_streams(app)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
@@ -126,7 +127,7 @@ class TestMMAApprovalIndicators:
|
|||||||
mock_imscope.style_color.return_value.__enter__.return_value = None
|
mock_imscope.style_color.return_value.__enter__.return_value = None
|
||||||
mock_imscope.style_var.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)
|
combined = _collect_text_colored_args(imgui_mock)
|
||||||
assert "APPROVAL PENDING" not in combined, (
|
assert "APPROVAL PENDING" not in combined, (
|
||||||
"text_colored called with 'APPROVAL PENDING' when no approval is pending"
|
"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_imscope.style_var.return_value.__enter__.return_value = None
|
||||||
|
|
||||||
mock_math.sin.return_value = 0.8
|
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)
|
combined = _collect_text_colored_args(imgui_mock)
|
||||||
assert "APPROVAL PENDING" in combined, (
|
assert "APPROVAL PENDING" in combined, (
|
||||||
"text_colored not called with 'APPROVAL PENDING' when _pending_mma_spawn is set"
|
"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_imscope.style_var.return_value.__enter__.return_value = None
|
||||||
|
|
||||||
mock_math.sin.return_value = 0.8
|
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)
|
combined = _collect_text_colored_args(imgui_mock)
|
||||||
assert "APPROVAL PENDING" in combined, (
|
assert "APPROVAL PENDING" in combined, (
|
||||||
"text_colored not called with 'APPROVAL PENDING' when _pending_mma_approval is set"
|
"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_imscope.style_var.return_value.__enter__.return_value = None
|
||||||
|
|
||||||
mock_math.sin.return_value = 0.8
|
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)
|
combined = _collect_text_colored_args(imgui_mock)
|
||||||
assert "APPROVAL PENDING" in combined, (
|
assert "APPROVAL PENDING" in combined, (
|
||||||
"text_colored not called with 'APPROVAL PENDING' when _pending_ask_dialog is True"
|
"text_colored not called with 'APPROVAL PENDING' when _pending_ask_dialog is True"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from unittest.mock import patch, MagicMock
|
from unittest.mock import patch, MagicMock
|
||||||
|
|
||||||
|
from src import gui_2
|
||||||
from src.gui_2 import App
|
from src.gui_2 import App
|
||||||
|
|
||||||
|
|
||||||
@@ -64,7 +65,9 @@ class TestMMADashboardStreams:
|
|||||||
app = _make_app(mma_streams={"Tier 1": "hello"})
|
app = _make_app(mma_streams={"Tier 1": "hello"})
|
||||||
imgui_mock = _make_imgui_mock()
|
imgui_mock = _make_imgui_mock()
|
||||||
imgui_mock.begin_child.return_value = True
|
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
|
# Setup imscope mocks
|
||||||
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
||||||
mock_imscope.child.return_value.__enter__.return_value = 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_color.return_value.__enter__.return_value = None
|
||||||
mock_imscope.style_var.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):
|
def test_tier3_renders_worker_subheaders(self):
|
||||||
"""_render_tier_stream_panel for Tier 3 must render a sub-header for each worker stream key."""
|
"""_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 = _make_imgui_mock()
|
||||||
imgui_mock.begin_child.return_value = True
|
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
|
# Setup imscope mocks
|
||||||
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
mock_imscope.window.return_value.__enter__.return_value = (True, True)
|
||||||
mock_imscope.child.return_value.__enter__.return_value = 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_color.return_value.__enter__.return_value = None
|
||||||
mock_imscope.style_var.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)
|
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-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"
|
assert "T-002" in text_args, "imgui.text not called with 'T-002' worker sub-header"
|
||||||
@@ -1,42 +1,32 @@
|
|||||||
import pytest
|
import pytest
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
|
|
||||||
def test_session_hub_window_removed():
|
def test_session_hub_window_removed():
|
||||||
import src.gui_2 as gui_2
|
import src.gui_2 as gui_2
|
||||||
|
source = inspect.getsource(gui_2.render_main_interface)
|
||||||
source = inspect.getsource(gui_2.App._render_main_interface)
|
assert "Session Hub" not in source, "Session Hub window should be removed"
|
||||||
assert "Session Hub" not in source, "Session Hub window should be removed"
|
|
||||||
|
|
||||||
|
|
||||||
def test_discussion_hub_has_snapshot_tab():
|
def test_discussion_hub_has_snapshot_tab():
|
||||||
import src.gui_2 as gui_2
|
import src.gui_2 as gui_2
|
||||||
|
source = inspect.getsource(gui_2.render_discussion_hub)
|
||||||
source = inspect.getsource(gui_2.App._render_discussion_hub)
|
assert "Snapshot" in source, "Discussion Hub should have Snapshot tab"
|
||||||
assert "Snapshot" in source, "Discussion Hub should have Snapshot tab"
|
assert "render_snapshot_tab" in source, "Discussion Hub should call render_snapshot_tab"
|
||||||
assert "_render_snapshot_tab" in source, "Discussion Hub should call _render_snapshot_tab"
|
|
||||||
|
|
||||||
|
|
||||||
def test_discussion_hub_has_context_composition_placeholder():
|
def test_discussion_hub_has_context_composition_placeholder():
|
||||||
import src.gui_2 as gui_2
|
import src.gui_2 as gui_2
|
||||||
|
source = inspect.getsource(gui_2.render_discussion_hub)
|
||||||
source = inspect.getsource(gui_2.App._render_discussion_hub)
|
assert "Context Composition" in source, (
|
||||||
assert "Context Composition" in source, (
|
"Discussion Hub should have Context Composition tab placeholder"
|
||||||
"Discussion Hub should have Context Composition tab placeholder"
|
)
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_discussion_hub_has_takes_tab():
|
def test_discussion_hub_has_takes_tab():
|
||||||
import src.gui_2 as gui_2
|
import src.gui_2 as gui_2
|
||||||
|
source = inspect.getsource(gui_2.render_discussion_hub)
|
||||||
source = inspect.getsource(gui_2.App._render_discussion_hub)
|
assert "Takes" in source, "Discussion Hub should have Takes tab"
|
||||||
assert "Takes" in source, "Discussion Hub should have Takes tab"
|
|
||||||
|
|
||||||
|
|
||||||
def test_show_windows_no_session_hub():
|
def test_show_windows_no_session_hub():
|
||||||
import src.app_controller as app_controller
|
import src.app_controller as app_controller
|
||||||
|
source = inspect.getsource(app_controller.AppController)
|
||||||
source = inspect.getsource(app_controller.AppController)
|
assert "Session Hub" not in source, (
|
||||||
assert "Session Hub" not in source, (
|
"Session Hub should be removed from show_windows"
|
||||||
"Session Hub should be removed from show_windows"
|
)
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from unittest.mock import patch, MagicMock
|
from unittest.mock import patch, MagicMock
|
||||||
|
from src import gui_2
|
||||||
|
from src.gui_2 import App
|
||||||
|
|
||||||
def test_shader_live_editor_renders():
|
def test_shader_live_editor_renders():
|
||||||
from src.gui_2 import App
|
|
||||||
app = App()
|
app = App()
|
||||||
app.show_windows["Shader Editor"] = True
|
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_color.return_value.__enter__.return_value = None
|
||||||
mock_imscope.style_var.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
|
assert mock_imscope.window.called
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
import pytest
|
import pytest
|
||||||
import inspect
|
import inspect
|
||||||
|
from src import gui_2
|
||||||
|
|
||||||
def test_takes_tab_replaces_placeholder():
|
def test_takes_tab_replaces_placeholder():
|
||||||
import src.gui_2 as gui_2
|
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"
|
|
||||||
|
|
||||||
|
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():
|
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)
|
source = inspect.getsource(gui_2.render_takes_panel)
|
||||||
assert "synthesis" in source.lower(), "Should have synthesis functionality"
|
assert "synthesis" in source.lower(), "Should have synthesis functionality"
|
||||||
|
|||||||
Reference in New Issue
Block a user