refactor(tests): Add strict type hints to third batch of test files

This commit is contained in:
2026-02-28 19:16:19 -05:00
parent 579ee8394f
commit e8513d563b
10 changed files with 37 additions and 29 deletions

View File

@@ -1,6 +1,7 @@
import pytest
import sys
import os
from typing import Any
# Ensure project root is in path for imports
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
@@ -13,20 +14,20 @@ def test_api_client_has_extensions() -> None:
assert hasattr(client, 'select_tab')
assert hasattr(client, 'select_list_item')
def test_select_tab_integration(live_gui):
def test_select_tab_integration(live_gui: Any) -> None:
client = ApiHookClient()
# We'll need to make sure the tags exist in gui_legacy.py
# For now, this is a placeholder for the integration test
response = client.select_tab("operations_tabs", "tab_tool")
assert response == {'status': 'queued'}
def test_select_list_item_integration(live_gui):
def test_select_list_item_integration(live_gui: Any) -> None:
client = ApiHookClient()
# Assuming 'Default' discussion exists or we can just test that it queues
response = client.select_list_item("disc_listbox", "Default")
assert response == {'status': 'queued'}
def test_get_indicator_state_integration(live_gui):
def test_get_indicator_state_integration(live_gui: Any) -> None:
client = ApiHookClient()
# thinking_indicator is usually hidden unless AI is running
response = client.get_indicator_state("thinking_indicator")

View File

@@ -6,13 +6,14 @@ import time
import json
import requests
import sys
from typing import Any
# Ensure project root is in path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from api_hook_client import ApiHookClient
def simulate_conductor_phase_completion(client: ApiHookClient):
def simulate_conductor_phase_completion(client: ApiHookClient) -> dict[str, Any]:
"""
Simulates the Conductor agent's logic for phase completion using ApiHookClient.
"""
@@ -33,7 +34,7 @@ def simulate_conductor_phase_completion(client: ApiHookClient):
results["verification_message"] = f"Automated verification failed: {e}"
return results
def test_conductor_integrates_api_hook_client_for_verification(live_gui):
def test_conductor_integrates_api_hook_client_for_verification(live_gui: Any) -> None:
"""
Verify that Conductor's simulated phase completion logic properly integrates
and uses the ApiHookClient for verification against the live GUI.
@@ -43,7 +44,7 @@ def test_conductor_integrates_api_hook_client_for_verification(live_gui):
assert results["verification_successful"] is True
assert "successfully" in results["verification_message"]
def test_conductor_handles_api_hook_failure(live_gui):
def test_conductor_handles_api_hook_failure(live_gui: Any) -> None:
"""
Verify Conductor handles a simulated API hook verification failure.
We patch the client's get_status to simulate failure even with live GUI.

View File

