Files
coding-agent-gitea/tests/test_coding_tools.py
Michael Ingvarsson e81f03c5aa fix grep
2026-07-16 12:04:51 +02:00

166 lines
5.1 KiB
Python

import os
import subprocess
from pathlib import Path
from unittest.mock import MagicMock, patch
import pytest
from gitea.tools.coding_tools import CodingTools
def test_list_files(tmp_path: Path) -> None:
d: Path = tmp_path / "sub"
d.mkdir()
f: Path = d / "hello.txt"
f.write_text("content")
res: str = CodingTools().list_files(str(d))
assert "hello.txt" in res
def test_list_files_error() -> None:
res: str = CodingTools().list_files("/nonexistent/directory/path/here")
assert "Error listing files" in res
def test_read_file(tmp_path: Path) -> None:
f: Path = tmp_path / "test.txt"
f.write_text("line1\nline2\nline3\n")
res: str = CodingTools().read_file(str(f), offset=1, limit=2)
assert "1: line1" in res
assert "2: line2" in res
assert "3: line3" not in res
def test_read_file_empty_or_out_of_bounds(tmp_path: Path) -> None:
f: Path = tmp_path / "test.txt"
f.write_text("")
res: str = CodingTools().read_file(str(f), offset=10, limit=2)
assert res == "File is empty or offset out of bounds."
def test_read_file_error() -> None:
res: str = CodingTools().read_file("/nonexistent/file/path/here")
assert "Error reading file" in res
def test_write_file(tmp_path: Path) -> None:
f: Path = tmp_path / "new_dir" / "test.txt"
res: str = CodingTools().write_file(str(f), "content")
assert "written successfully" in res
assert f.read_text() == "content"
def test_write_file_error() -> None:
res: str = CodingTools().write_file("", "content")
assert "Error writing file" in res
def test_edit_file(tmp_path: Path) -> None:
f: Path = tmp_path / "test.txt"
f.write_text("hello world")
res: str = CodingTools().edit_file(str(f), "world", "there")
assert "edited successfully" in res
assert f.read_text() == "hello there"
def test_edit_file_not_found(tmp_path: Path) -> None:
f: Path = tmp_path / "test.txt"
f.write_text("hello world")
res: str = CodingTools().edit_file(str(f), "nonexistent", "there")
assert "not found" in res
def test_edit_file_error() -> None:
res: str = CodingTools().edit_file("/nonexistent/file/path/here", "world", "there")
assert "Error editing file" in res
@patch("subprocess.Popen")
def test_run_command_success(mock_popen: MagicMock) -> None:
mock_process: MagicMock = MagicMock()
mock_process.communicate.return_value = ("output_stdout", "output_stderr")
mock_process.returncode = 0
mock_popen.return_value = mock_process
res: str = CodingTools().run_command("echo hello")
assert "output_stdout" in res
assert "output_stderr" in res
@patch("subprocess.Popen")
def test_run_command_failure(mock_popen: MagicMock) -> None:
mock_process: MagicMock = MagicMock()
mock_process.communicate.return_value = ("output_stdout", "output_stderr")
mock_process.returncode = 1
mock_popen.return_value = mock_process
res: str = CodingTools().run_command("false")
assert "Command failed with exit code 1" in res
def test_run_command_error() -> None:
with patch("subprocess.Popen", side_effect=ValueError("Invalid run")):
res: str = CodingTools().run_command("echo")
assert "Error running command" in res
@patch("subprocess.Popen")
def test_run_command_timeout(mock_popen: MagicMock) -> None:
mock_process: MagicMock = MagicMock()
mock_process.communicate.side_effect = [
subprocess.TimeoutExpired(cmd="test", timeout=1),
("stdout_after_kill", "stderr_after_kill")
]
mock_popen.return_value = mock_process
res: str = CodingTools().run_command("hang_cmd", timeout=1)
assert "Command timed out after 1 seconds" in res
assert "stdout_after_kill" in res
mock_process.kill.assert_called_once()
@patch("subprocess.Popen")
def test_grep_search_success(mock_popen: MagicMock) -> None:
mock_process: MagicMock = MagicMock()
mock_process.communicate.return_value = ("match_line", "")
mock_process.returncode = 0
mock_popen.return_value = mock_process
tools = CodingTools()
res: str = tools.grep_search("pattern", "/path")
assert res == "match_line"
mock_popen.assert_called_once_with(
["grep", "-ri", "pattern", tools._resolve_path("/path")],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
cwd=tools.repo_path,
)
@patch("subprocess.Popen")
def test_grep_search_no_matches(mock_popen: MagicMock) -> None:
mock_process: MagicMock = MagicMock()
mock_process.communicate.return_value = ("", "")
mock_process.returncode = 1
mock_popen.return_value = mock_process
tools = CodingTools()
res: str = tools.grep_search("pattern", "/path")
assert "No matches found" in res
mock_popen.assert_called_once_with(
["grep", "-ri", "pattern", tools._resolve_path("/path")],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
cwd=tools.repo_path,
)
def test_grep_search_error() -> None:
with patch("subprocess.Popen", side_effect=ValueError("Invalid run")):
res: str = CodingTools().grep_search("pattern")
assert "Error during grep search" in res