Skip to content

Commit 1f7577e

Browse files
author
Yoshihiro Takahara
committed
fix: type annotations and text editor test
- Add Generator type annotations for pytest fixtures - Fix test_patch_text_file.py - Replace get_text_file_contents with read_multiple_ranges - Update line ranges to properly handle line numbers (2-3 instead of 2-4) - Add missing await for async method calls
1 parent df2d3ce commit 1f7577e

File tree

3 files changed

+41
-24
lines changed

3 files changed

+41
-24
lines changed

src/mcp_text_editor/server.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,14 @@ async def run_tool(self, arguments: Dict[str, Any]) -> Sequence[TextContent]:
241241
logger.error(traceback.format_exc())
242242
raise RuntimeError(f"Error processing request: {str(e)}") from e
243243

244+
244245
class CreateTextFileHandler:
245246
"""Handler for creating a new text file."""
246247

247248
name = "create_text_file"
248-
description = "Create a new text file with given content. The file must not exist already."
249+
description = (
250+
"Create a new text file with given content. The file must not exist already."
251+
)
249252

250253
def __init__(self):
251254
self.editor = TextEditor()
@@ -293,7 +296,7 @@ async def run_tool(self, arguments: Dict[str, Any]) -> Sequence[TextContent]:
293296
raise RuntimeError(f"File already exists: {file_path}")
294297

