refactor(tests): Add strict type hints to fourth batch of test files
This commit is contained in:
@@ -18,7 +18,7 @@ class TestCliToolBridgeMapping(unittest.TestCase):
|
||||
@patch('sys.stdin', new_callable=io.StringIO)
|
||||
@patch('sys.stdout', new_callable=io.StringIO)
|
||||
@patch('api_hook_client.ApiHookClient.request_confirmation')
|
||||
def test_mapping_from_api_format(self, mock_request, mock_stdout, mock_stdin):
|
||||
def test_mapping_from_api_format(self, mock_request: MagicMock, mock_stdout: MagicMock, mock_stdin: MagicMock) -> None:
|
||||
"""
|
||||
Verify that bridge correctly maps 'id', 'name', 'input' (Gemini API format)
|
||||
into tool_name and tool_input for the hook client.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from typing import Any
|
||||
import pytest
|
||||
import os
|
||||
import tomllib
|
||||
@@ -11,7 +12,7 @@ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
||||
import ai_client
|
||||
import project_manager
|
||||
|
||||
def test_credentials_error_mentions_deepseek(monkeypatch):
|
||||
def test_credentials_error_mentions_deepseek(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""
|
||||
Verify that the error message shown when credentials.toml is missing
|
||||
includes deepseek instructions.
|
||||
@@ -48,7 +49,7 @@ def test_deepseek_model_listing() -> None:
|
||||
assert "deepseek-chat" in models
|
||||
assert "deepseek-reasoner" in models
|
||||
|
||||
def test_gui_provider_list_via_hooks(live_gui):
|
||||
def test_gui_provider_list_via_hooks(live_gui: Any) -> None:
|
||||
"""
|
||||
Verify 'deepseek' is present in the GUI provider list using API hooks.
|
||||
"""
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from typing import Any
|
||||
import pytest
|
||||
import time
|
||||
import os
|
||||
@@ -5,7 +6,7 @@ import sys
|
||||
import requests
|
||||
from api_hook_client import ApiHookClient
|
||||
|
||||
def test_gemini_cli_full_integration(live_gui):
|
||||
def test_gemini_cli_full_integration(live_gui: Any) -> None:
|
||||
"""
|
||||
Integration test for the Gemini CLI provider and tool bridge.
|
||||
Handles 'ask_received' events from the bridge and any other approval requests.
|
||||
@@ -70,7 +71,7 @@ def test_gemini_cli_full_integration(live_gui):
|
||||
assert approved_count > 0, "No approval events were processed"
|
||||
assert found_final, "Final message from mock CLI was not found in the GUI history"
|
||||
|
||||
def test_gemini_cli_rejection_and_history(live_gui):
|
||||
def test_gemini_cli_rejection_and_history(live_gui: Any) -> None:
|
||||
"""
|
||||
Integration test for the Gemini CLI provider: Rejection flow and history.
|
||||
"""
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from typing import Generator
|
||||
import pytest
|
||||
from unittest.mock import patch
|
||||
from gui_2 import App
|
||||
|
||||
@pytest.fixture
|
||||
def app_instance() -> None:
|
||||
def app_instance() -> Generator[App, None, None]:
|
||||
with (
|
||||
patch('gui_2.load_config', return_value={'gui': {'show_windows': {}}}),
|
||||
patch('gui_2.save_config'),
|
||||
@@ -17,7 +18,7 @@ def app_instance() -> None:
|
||||
):
|
||||
yield App()
|
||||
|
||||
def test_gui2_hubs_exist_in_show_windows(app_instance):
|
||||
def test_gui2_hubs_exist_in_show_windows(app_instance: App) -> None:
|
||||
"""
|
||||
Verifies that the new consolidated Hub windows are defined in the App's show_windows.
|
||||
This ensures they will be available in the 'Windows' menu.
|
||||
@@ -33,7 +34,7 @@ def test_gui2_hubs_exist_in_show_windows(app_instance):
|
||||
for hub in expected_hubs:
|
||||
assert hub in app_instance.show_windows, f"Expected hub window '{hub}' not found in show_windows"
|
||||
|
||||
def test_gui2_old_windows_removed_from_show_windows(app_instance):
|
||||
def test_gui2_old_windows_removed_from_show_windows(app_instance: App) -> None:
|
||||
"""
|
||||
Verifies that the old fragmented windows are removed from show_windows.
|
||||
"""
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from typing import Generator
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch, AsyncMock
|
||||
import asyncio
|
||||
@@ -7,7 +8,7 @@ from events import UserRequestEvent
|
||||
import ai_client
|
||||
|
||||
@pytest.fixture
|
||||
def mock_app() -> None:
|
||||
def mock_app() -> Generator[App, None, None]:
|
||||
with (
|
||||
patch('gui_2.load_config', return_value={
|
||||
"ai": {"provider": "gemini", "model": "model-1", "temperature": 0.0, "max_tokens": 100, "history_trunc_limit": 1000},
|
||||
@@ -33,7 +34,7 @@ def mock_app() -> None:
|
||||
# so we just let it daemon-exit.
|
||||
|
||||
@pytest.mark.timeout(10)
|
||||
def test_user_request_integration_flow(mock_app):
|
||||
def test_user_request_integration_flow(mock_app: App) -> None:
|
||||
"""
|
||||
Verifies that pushing a UserRequestEvent to the event_queue:
|
||||
1. Triggers ai_client.send
|
||||
@@ -83,7 +84,7 @@ def test_user_request_integration_flow(mock_app):
|
||||
assert app.ai_status == "done"
|
||||
|
||||
@pytest.mark.timeout(10)
|
||||
def test_user_request_error_handling(mock_app):
|
||||
def test_user_request_error_handling(mock_app: App) -> None:
|
||||
"""
|
||||
Verifies that if ai_client.send raises an exception, the UI is updated with the error state.
|
||||
"""
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from typing import Tuple
|
||||
import os
|
||||
import shutil
|
||||
import pytest
|
||||
@@ -7,7 +8,7 @@ from log_registry import LogRegistry
|
||||
from log_pruner import LogPruner
|
||||
|
||||
@pytest.fixture
|
||||
def pruner_setup(tmp_path):
|
||||
def pruner_setup(tmp_path: Path) -> Tuple[LogPruner, LogRegistry, Path]:
|
||||
logs_dir = tmp_path / "logs"
|
||||
logs_dir.mkdir()
|
||||
registry_path = logs_dir / "log_registry.toml"
|
||||
@@ -15,7 +16,7 @@ def pruner_setup(tmp_path):
|
||||
pruner = LogPruner(registry, str(logs_dir))
|
||||
return pruner, registry, logs_dir
|
||||
|
||||
def test_prune_old_insignificant_logs(pruner_setup):
|
||||
def test_prune_old_insignificant_logs(pruner_setup: Tuple[LogPruner, LogRegistry, Path]) -> None:
|
||||
pruner, registry, logs_dir = pruner_setup
|
||||
# 1. Old and small (insignificant) -> should be pruned
|
||||
session_id_old_small = "old_small"
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
from typing import Generator
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
import asyncio
|
||||
from gui_2 import App
|
||||
|
||||
@pytest.fixture
|
||||
def app_instance() -> None:
|
||||
def app_instance() -> Generator[App, None, None]:
|
||||
with (
|
||||
patch('gui_2.load_config', return_value={'ai': {}, 'projects': {}}),
|
||||
patch('gui_2.save_config'),
|
||||
@@ -21,7 +22,7 @@ def app_instance() -> None:
|
||||
app._loop = MagicMock()
|
||||
yield app
|
||||
|
||||
def test_cb_ticket_retry(app_instance):
|
||||
def test_cb_ticket_retry(app_instance: App) -> None:
|
||||
ticket_id = "test_ticket_1"
|
||||
app_instance.active_tickets = [{"id": ticket_id, "status": "failed"}]
|
||||
with patch('asyncio.run_coroutine_threadsafe') as mock_run_safe:
|
||||
@@ -34,7 +35,7 @@ def test_cb_ticket_retry(app_instance):
|
||||
args, _ = mock_run_safe.call_args
|
||||
assert args[1] == app_instance._loop
|
||||
|
||||
def test_cb_ticket_skip(app_instance):
|
||||
def test_cb_ticket_skip(app_instance: App) -> None:
|
||||
ticket_id = "test_ticket_1"
|
||||
app_instance.active_tickets = [{"id": ticket_id, "status": "todo"}]
|
||||
with patch('asyncio.run_coroutine_threadsafe') as mock_run_safe:
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
from typing import Generator
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
import ai_client
|
||||
from gui_2 import App
|
||||
|
||||
@pytest.fixture
|
||||
def app_instance() -> None:
|
||||
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('gui_2.save_config'),
|
||||
@@ -21,8 +22,7 @@ def app_instance() -> None:
|
||||
app = App()
|
||||
yield app
|
||||
|
||||
def test_redundant_calls_in_process_pending_gui_tasks(app_instance):
|
||||
# Setup
|
||||
def test_redundant_calls_in_process_pending_gui_tasks(app_instance: App) -> None:
|
||||
app_instance._pending_gui_tasks = [
|
||||
{'action': 'set_value', 'item': 'current_provider', 'value': 'anthropic'}
|
||||
]
|
||||
@@ -40,8 +40,7 @@ def test_redundant_calls_in_process_pending_gui_tasks(app_instance):
|
||||
assert mock_set_provider.call_count == 1
|
||||
assert mock_reset_session.call_count == 1
|
||||
|
||||
def test_gcli_path_updates_adapter(app_instance):
|
||||
# Setup
|
||||
def test_gcli_path_updates_adapter(app_instance: App) -> None:
|
||||
app_instance.current_provider = 'gemini_cli'
|
||||
app_instance._pending_gui_tasks = [
|
||||
{'action': 'set_value', 'item': 'gcli_path', 'value': '/new/path/to/gemini'}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import os
|
||||
import shutil
|
||||
import pytest
|
||||
import shutil
|
||||
import os
|
||||
import tomllib
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
from unittest.mock import patch
|
||||
from typing import Generator
|
||||
import session_logger
|
||||
import tomllib
|
||||
|
||||
@pytest.fixture
|
||||
def temp_logs(tmp_path, monkeypatch):
|
||||
# Ensure closed before starting
|
||||
def temp_logs(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Generator[Path, None, None]:
|
||||
# Ensure closed before starting
|
||||
session_logger.close_session()
|
||||
monkeypatch.setattr(session_logger, "_comms_fh", None)
|
||||
# Mock _LOG_DIR in session_logger
|
||||
@@ -28,7 +29,8 @@ def temp_logs(tmp_path, monkeypatch):
|
||||
session_logger._LOG_DIR = original_log_dir
|
||||
session_logger._SCRIPTS_DIR = original_scripts_dir
|
||||
|
||||
def test_open_session_creates_subdir_and_registry(temp_logs):
|
||||
def test_open_session_creates_subdir_and_registry(temp_logs: Path) -> None:
|
||||
|
||||
label = "test-label"
|
||||
# We can't easily mock datetime.datetime.now() because it's a built-in
|
||||
# but we can check the resulting directory name pattern
|
||||
|
||||
Reference in New Issue
Block a user