refactor(tests): Update test suite and API hooks for AppController architecture
This commit is contained in:
@@ -88,7 +88,7 @@ def mock_app() -> Generator[App, None, None]:
|
||||
Mock version of the App for simple unit tests that don't need a loop.
|
||||
"""
|
||||
with (
|
||||
patch('gui_2.load_config', return_value={
|
||||
patch('src.models.load_config', return_value={
|
||||
'ai': {'provider': 'gemini', 'model': 'gemini-2.5-flash-lite'},
|
||||
'projects': {'paths': [], 'active': ''},
|
||||
'gui': {'show_windows': {}}
|
||||
@@ -97,16 +97,19 @@ def mock_app() -> Generator[App, None, None]:
|
||||
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.object(App, '_prune_old_logs'),
|
||||
patch.object(App, '_init_ai_and_hooks'),
|
||||
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('gui_2.PerformanceMonitor')
|
||||
):
|
||||
app = App()
|
||||
yield app
|
||||
if hasattr(app, 'controller'):
|
||||
app.controller.stop_services()
|
||||
if hasattr(app, 'shutdown'):
|
||||
app.shutdown()
|
||||
|
||||
@@ -117,7 +120,7 @@ def app_instance() -> Generator[App, None, None]:
|
||||
Matches the pattern used in test_token_viz.py and test_gui_phase4.py.
|
||||
"""
|
||||
with (
|
||||
patch('gui_2.load_config', return_value={
|
||||
patch('src.models.load_config', return_value={
|
||||
'ai': {'provider': 'gemini', 'model': 'gemini-2.5-flash-lite'},
|
||||
'projects': {'paths': [], 'active': ''},
|
||||
'gui': {'show_windows': {}}
|
||||
@@ -126,22 +129,28 @@ def app_instance() -> Generator[App, None, None]:
|
||||
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.object(App, '_prune_old_logs'),
|
||||
patch.object(App, '_init_ai_and_hooks'),
|
||||
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('gui_2.PerformanceMonitor')
|
||||
):
|
||||
app = App()
|
||||
yield app
|
||||
# Cleanup: Ensure background threads and asyncio loop are stopped
|
||||
if hasattr(app, 'controller'):
|
||||
app.controller.stop_services()
|
||||
|
||||
if hasattr(app, 'shutdown'):
|
||||
app.shutdown()
|
||||
|
||||
if hasattr(app, '_loop') and not app._loop.is_closed():
|
||||
tasks = [t for t in asyncio.all_tasks(app._loop) if not t.done()]
|
||||
# Use controller._loop for cleanup
|
||||
loop = getattr(app.controller, '_loop', None) if hasattr(app, 'controller') else None
|
||||
if loop and not loop.is_closed():
|
||||
tasks = [t for t in asyncio.all_tasks(loop) if not t.done()]
|
||||
if tasks:
|
||||
# Cancel tasks so they can be gathered
|
||||
for task in tasks:
|
||||
@@ -149,14 +158,14 @@ def app_instance() -> Generator[App, None, None]:
|
||||
# We can't really run the loop if it's already stopping or thread is dead,
|
||||
# but we try to be clean.
|
||||
try:
|
||||
if app._loop.is_running():
|
||||
app._loop.call_soon_threadsafe(app._loop.stop)
|
||||
if loop.is_running():
|
||||
loop.call_soon_threadsafe(loop.stop)
|
||||
except: pass
|
||||
|
||||
# Finally close the loop if we can
|
||||
try:
|
||||
if not app._loop.is_running():
|
||||
app._loop.close()
|
||||
if not loop.is_running():
|
||||
loop.close()
|
||||
except: pass
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
|
||||
Reference in New Issue
Block a user