295298
encoding = arguments.get("encoding", "utf-8")
296-
299+
297300
# Create new file using edit_file_contents with empty expected_hash
298301
result = await self.editor.edit_file_contents(
299302
file_path,
@@ -374,12 +377,11 @@ async def run_tool(self, arguments: Dict[str, Any]) -> Sequence[TextContent]:
374377
raise RuntimeError(f"File does not exist: {file_path}")
375378

376379
encoding = arguments.get("encoding", "utf-8")
377-
380+
378381
# Check file contents and hash before modification
379382
# Get file information and verify hash
380-
content, _, _, current_hash, total_lines, _ = await self.editor.read_file_contents(
381-
file_path,
382-
encoding=encoding
383+
content, _, _, current_hash, total_lines, _ = (
384+
await self.editor.read_file_contents(file_path, encoding=encoding)
383385
)
384386

385387
# Verify file hash
@@ -414,13 +416,13 @@ async def run_tool(self, arguments: Dict[str, Any]) -> Sequence[TextContent]:
414416
raise RuntimeError(f"Error processing request: {str(e)}") from e
415417

416418

417-
418419
# Initialize tool handlers
419420
get_contents_handler = GetTextFileContentsHandler()
420421
edit_contents_handler = EditTextFileContentsHandler()
421422
create_file_handler = CreateTextFileHandler()
422423
append_file_handler = AppendTextFileContentsHandler()
423424

425+
424426
@app.list_tools()
425427
async def list_tools() -> List[Tool]:
426428
"""List available tools."""

tests/test_append_text_file.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Test cases for append_text_file_contents handler."""
22

33
import os
4-
from typing import Any, Dict
4+
from typing import Any, Dict, Generator
55

66
import pytest
77

@@ -19,7 +19,7 @@ def test_dir(tmp_path: str) -> str:
1919

2020

2121
@pytest.fixture
22-
def cleanup_files() -> None:
22+
def cleanup_files() -> Generator[None, None, None]:
2323
"""Clean up any test files after each test."""
2424
yield
2525
# Add cleanup code if needed
@@ -56,7 +56,7 @@ async def test_append_text_file_success(test_dir: str, cleanup_files: None) -> N
5656
# Parse response to check success
5757
assert len(response) == 1
5858
result = response[0].text
59-
assert "\"result\": \"ok\"" in result
59+
assert '"result": "ok"' in result
6060

6161

6262
@pytest.mark.asyncio
@@ -78,7 +78,9 @@ async def test_append_text_file_not_exists(test_dir: str, cleanup_files: None) -
7878

7979

8080
@pytest.mark.asyncio
81-
async def test_append_text_file_hash_mismatch(test_dir: str, cleanup_files: None) -> None:
81+
async def test_append_text_file_hash_mismatch(
82+
test_dir: str, cleanup_files: None
83+
) -> None:
8284
"""Test appending with incorrect file hash."""
8385
test_file = os.path.join(test_dir, "hash_test.txt")
8486
initial_content = "Initial content\n"
@@ -101,7 +103,9 @@ async def test_append_text_file_hash_mismatch(test_dir: str, cleanup_files: None
101103

102104

103105
@pytest.mark.asyncio
104-
async def test_append_text_file_relative_path(test_dir: str, cleanup_files: None) -> None:
106+
async def test_append_text_file_relative_path(
107+
test_dir: str, cleanup_files: None
108+
) -> None:
105109
"""Test attempting to append using a relative path."""
106110
arguments: Dict[str, Any] = {
107111
"path": "relative_path.txt",
@@ -125,17 +129,23 @@ async def test_append_text_file_missing_args() -> None:
125129

126130
# Test missing contents
127131
with pytest.raises(RuntimeError) as exc_info:
128-
await append_handler.run_tool({"path": "/absolute/path.txt", "file_hash": "hash"})
132+
await append_handler.run_tool(
133+
{"path": "/absolute/path.txt", "file_hash": "hash"}
134+
)
129135
assert "Missing required argument: contents" in str(exc_info.value)
130136

131137
# Test missing file_hash
132138
with pytest.raises(RuntimeError) as exc_info:
133-
await append_handler.run_tool({"path": "/absolute/path.txt", "contents": "content\n"})
139+
await append_handler.run_tool(
140+
{"path": "/absolute/path.txt", "contents": "content\n"}
141+
)
134142
assert "Missing required argument: file_hash" in str(exc_info.value)
135143

136144

137145
@pytest.mark.asyncio
138-
async def test_append_text_file_custom_encoding(test_dir: str, cleanup_files: None) -> None:
146+
async def test_append_text_file_custom_encoding(
147+
test_dir: str, cleanup_files: None
148+
) -> None:
139149
"""Test appending with custom encoding."""
140150
test_file = os.path.join(test_dir, "encode_test.txt")
141151
initial_content = "こんにちは\n"
@@ -147,7 +157,9 @@ async def test_append_text_file_custom_encoding(test_dir: str, cleanup_files: No
147157

148158
# Get file hash for append operation
149159
editor = TextEditor()
150-
_, _, _, file_hash, _, _ = await editor.read_file_contents(test_file, encoding="utf-8")
160+
_, _, _, file_hash, _, _ = await editor.read_file_contents(
161+
test_file, encoding="utf-8"
162+
)
151163

152164
# Append content using handler with specified encoding
153165
arguments: Dict[str, Any] = {
@@ -166,4 +178,4 @@ async def test_append_text_file_custom_encoding(test_dir: str, cleanup_files: No
166178
# Parse response to check success
167179
assert len(response) == 1
168180
result = response[0].text
169-
assert "\"result\": \"ok\"" in result
181+
assert '"result": "ok"' in result

tests/test_create_text_file.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
"""Test cases for create_text_file handler."""
22

33
import os
4-
from typing import Any, Dict
4+
from typing import Any, Dict, Generator
55

66
import pytest
77

88
from mcp_text_editor.server import CreateTextFileHandler
9-
from mcp_text_editor.text_editor import TextEditor
109

1110
# Initialize handlers for tests
1211
create_file_handler = CreateTextFileHandler()
@@ -19,7 +18,7 @@ def test_dir(tmp_path: str) -> str:
1918

2019

2120
@pytest.fixture
22-
def cleanup_files() -> None:
21+
def cleanup_files() -> Generator[None, None, None]:
2322
"""Clean up any test files after each test."""
2423
yield
2524
# Add cleanup code if needed
@@ -46,7 +45,7 @@ async def test_create_text_file_success(test_dir: str, cleanup_files: None) -> N
4645
# Parse response to check success
4746
assert len(response) == 1
4847
result = response[0].text
49-
assert "\"result\": \"ok\"" in result
48+
assert '"result": "ok"' in result
5049

5150

5251
@pytest.mark.asyncio
@@ -70,7 +69,9 @@ async def test_create_text_file_exists(test_dir: str, cleanup_files: None) -> No
7069

7170

7271
@pytest.mark.asyncio
73-
async def test_create_text_file_relative_path(test_dir: str, cleanup_files: None) -> None:
72+
async def test_create_text_file_relative_path(
73+
test_dir: str, cleanup_files: None
74+
) -> None:
7475
"""Test attempting to create a file with a relative path."""
7576
# Try to create file using relative path
7677
arguments: Dict[str, Any] = {
@@ -99,7 +100,9 @@ async def test_create_text_file_missing_args() -> None:
99100

100101

101102
@pytest.mark.asyncio
102-
async def test_create_text_file_custom_encoding(test_dir: str, cleanup_files: None) -> None:
103+
async def test_create_text_file_custom_encoding(
104+
test_dir: str, cleanup_files: None
105+
) -> None:
103106
"""Test creating a file with custom encoding."""
104107
test_file = os.path.join(test_dir, "encoded_file.txt")
105108
content = "こんにちは\n" # Japanese text
@@ -120,4 +123,4 @@ async def test_create_text_file_custom_encoding(test_dir: str, cleanup_files: No
120123
# Parse response to check success
121124
assert len(response) == 1
122125
result = response[0].text
123-
assert "\"result\": \"ok\"" in result
126+
assert '"result": "ok"' in result

0 commit comments

Comments
 (0)