@@ -4,9 +4,10 @@ import os
import sys
import requests
import json
from typing import Any
from api_hook_client import ApiHookClient
def test_gemini_cli_context_bleed_prevention(live_gui):
def test_gemini_cli_context_bleed_prevention(live_gui: Any) -> None:
"""
Test that the GeminiCliAdapter correctly filters out echoed 'user' messages
and only shows assistant content in the GUI history.
@@ -39,7 +40,7 @@ print(json.dumps({"type": "result", "stats": {"total_tokens": 10}}), flush=True)
assert "echoing you" not in ai_entries[0].get("content")
os.remove(bleed_mock)
def test_gemini_cli_parameter_resilience(live_gui):
def test_gemini_cli_parameter_resilience(live_gui: Any) -> None:
"""
Test that mcp_client correctly handles 'file_path' and 'dir_path' aliases
sent by the AI instead of 'path'.
@@ -106,7 +107,7 @@ else:
assert found, "Tool result indicating success not found in history"
os.remove(alias_mock)
def test_gemini_cli_loop_termination(live_gui):
def test_gemini_cli_loop_termination(live_gui: Any) -> None:
"""
Test that multi-round tool calling correctly terminates and preserves
payload (session context) between rounds.

View File

@@ -2,6 +2,7 @@ import pytest
from unittest.mock import patch, MagicMock
import sys
import os
from typing import Any
# Add project root to sys.path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
@@ -19,7 +20,7 @@ def setup_ai_client() -> None:
@patch('ai_client.GeminiCliAdapter')
@patch('ai_client._get_combined_system_prompt')
def test_send_invokes_adapter_send(mock_prompt, mock_adapter_class):
def test_send_invokes_adapter_send(mock_prompt: Any, mock_adapter_class: Any) -> None:
mock_prompt.return_value = "Mocked Prompt"
mock_instance = mock_adapter_class.return_value
mock_instance.send.return_value = {"text": "Done", "tool_calls": []}
@@ -34,7 +35,7 @@ def test_send_invokes_adapter_send(mock_prompt, mock_adapter_class):
assert kwargs['system_instruction'] == "Mocked Prompt\n\n<context>\ncontext\n</context>"
@patch('ai_client.GeminiCliAdapter')
def test_get_history_bleed_stats(mock_adapter_class):
def test_get_history_bleed_stats(mock_adapter_class: Any) -> None:
mock_instance = mock_adapter_class.return_value
mock_instance.send.return_value = {"text": "txt", "tool_calls": []}
mock_instance.last_usage = {"input_tokens": 1500}

View File

@@ -2,6 +2,7 @@ import pytest
from unittest.mock import patch, MagicMock
import importlib.util
import sys
from typing import Any
import dearpygui.dearpygui as dpg
# Load gui.py as a module for testing
@@ -29,14 +30,13 @@ def app_instance() -> None:
yield app
dpg.destroy_context()
def test_diagnostics_panel_initialization(app_instance):
def test_diagnostics_panel_initialization(app_instance: Any) -> None:
assert "Diagnostics" in app_instance.window_info
assert app_instance.window_info["Diagnostics"] == "win_diagnostics"
assert "frame_time" in app_instance.perf_history
assert len(app_instance.perf_history["frame_time"]) == 100
def test_diagnostics_panel_updates(app_instance):
# Mock dependencies
def test_diagnostics_panel_updates(app_instance: Any) -> None:
mock_metrics = {
'last_frame_time_ms': 10.0,
'fps': 100.0,

View File

@@ -3,6 +3,7 @@ from unittest.mock import patch, MagicMock
import importlib.util
import sys
import os
from typing import Any
import dearpygui.dearpygui as dpg
# Ensure project root is in path for imports
@@ -40,7 +41,7 @@ def app_instance() -> None:
yield app
dpg.destroy_context()
def test_telemetry_panel_updates_correctly(app_instance):
def test_telemetry_panel_updates_correctly(app_instance: Any) -> None:
"""
Tests that the _update_performance_diagnostics method correctly updates
DPG widgets based on the stats from ai_client.
@@ -71,7 +72,7 @@ def test_telemetry_panel_updates_correctly(app_instance):
# Assert Gemini-specific widget was hidden
mock_configure_item.assert_any_call("gemini_cache_label", show=False)
def test_cache_data_display_updates_correctly(app_instance):
def test_cache_data_display_updates_correctly(app_instance: Any) -> None:
"""
Tests that the _update_performance_diagnostics method correctly updates the
GUI with Gemini cache statistics when the provider is set to Gemini.

View File

@@ -1,6 +1,7 @@
import os
import shutil
import pytest
from typing import Any
from pathlib import Path
from datetime import datetime, timedelta
from unittest.mock import patch
@@ -10,7 +11,7 @@ from log_registry import LogRegistry
from log_pruner import LogPruner
@pytest.fixture
def e2e_setup(tmp_path, monkeypatch):
def e2e_setup(tmp_path: Path, monkeypatch: Any) -> Any:
# Ensure closed before starting
session_logger.close_session()
monkeypatch.setattr(session_logger, "_comms_fh", None)
@@ -29,7 +30,7 @@ def e2e_setup(tmp_path, monkeypatch):
session_logger._LOG_DIR = original_log_dir
session_logger._SCRIPTS_DIR = original_scripts_dir
def test_logging_e2e(e2e_setup):
def test_logging_e2e(e2e_setup: Any) -> None:
tmp_path = e2e_setup
logs_dir = tmp_path / "logs"
# Step 1: Initialize (open_session)

View File

@@ -1,9 +1,10 @@
import pytest
from unittest.mock import patch, MagicMock
from typing import Any
from gui_2 import App
@pytest.fixture
def app_instance():
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': {}}),
@@ -23,7 +24,7 @@ def app_instance():
# Return the app and the mock_pm for use in tests
yield app, mock_pm
def test_mma_dashboard_refresh(app_instance):
def test_mma_dashboard_refresh(app_instance: Any) -> None:
app, mock_pm = app_instance
# 1. Define mock tracks
mock_tracks = [
@@ -43,7 +44,7 @@ def test_mma_dashboard_refresh(app_instance):
# Verify get_all_tracks was called with the correct base_dir
mock_pm.get_all_tracks.assert_called_with(app.ui_files_base_dir)
def test_mma_dashboard_initialization_refresh(app_instance):
def test_mma_dashboard_initialization_refresh(app_instance: Any) -> None:
"""
Checks that _refresh_from_project is called during initialization if
_load_active_project is NOT mocked to skip it (but here it IS mocked in fixture).

View File

@@ -1,17 +1,18 @@
import pytest
from unittest.mock import MagicMock, patch
import json
from typing import Any
import orchestrator_pm
import conductor_tech_lead
import multi_agent_conductor
from models import Track, Ticket
@pytest.fixture
def mock_ai_client() -> None:
def mock_ai_client() -> Any:
with patch("ai_client.send") as mock_send:
yield mock_send
def test_generate_tracks(mock_ai_client):
def test_generate_tracks(mock_ai_client: Any) -> None:
# Tier 1 (PM) response mock
mock_ai_client.return_value = json.dumps([
{"id": "track_1", "title": "Infrastructure Setup", "description": "Setup basic project structure"},
@@ -26,8 +27,7 @@ def test_generate_tracks(mock_ai_client):
assert tracks[1]["id"] == "track_2"
mock_ai_client.assert_called_once()
def test_generate_tickets(mock_ai_client):
# Tier 2 (Tech Lead) response mock
def test_generate_tickets(mock_ai_client: Any) -> None:
mock_ai_client.return_value = json.dumps([
{"id": "T-001", "description": "Define interfaces", "depends_on": []},
{"id": "T-002", "description": "Implement interfaces", "depends_on": ["T-001"]}
@@ -102,7 +102,7 @@ def test_conductor_engine_parse_json_tickets() -> None:
assert track.tickets[1].id == "T2"
assert track.tickets[1].depends_on == ["T1"]
def test_run_worker_lifecycle_blocked(mock_ai_client):
def test_run_worker_lifecycle_blocked(mock_ai_client: Any) -> None:
ticket = Ticket(id="T1", description="desc", status="todo", assigned_to="user")
context = multi_agent_conductor.WorkerContext(ticket_id="T1", model_name="model", messages=[])
mock_ai_client.return_value = "BLOCKED because of missing info"