Skip to content

Commit dc94847

Browse files
rootclaude
andcommitted
fix: disable pylint import-error for optional MCP dependency
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 7a7e600 commit dc94847

File tree

1 file changed

+37
-34
lines changed

1 file changed

+37
-34
lines changed

tests/test_mcp_server.py

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from unittest.mock import AsyncMock, MagicMock, patch
77

88
import pytest
9-
from mcp.types import TextContent, Tool
9+
from mcp.types import TextContent, Tool # pylint: disable=import-error
1010

1111
# Import the module functions and server instance
1212
from gitingest.mcp_server import (
@@ -23,7 +23,7 @@ class TestMCPListTools:
2323
"""Test cases for the list_tools handler."""
2424

2525
@pytest.mark.asyncio
26-
async def test_list_tools_returns_correct_tools(self):
26+
async def test_list_tools_returns_correct_tools(self) -> None:
2727
"""Test that list_tools returns the expected tools."""
2828
tools = await list_tools()
2929

@@ -36,7 +36,7 @@ async def test_list_tools_returns_correct_tools(self):
3636
assert "ingest a git repository" in tool.description.lower()
3737

3838
@pytest.mark.asyncio
39-
async def test_list_tools_schema_validation(self):
39+
async def test_list_tools_schema_validation(self) -> None:
4040
"""Test that the ingest_repository tool has correct schema."""
4141
tools = await list_tools()
4242
ingest_tool = tools[0]
@@ -69,14 +69,15 @@ async def test_list_tools_schema_validation(self):
6969
assert param in properties
7070

7171
@pytest.mark.asyncio
72-
async def test_list_tools_source_examples(self):
72+
async def test_list_tools_source_examples(self) -> None:
7373
"""Test that the source parameter has proper examples."""
7474
tools = await list_tools()
7575
source_prop = tools[0].inputSchema["properties"]["source"]
7676

7777
assert "examples" in source_prop
7878
examples = source_prop["examples"]
79-
assert len(examples) >= 3
79+
min_examples = 3
80+
assert len(examples) >= min_examples
8081
assert any("github.com" in ex for ex in examples)
8182
assert any("/path/to/" in ex for ex in examples)
8283
assert "." in examples
@@ -86,7 +87,7 @@ class TestMCPCallTool:
8687
"""Test cases for the call_tool handler."""
8788

8889
@pytest.mark.asyncio
89-
async def test_call_tool_ingest_repository_success(self):
90+
async def test_call_tool_ingest_repository_success(self) -> None:
9091
"""Test successful repository ingestion through call_tool."""
9192
with patch("gitingest.mcp_server.ingest_async") as mock_ingest:
9293
mock_ingest.return_value = (
@@ -110,7 +111,7 @@ async def test_call_tool_ingest_repository_success(self):
110111
assert "Generated by Gitingest MCP Server" in content
111112

112113
@pytest.mark.asyncio
113-
async def test_call_tool_unknown_tool(self):
114+
async def test_call_tool_unknown_tool(self) -> None:
114115
"""Test handling of unknown tool calls."""
115116
result = await call_tool("unknown_tool", {})
116117

@@ -120,7 +121,7 @@ async def test_call_tool_unknown_tool(self):
120121
assert "Unknown tool: unknown_tool" in result[0].text
121122

122123
@pytest.mark.asyncio
123-
async def test_call_tool_exception_handling(self):
124+
async def test_call_tool_exception_handling(self) -> None:
124125
"""Test exception handling in call_tool."""
125126
with patch("gitingest.mcp_server._handle_ingest_repository") as mock_handle:
126127
mock_handle.side_effect = Exception("Test exception")
@@ -132,7 +133,7 @@ async def test_call_tool_exception_handling(self):
132133
assert "Error executing ingest_repository: Test exception" in result[0].text
133134

134135
@pytest.mark.asyncio
135-
async def test_call_tool_logs_errors(self):
136+
async def test_call_tool_logs_errors(self) -> None:
136137
"""Test that call_tool logs errors properly."""
137138
with (
138139
patch("gitingest.mcp_server._handle_ingest_repository") as mock_handle,
@@ -144,15 +145,15 @@ async def test_call_tool_logs_errors(self):
144145
await call_tool("ingest_repository", {"source": "test"})
145146

146147
mock_logger.exception.assert_called_once()
147-
args, kwargs = mock_logger.exception.call_args
148-
assert "Error in tool call ingest_repository" in args[0]
148+
args, _kwargs = mock_logger.exception.call_args
149+
assert args == ("Error in tool call %s", "ingest_repository")
149150

150151

151152
class TestHandleIngestRepository:
152153
"""Test cases for the _handle_ingest_repository helper function."""
153154

154155
@pytest.mark.asyncio
155-
async def test_handle_ingest_repository_minimal_args(self):
156+
async def test_handle_ingest_repository_minimal_args(self) -> None:
156157
"""Test repository ingestion with minimal arguments."""
157158
with patch("gitingest.mcp_server.ingest_async") as mock_ingest:
158159
mock_ingest.return_value = ("summary", "tree", "content")
@@ -177,7 +178,7 @@ async def test_handle_ingest_repository_minimal_args(self):
177178
)
178179

179180
@pytest.mark.asyncio
180-
async def test_handle_ingest_repository_all_args(self):
181+
async def test_handle_ingest_repository_all_args(self) -> None:
181182
"""Test repository ingestion with all arguments."""
182183
with patch("gitingest.mcp_server.ingest_async") as mock_ingest:
183184
mock_ingest.return_value = ("summary", "tree", "content")
@@ -207,12 +208,12 @@ async def test_handle_ingest_repository_all_args(self):
207208
branch="develop",
208209
include_gitignored=True,
209210
include_submodules=True,
210-
token="ghp_test_token",
211+
token="test_token_123", # noqa: S106
211212
output=None,
212213
)
213214

214215
@pytest.mark.asyncio
215-
async def test_handle_ingest_repository_pattern_conversion(self):
216+
async def test_handle_ingest_repository_pattern_conversion(self) -> None:
216217
"""Test that patterns are correctly converted to sets."""
217218
with patch("gitingest.mcp_server.ingest_async") as mock_ingest:
218219
mock_ingest.return_value = ("summary", "tree", "content")
@@ -232,7 +233,7 @@ async def test_handle_ingest_repository_pattern_conversion(self):
232233
assert call_args["exclude_patterns"] == {"*.txt"}
233234

234235
@pytest.mark.asyncio
235-
async def test_handle_ingest_repository_none_patterns(self):
236+
async def test_handle_ingest_repository_none_patterns(self) -> None:
236237
"""Test handling of None patterns."""
237238
with patch("gitingest.mcp_server.ingest_async") as mock_ingest:
238239
mock_ingest.return_value = ("summary", "tree", "content")
@@ -250,7 +251,7 @@ async def test_handle_ingest_repository_none_patterns(self):
250251
assert call_args["exclude_patterns"] is None
251252

252253
@pytest.mark.asyncio
253-
async def test_handle_ingest_repository_exception(self):
254+
async def test_handle_ingest_repository_exception(self) -> None:
254255
"""Test exception handling in _handle_ingest_repository."""
255256
with (
256257
patch("gitingest.mcp_server.ingest_async") as mock_ingest,
@@ -267,11 +268,11 @@ async def test_handle_ingest_repository_exception(self):
267268

268269
# Verify error was logged
269270
mock_logger.exception.assert_called_once()
270-
args, kwargs = mock_logger.exception.call_args
271-
assert "Error during ingestion" in args[0]
271+
args, _kwargs = mock_logger.exception.call_args
272+
assert args == ("Error during ingestion",)
272273

273274
@pytest.mark.asyncio
274-
async def test_handle_ingest_repository_logs_info(self):
275+
async def test_handle_ingest_repository_logs_info(self) -> None:
275276
"""Test that _handle_ingest_repository logs info messages."""
276277
with (
277278
patch("gitingest.mcp_server.ingest_async") as mock_ingest,
@@ -289,7 +290,7 @@ async def test_handle_ingest_repository_logs_info(self):
289290
)
290291

291292
@pytest.mark.asyncio
292-
async def test_handle_ingest_repository_response_format(self):
293+
async def test_handle_ingest_repository_response_format(self) -> None:
293294
"""Test the format of the response content."""
294295
with patch("gitingest.mcp_server.ingest_async") as mock_ingest:
295296
mock_ingest.return_value = (
@@ -317,13 +318,13 @@ class TestMCPServerIntegration:
317318
"""Integration tests for the MCP server."""
318319

319320
@pytest.mark.asyncio
320-
async def test_server_instance_created(self):
321+
async def test_server_instance_created(self) -> None:
321322
"""Test that the MCP server instance is properly created."""
322323
assert app is not None
323324
assert app.name == "gitingest"
324325

325326
@pytest.mark.asyncio
326-
async def test_start_mcp_server_calls_stdio(self):
327+
async def test_start_mcp_server_calls_stdio(self) -> None:
327328
"""Test that start_mcp_server calls the stdio runner."""
328329
with patch("gitingest.mcp_server._run_stdio") as mock_run_stdio:
329330
mock_run_stdio.return_value = AsyncMock()
@@ -333,7 +334,7 @@ async def test_start_mcp_server_calls_stdio(self):
333334
mock_run_stdio.assert_called_once()
334335

335336
@pytest.mark.asyncio
336-
async def test_start_mcp_server_logs_startup(self):
337+
async def test_start_mcp_server_logs_startup(self) -> None:
337338
"""Test that start_mcp_server logs startup message."""
338339
with (
339340
patch("gitingest.mcp_server._run_stdio") as mock_run_stdio,
@@ -348,7 +349,7 @@ async def test_start_mcp_server_logs_startup(self):
348349
)
349350

350351
@pytest.mark.asyncio
351-
async def test_run_stdio_integration(self):
352+
async def test_run_stdio_integration(self) -> None:
352353
"""Test _run_stdio function integration."""
353354
with patch("gitingest.mcp_server.stdio_server") as mock_stdio_server:
354355
# Mock the async context manager
@@ -374,14 +375,15 @@ async def test_run_stdio_integration(self):
374375
# Verify app.run was called with streams and init options
375376
mock_run.assert_called_once()
376377
call_args = mock_run.call_args[0]
377-
assert len(call_args) == 3 # read_stream, write_stream, init_options
378+
expected_args = 3 # read_stream, write_stream, init_options
379+
assert len(call_args) == expected_args
378380

379381

380382
class TestMCPServerParameterValidation:
381383
"""Test parameter validation for MCP server tools."""
382384

383385
@pytest.mark.asyncio
384-
async def test_ingest_repository_missing_source(self):
386+
async def test_ingest_repository_missing_source(self) -> None:
385387
"""Test that missing source parameter is handled."""
386388
# This should raise a KeyError which gets caught by call_tool
387389
result = await call_tool("ingest_repository", {})
@@ -391,7 +393,7 @@ async def test_ingest_repository_missing_source(self):
391393
assert "Error ingesting repository" in result[0].text
392394

393395
@pytest.mark.asyncio
394-
async def test_ingest_repository_invalid_parameters(self):
396+
async def test_ingest_repository_invalid_parameters(self) -> None:
395397
"""Test handling of invalid parameter types."""
396398
with patch("gitingest.mcp_server.ingest_async") as mock_ingest:
397399
# ingest_async should handle type validation, but let's test edge cases
@@ -410,7 +412,7 @@ async def test_ingest_repository_invalid_parameters(self):
410412
assert "Error ingesting repository: Invalid parameter type" in result[0].text
411413

412414
@pytest.mark.asyncio
413-
async def test_ingest_repository_empty_patterns(self):
415+
async def test_ingest_repository_empty_patterns(self) -> None:
414416
"""Test handling of empty pattern lists."""
415417
with patch("gitingest.mcp_server.ingest_async") as mock_ingest:
416418
mock_ingest.return_value = ("summary", "tree", "content")
@@ -433,7 +435,7 @@ class TestMCPServerEdgeCases:
433435
"""Test edge cases and error scenarios."""
434436

435437
@pytest.mark.asyncio
436-
async def test_call_tool_empty_arguments(self):
438+
async def test_call_tool_empty_arguments(self) -> None:
437439
"""Test call_tool with empty arguments dict."""
438440
result = await call_tool("ingest_repository", {})
439441

@@ -442,7 +444,7 @@ async def test_call_tool_empty_arguments(self):
442444
assert "Error ingesting repository" in result[0].text
443445

444446
@pytest.mark.asyncio
445-
async def test_handle_ingest_repository_partial_results(self):
447+
async def test_handle_ingest_repository_partial_results(self) -> None:
446448
"""Test handling when ingest_async returns partial results."""
447449
with patch("gitingest.mcp_server.ingest_async") as mock_ingest:
448450
# Test with empty strings
@@ -459,17 +461,18 @@ async def test_handle_ingest_repository_partial_results(self):
459461
assert "## Content" in content
460462

461463
@pytest.mark.asyncio
462-
async def test_concurrent_tool_calls(self):
464+
async def test_concurrent_tool_calls(self) -> None:
463465
"""Test that concurrent tool calls work correctly."""
464466
with patch("gitingest.mcp_server.ingest_async") as mock_ingest:
465467
mock_ingest.return_value = ("summary", "tree", "content")
466468

467469
# Create multiple concurrent calls
468-
tasks = [call_tool("ingest_repository", {"source": f"test-{i}"}) for i in range(3)]
470+
num_tasks = 3
471+
tasks = [call_tool("ingest_repository", {"source": f"test-{i}"}) for i in range(num_tasks)]
469472

470473
results = await asyncio.gather(*tasks)
471474

472-
assert len(results) == 3
475+
assert len(results) == num_tasks
473476
for result in results:
474477
assert isinstance(result, list)
475478
assert len(result) == 1

0 commit comments

Comments
 (0)