|
import os
|
|
import tempfile
|
|
|
|
from pr.tools.base import get_tools_definition
|
|
from pr.tools.command import run_command
|
|
from pr.tools.filesystem import chdir, getpwd, list_directory, read_file, search_replace, write_file
|
|
from pr.tools.interactive_control import start_interactive_session
|
|
from pr.tools.patch import apply_patch, create_diff
|
|
from pr.tools.python_exec import python_exec
|
|
|
|
|
|
class TestFilesystemTools:
|
|
|
|
def test_write_and_read_file(self, temp_dir):
|
|
filepath = os.path.join(temp_dir, "test.txt")
|
|
content = "Hello, World!"
|
|
|
|
write_result = write_file(filepath, content)
|
|
assert write_result["status"] == "success"
|
|
|
|
read_result = read_file(filepath)
|
|
assert read_result["status"] == "success"
|
|
assert content in read_result["content"]
|
|
|
|
def test_read_nonexistent_file(self):
|
|
result = read_file("/nonexistent/path/file.txt")
|
|
assert result["status"] == "error"
|
|
|
|
def test_list_directory(self, temp_dir):
|
|
test_file = os.path.join(temp_dir, "testfile.txt")
|
|
with open(test_file, "w") as f:
|
|
f.write("test")
|
|
|
|
result = list_directory(temp_dir)
|
|
assert result["status"] == "success"
|
|
assert any(item["name"] == "testfile.txt" for item in result["items"])
|
|
|
|
def test_search_replace(self, temp_dir):
|
|
filepath = os.path.join(temp_dir, "test.txt")
|
|
content = "Hello, World!"
|
|
with open(filepath, "w") as f:
|
|
f.write(content)
|
|
|
|
result = search_replace(filepath, "World", "Universe")
|
|
assert result["status"] == "success"
|
|
|
|
read_result = read_file(filepath)
|
|
assert "Hello, Universe!" in read_result["content"]
|
|
|
|
def test_chdir_and_getpwd(self):
|
|
original_cwd = getpwd()["path"]
|
|
try:
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
result = chdir(temp_dir)
|
|
assert result["status"] == "success"
|
|
assert getpwd()["path"] == temp_dir
|
|
finally:
|
|
chdir(original_cwd)
|
|
|
|
|
|
class TestCommandTools:
|
|
|
|
def test_run_command_with_cwd(self):
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
result = run_command("pwd", cwd=temp_dir)
|
|
assert result["status"] == "success"
|
|
assert temp_dir in result["stdout"].strip()
|
|
|
|
def test_run_command_basic(self):
|
|
result = run_command("echo hello")
|
|
assert result["status"] == "success"
|
|
assert "hello" in result["stdout"]
|
|
|
|
|
|
class TestInteractiveSessionTools:
|
|
|
|
def test_start_interactive_session_with_cwd(self):
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
session_name = start_interactive_session("pwd", cwd=temp_dir)
|
|
assert session_name is not None
|
|
# Note: In a real test, we'd need to interact with the session, but for now just check it starts
|
|
|
|
|
|
class TestPythonExecTools:
|
|
|
|
def test_python_exec_with_cwd(self):
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
code = "import os; print(os.getcwd())"
|
|
result = python_exec(code, {}, cwd=temp_dir)
|
|
assert result["status"] == "success"
|
|
assert temp_dir in result["output"].strip()
|
|
|
|
def test_python_exec_basic(self):
|
|
result = python_exec("print('hello')", {})
|
|
assert result["status"] == "success"
|
|
assert "hello" in result["output"]
|
|
|
|
|
|
class TestPatchTools:
|
|
|
|
def test_create_diff(self, temp_dir):
|
|
file1 = os.path.join(temp_dir, "file1.txt")
|
|
file2 = os.path.join(temp_dir, "file2.txt")
|
|
with open(file1, "w") as f:
|
|
f.write("line1\nline2\nline3\n")
|
|
with open(file2, "w") as f:
|
|
f.write("line1\nline2 modified\nline3\n")
|
|
|
|
result = create_diff(file1, file2)
|
|
assert result["status"] == "success"
|
|
assert "line2" in result["diff"]
|
|
assert "line2 modified" in result["diff"]
|
|
|
|
def test_apply_patch(self, temp_dir):
|
|
filepath = os.path.join(temp_dir, "file.txt")
|
|
with open(filepath, "w") as f:
|
|
f.write("line1\nline2\nline3\n")
|
|
|
|
# Create a simple patch
|
|
patch_content = """--- a/file.txt
|
|
+++ b/file.txt
|
|
@@ -1,3 +1,3 @@
|
|
line1
|
|
-line2
|
|
+line2 modified
|
|
line3
|
|
"""
|
|
result = apply_patch(filepath, patch_content)
|
|
assert result["status"] == "success"
|
|
|
|
read_result = read_file(filepath)
|
|
assert "line2 modified" in read_result["content"]
|
|
|
|
|
|
class TestToolDefinitions:
|
|
|
|
def test_get_tools_definition_returns_list(self):
|
|
tools = get_tools_definition()
|
|
assert isinstance(tools, list)
|
|
assert len(tools) > 0
|
|
|
|
def test_all_tools_have_required_fields(self):
|
|
tools = get_tools_definition()
|
|
|
|
for tool in tools:
|
|
assert "type" in tool
|
|
assert tool["type"] == "function"
|
|
assert "function" in tool
|
|
|
|
func = tool["function"]
|
|
assert "name" in func
|
|
assert "description" in func
|
|
assert "parameters" in func
|
|
|
|
def test_filesystem_tools_present(self):
|
|
tools = get_tools_definition()
|
|
tool_names = [t["function"]["name"] for t in tools]
|
|
|
|
assert "read_file" in tool_names
|
|
assert "write_file" in tool_names
|
|
assert "list_directory" in tool_names
|
|
assert "search_replace" in tool_names
|
|
assert "chdir" in tool_names
|
|
assert "getpwd" in tool_names
|
|
|
|
def test_command_tools_present(self):
|
|
tools = get_tools_definition()
|
|
tool_names = [t["function"]["name"] for t in tools]
|
|
|
|
assert "run_command" in tool_names
|
|
assert "start_interactive_session" in tool_names
|
|
|
|
def test_python_exec_present(self):
|
|
tools = get_tools_definition()
|
|
tool_names = [t["function"]["name"] for t in tools]
|
|
|
|
assert "python_exec" in tool_names
|
|
|
|
def test_patch_tools_present(self):
|
|
tools = get_tools_definition()
|
|
tool_names = [t["function"]["name"] for t in tools]
|
|
|
|
assert "apply_patch" in tool_names
|
|
assert "create_diff" in tool_names
|