Botched: Need to do a higher reaosning model to fix this mess.

This commit is contained in:
2026-03-04 12:32:14 -05:00
parent 8d3fdb53d0
commit 01b3c26653
18 changed files with 180 additions and 132 deletions

View File

@@ -189,6 +189,11 @@ def live_gui() -> Generator[tuple[subprocess.Popen, str], None, None]:
(temp_workspace / "manual_slop.toml").write_text("[project]\nname = 'TestProject'\n", encoding="utf-8")
(temp_workspace / "conductor" / "tracks").mkdir(parents=True, exist_ok=True)
# Resolve absolute paths for shared resources
project_root = Path(os.getcwd())
cred_file = project_root / "credentials.toml"
mcp_file = project_root / "mcp_env.toml"
# Preserve GUI layout for tests
layout_file = Path("manualslop_layout.ini")
if layout_file.exists():
@@ -209,7 +214,11 @@ def live_gui() -> Generator[tuple[subprocess.Popen, str], None, None]:
# Use environment variable to point to temp config if App supports it,
# or just run from that CWD.
env = os.environ.copy()
env["PYTHONPATH"] = os.getcwd()
env["PYTHONPATH"] = str(project_root.absolute())
if cred_file.exists():
env["SLOP_CREDENTIALS"] = str(cred_file.absolute())
if mcp_file.exists():
env["SLOP_MCP_ENV"] = str(mcp_file.absolute())
process = subprocess.Popen(
["uv", "run", "python", "-u", gui_script, "--enable-test-hooks"],

View File

@@ -34,11 +34,11 @@ def test_get_indicator_state_integration(live_gui: Any) -> None:
def test_app_processes_new_actions() -> None:
import gui_2
with patch('gui_2.load_config', return_value={}), \
with patch('src.models.load_config', return_value={}), \
patch('gui_2.PerformanceMonitor'), \
patch('gui_2.session_logger'), \
patch.object(gui_2.App, '_prune_old_logs'), \
patch.object(gui_2.App, '_load_active_project'):
patch('src.app_controller.AppController._prune_old_logs'), \
patch('src.app_controller.AppController._load_active_project'):
app = gui_2.App()
# Test set_value via _pending_gui_tasks
# First we need to register a settable field for testing if not present

View File

@@ -8,19 +8,19 @@ from events import EventEmitter
@pytest.fixture
def app_instance() -> Generator[type[App], None, None]:
"""
Fixture to create an instance of the gui_2.App class for testing.
It mocks functions that would render a window or block execution.
"""
Fixture to create an instance of the gui_2.App class for testing.
It mocks functions that would render a window or block execution.
"""
if not hasattr(ai_client, 'events') or ai_client.events is None:
ai_client.events = EventEmitter()
with (
patch('gui_2.load_config', return_value={'ai': {}, 'projects': {}}),
patch('src.models.load_config', return_value={'ai': {}, 'projects': {}}),
patch('gui_2.save_config'),
patch('gui_2.project_manager'),
patch('gui_2.session_logger'),
patch('gui_2.immapp.run'),
patch.object(App, '_load_active_project'),
patch.object(App, '_fetch_models'),
patch('src.app_controller.AppController._load_active_project'),
patch('src.app_controller.AppController._fetch_models'),
patch.object(App, '_load_fonts'),
patch.object(App, '_post_init')
):
@@ -43,4 +43,4 @@ def test_app_subscribes_to_events(app_instance: type[App]) -> None:
for call in calls:
handler = call.args[1]
assert hasattr(handler, '__self__')
assert handler.__self__ is app
assert handler.__self__ is app.controller

View File

@@ -9,7 +9,7 @@ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "s
def test_gui_updates_on_event(app_instance: App) -> None:
app_instance.last_md = "mock_md"
with patch.object(app_instance, '_refresh_api_metrics') as mock_refresh:
with patch.object(app_instance.controller, '_refresh_api_metrics') as mock_refresh:
# Simulate event (bypassing events.emit since _init_ai_and_hooks is mocked)
app_instance._on_api_event(payload={"text": "test"})
# Process tasks manually

View File

@@ -9,10 +9,15 @@ from fastapi.testclient import TestClient
class TestHeadlessAPI(unittest.TestCase):
def setUp(self) -> None:
with patch('gui_2.session_logger.open_session'), \
with patch('src.models.load_config', return_value={'ai': {'provider': 'gemini', 'model': 'gemini-2.5-flash-lite'}, 'projects': {}, 'gui': {'show_windows': {}}}), \
patch('gui_2.session_logger.open_session'), \
patch('gui_2.ai_client.set_provider'), \
patch('gui_2.PerformanceMonitor'), \
patch('gui_2.session_logger.close_session'):
patch('gui_2.session_logger.close_session'), \
patch('src.app_controller.AppController._init_ai_and_hooks'), \
patch('src.app_controller.AppController._fetch_models'), \
patch('src.app_controller.AppController._prune_old_logs'), \
patch('src.app_controller.AppController.start_services'):
self.app_instance = gui_2.App()
# Set a default API key for tests
self.test_api_key = "test-secret-key"

View File

@@ -41,7 +41,11 @@ def test_old_windows_removed_from_gui2(app_instance_simple: Any) -> None:
def app_instance_simple() -> Any:
from unittest.mock import patch
from gui_2 import App
with patch('gui_2.load_config', return_value={}):
with patch('src.models.load_config', return_value={'ai': {}, 'projects': {}, 'gui': {'show_windows': {}}}), \
patch('src.app_controller.AppController._init_ai_and_hooks'), \
patch('src.app_controller.AppController._fetch_models'), \
patch('src.app_controller.AppController._prune_old_logs'), \
patch('src.app_controller.AppController.start_services'):
app = App()
return app

View File

@@ -7,15 +7,18 @@ from gui_2 import App
def app_instance() -> Any:
# We patch the dependencies of App.__init__ to avoid side effects
with (
patch('gui_2.load_config', return_value={'ai': {}, 'projects': {}}),
patch('src.models.load_config', return_value={'ai': {}, 'projects': {}}),
patch('gui_2.save_config'),
patch('gui_2.project_manager') as mock_pm,
patch('gui_2.session_logger'),
patch('gui_2.immapp.run'),
patch.object(App, '_load_active_project'),
patch.object(App, '_fetch_models'),
patch('src.app_controller.AppController._load_active_project'),
patch('src.app_controller.AppController._fetch_models'),
patch.object(App, '_load_fonts'),
patch.object(App, '_post_init')
patch.object(App, '_post_init'),
patch('src.app_controller.AppController._prune_old_logs'),
patch('src.app_controller.AppController.start_services'),
patch('src.app_controller.AppController._init_ai_and_hooks')
):
app = App()
# Ensure project and ui_files_base_dir are set for _refresh_from_project

View File

@@ -7,15 +7,18 @@ from gui_2 import App
@pytest.fixture
def app_instance() -> Generator[App, None, None]:
with (
patch('gui_2.load_config', return_value={'ai': {'provider': 'gemini', 'model': 'gemini-2.5-flash-lite'}, 'projects': {}}),
patch('src.models.load_config', return_value={'ai': {'provider': 'gemini', 'model': 'gemini-2.5-flash-lite'}, 'projects': {}}),
patch('gui_2.save_config'),
patch('gui_2.project_manager'),
patch('gui_2.session_logger'),
patch('gui_2.immapp.run'),
patch.object(App, '_load_active_project'),
patch.object(App, '_fetch_models'),
patch('src.app_controller.AppController._load_active_project'),
patch('src.app_controller.AppController._fetch_models'),
patch.object(App, '_load_fonts'),
patch.object(App, '_post_init'),
patch('src.app_controller.AppController._prune_old_logs'),
patch('src.app_controller.AppController.start_services'),
patch('src.app_controller.AppController._init_ai_and_hooks'),
patch('ai_client.set_provider'),
patch('ai_client.reset_session')
):