From c52e4612aef6d031d3afc90de217ef6269142b41 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sat, 16 May 2026 11:22:41 -0400 Subject: [PATCH] fix(tests): Update tests and HotReloader to accommodate gui_2 refactoring --- src/gui_2.py | 6 +- src/hot_reloader.py | 2 - tests/test_auto_slices.py | 6 +- tests/test_context_composition_panel.py | 12 ++-- tests/test_context_presets.py | 42 +++++------ tests/test_ui_summary_only_removal.py | 96 ++++++++++++------------- 6 files changed, 81 insertions(+), 83 deletions(-) diff --git a/src/gui_2.py b/src/gui_2.py index 50a581ce..7519a7c6 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -131,9 +131,8 @@ class App: self.workspace_profiles = self.workspace_manager.load_all_profiles() self.controller.start_services(self) # --- Controller Callbacks & Actions --- - self.controller._predefined_callbacks['_render_text_viewer'] = self._render_text_viewer - self.controller._predefined_callbacks['save_context_preset'] = self.save_context_preset - self.controller._predefined_callbacks['load_context_preset'] = self.load_context_preset + self.controller._predefined_callbacks['save_context_preset'] = self.controller.save_context_preset + self.controller._predefined_callbacks['load_context_preset'] = self.controller.load_context_preset self.controller._predefined_callbacks['set_ui_file_paths'] = lambda p: setattr(self, 'ui_file_paths', p) self.controller._predefined_callbacks['set_ui_screenshot_paths'] = lambda p: setattr(self, 'ui_screenshot_paths', p) self.controller._predefined_callbacks['simulate_save_preset'] = self._simulate_save_preset @@ -266,7 +265,6 @@ class App: self.context_files = [item] self.screenshots = ['test.png'] self.save_context_preset(name) - def _handle_approve_ask(self) -> None: """UI-level wrapper for approving a pending tool execution ask.""" self.controller._handle_approve_ask() diff --git a/src/hot_reloader.py b/src/hot_reloader.py index c761eeb0..8adc93d3 100644 --- a/src/hot_reloader.py +++ b/src/hot_reloader.py @@ -18,8 +18,6 @@ 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 diff --git a/tests/test_auto_slices.py b/tests/test_auto_slices.py index 860b9d3e..d75ff319 100644 --- a/tests/test_auto_slices.py +++ b/tests/test_auto_slices.py @@ -66,7 +66,8 @@ def test_add_selected_triggers_auto_slices(mock_app): mock_imscope.window.return_value.__enter__.return_value = (True, True) with patch.object(mock_app, '_populate_auto_slices') as mock_populate: - mock_app._render_add_context_files_modal() + import src.gui_2 + src.gui_2.render_add_context_files_modal(mock_app) assert mock_populate.called assert len(mock_app.context_files) == 1 @@ -99,7 +100,8 @@ def test_add_all_triggers_auto_slices(mock_app): mock_imscope.window.return_value.__enter__.return_value = (True, True) with patch.object(mock_app, '_populate_auto_slices') as mock_populate: - mock_app._render_context_composition_panel() + import src.gui_2 + src.gui_2.render_context_composition_panel(mock_app) assert mock_populate.called assert len(mock_app.context_files) == 1 diff --git a/tests/test_context_composition_panel.py b/tests/test_context_composition_panel.py index cdf8667b..97544356 100644 --- a/tests/test_context_composition_panel.py +++ b/tests/test_context_composition_panel.py @@ -5,19 +5,19 @@ import inspect def test_context_composition_panel_replaces_placeholder(): import src.gui_2 as gui_2 - source = inspect.getsource(gui_2.App._render_discussion_hub) + source = inspect.getsource(gui_2.render_discussion_hub) assert "_render_context_composition_placeholder" not in source, ( "Placeholder should be replaced" ) - assert "_render_context_composition_panel" in source, ( - "Should have _render_context_composition_panel" + assert "render_context_composition_panel" in source, ( + "Should have render_context_composition_panel" ) def test_context_composition_has_save_load_buttons(): import src.gui_2 as gui_2 - source = inspect.getsource(gui_2.App._render_context_presets) + source = inspect.getsource(gui_2.render_context_presets) assert "Save##ctx" in source or "save" in source.lower(), ( "Should have Save functionality" ) @@ -29,14 +29,14 @@ def test_context_composition_has_save_load_buttons(): def test_context_composition_shows_files(): import src.gui_2 as gui_2 - source = inspect.getsource(gui_2.App._render_context_composition_panel) + source = inspect.getsource(gui_2.render_context_composition_panel) assert "files" in source.lower() or "Files" in source, "Should show files" def test_context_composition_has_preset_list(): import src.gui_2 as gui_2 - source = inspect.getsource(gui_2.App._render_context_composition_panel) + source = inspect.getsource(gui_2.render_context_composition_panel) assert "context_presets" in source or "preset" in source.lower(), ( "Should reference presets" ) diff --git a/tests/test_context_presets.py b/tests/test_context_presets.py index 23bdbb6b..e38bcdbf 100644 --- a/tests/test_context_presets.py +++ b/tests/test_context_presets.py @@ -1,59 +1,59 @@ import pytest -from src.project_manager import ( - save_context_preset, - load_context_preset, - delete_context_preset -) +from src.context_presets import ContextPresetManager +from src.models import ContextPreset, ContextFileEntry def test_save_context_preset(): + manager = ContextPresetManager() project_dict = {} preset_name = "test_preset" - files = ["file1.py", "file2.py"] + files = [ContextFileEntry(path="file1.py"), ContextFileEntry(path="file2.py")] screenshots = ["screenshot1.png"] - save_context_preset(project_dict, preset_name, files, screenshots) + preset = ContextPreset(name=preset_name, files=files, screenshots=screenshots) + manager.save_preset(project_dict, preset) assert "context_presets" in project_dict assert preset_name in project_dict["context_presets"] - assert project_dict["context_presets"][preset_name]["files"] == files + assert project_dict["context_presets"][preset_name]["files"] == [f.to_dict() for f in files] assert project_dict["context_presets"][preset_name]["screenshots"] == screenshots -def test_load_context_preset(): +def test_load_all_context_presets(): + manager = ContextPresetManager() project_dict = { "context_presets": { "test_preset": { - "files": ["file1.py"], + "name": "test_preset", + "files": [{"path": "file1.py", "view_mode": "summary", "custom_slices": []}], "screenshots": ["screenshot1.png"] } } } - preset = load_context_preset(project_dict, "test_preset") + presets = manager.load_all(project_dict) - assert preset["files"] == ["file1.py"] - assert preset["screenshots"] == ["screenshot1.png"] - -def test_load_nonexistent_preset(): - project_dict = {"context_presets": {}} - with pytest.raises(KeyError): - load_context_preset(project_dict, "nonexistent") + assert "test_preset" in presets + assert presets["test_preset"].files[0].path == "file1.py" + assert presets["test_preset"].screenshots == ["screenshot1.png"] def test_delete_context_preset(): + manager = ContextPresetManager() project_dict = { "context_presets": { "test_preset": { - "files": ["file1.py"], + "name": "test_preset", + "files": [{"path": "file1.py", "view_mode": "summary", "custom_slices": []}], "screenshots": [] } } } - delete_context_preset(project_dict, "test_preset") + manager.delete_preset(project_dict, "test_preset") assert "test_preset" not in project_dict["context_presets"] def test_delete_nonexistent_preset_no_error(): + manager = ContextPresetManager() project_dict = {"context_presets": {}} # Should not raise error if it doesn't exist - delete_context_preset(project_dict, "nonexistent") + manager.delete_preset(project_dict, "nonexistent") assert "nonexistent" not in project_dict["context_presets"] diff --git a/tests/test_ui_summary_only_removal.py b/tests/test_ui_summary_only_removal.py index e821c9d4..3abf3f66 100644 --- a/tests/test_ui_summary_only_removal.py +++ b/tests/test_ui_summary_only_removal.py @@ -4,72 +4,72 @@ from src import models def test_ui_summary_only_not_in_projects_panel(): - import src.gui_2 as gui_2 + import src.gui_2 as gui_2 - source = inspect.getsource(gui_2.App._render_projects_panel) - assert "ui_summary_only" not in source, ( - "ui_summary_only checkbox should be removed from Projects panel" - ) - assert "Summary Only" not in source, ( - "Summary Only label should be removed from Projects panel" - ) + source = inspect.getsource(gui_2.render_projects_panel) + assert "ui_summary_only" not in source, ( + "ui_summary_only checkbox should be removed from Projects panel" + ) + assert "Summary Only" not in source, ( + "Summary Only label should be removed from Projects panel" + ) def test_ui_summary_only_not_in_app_controller_projects(): - import src.app_controller as app_controller + import src.app_controller as app_controller - source = inspect.getsource(app_controller.AppController) - assert "ui_summary_only" not in source, ( - "ui_summary_only should be removed from AppController" - ) + source = inspect.getsource(app_controller.AppController) + assert "ui_summary_only" not in source, ( + "ui_summary_only should be removed from AppController" + ) def test_file_item_has_per_file_flags(): - item = models.FileItem(path="test.py") - assert hasattr(item, "auto_aggregate") - assert hasattr(item, "force_full") - assert item.auto_aggregate is True - assert item.force_full is False + item = models.FileItem(path="test.py") + assert hasattr(item, "auto_aggregate") + assert hasattr(item, "force_full") + assert item.auto_aggregate is True + assert item.force_full is False def test_file_item_serialization_with_flags(): - item = models.FileItem(path="test.py", auto_aggregate=False, force_full=True) - data = item.to_dict() + item = models.FileItem(path="test.py", auto_aggregate=False, force_full=True) + data = item.to_dict() - assert data["auto_aggregate"] is False - assert data["force_full"] is True + assert data["auto_aggregate"] is False + assert data["force_full"] is True - restored = models.FileItem.from_dict(data) - assert restored.auto_aggregate is False - assert restored.force_full is True + restored = models.FileItem.from_dict(data) + assert restored.auto_aggregate is False + assert restored.force_full is True def test_project_without_summary_only_loads(): - proj = {"project": {"name": "test", "paths": []}} - assert proj.get("project", {}).get("summary_only") is None + proj = {"project": {"name": "test", "paths": []}} + assert proj.get("project", {}).get("summary_only") is None def test_aggregate_from_items_respects_auto_aggregate(): - from pathlib import Path - from src import aggregate + from pathlib import Path + from src import aggregate - items = [ - { - "path": Path("file1.py"), - "entry": "file1.py", - "content": "print('hello')", - "auto_aggregate": True, - "force_full": False, - }, - { - "path": Path("file2.py"), - "entry": "file2.py", - "content": "print('world')", - "auto_aggregate": False, - "force_full": False, - }, - ] + items = [ + { + "path": Path("file1.py"), + "entry": "file1.py", + "content": "print('hello')", + "auto_aggregate": True, + "force_full": False, + }, + { + "path": Path("file2.py"), + "entry": "file2.py", + "content": "print('world')", + "auto_aggregate": False, + "force_full": False, + }, + ] - result = aggregate._build_files_section_from_items(items) - assert "file1.py" in result - assert "file2.py" not in result + result = aggregate._build_files_section_from_items(items) + assert "file1.py" in result + assert "file2.py" not in result