rein-openweights/tests/test_tools.py

122 lines
3.4 KiB
Python
Raw Normal View History

import subprocess
import pytest
from rein_openweights.tools import (
ToolPolicyError,
call_tool,
edit_file,
git_add_commit,
git_diff,
git_log,
git_status,
glob_files,
grep_files,
openai_tool_schemas,
read_file,
write_file,
)
def _init_repo(tmp_path):
subprocess.run(["git", "init", "-q"], cwd=tmp_path, check=True)
subprocess.run(["git", "config", "user.email", "t@example.com"], cwd=tmp_path, check=True)
subprocess.run(["git", "config", "user.name", "t"], cwd=tmp_path, check=True)
subprocess.run(["git", "commit", "-q", "--allow-empty", "-m", "init"], cwd=tmp_path, check=True)
return tmp_path
def test_write_then_read_file(tmp_path):
repo = _init_repo(tmp_path)
write_file(repo, "a.txt", "hello")
assert read_file(repo, "a.txt") == "hello"
def test_edit_file_replaces_first_occurrence(tmp_path):
repo = _init_repo(tmp_path)
write_file(repo, "a.txt", "foo foo")
edit_file(repo, "a.txt", "foo", "bar")
assert read_file(repo, "a.txt") == "bar foo"
def test_edit_file_missing_old_raises(tmp_path):
repo = _init_repo(tmp_path)
write_file(repo, "a.txt", "hello")
with pytest.raises(ToolPolicyError, match="old string not found"):
edit_file(repo, "a.txt", "nope", "x")
def test_path_traversal_is_blocked(tmp_path):
repo = _init_repo(tmp_path)
with pytest.raises(ToolPolicyError, match="escapes repo root"):
read_file(repo, "../outside.txt")
def test_glob_files(tmp_path):
repo = _init_repo(tmp_path)
write_file(repo, "src/a.py", "1")
write_file(repo, "src/b.py", "2")
write_file(repo, "src/c.txt", "3")
result = glob_files(repo, "**/*.py")
assert "src/a.py" in result
assert "src/b.py" in result
assert "src/c.txt" not in result
def test_grep_files(tmp_path):
repo = _init_repo(tmp_path)
write_file(repo, "a.txt", "hello world\nneedle here\n")
result = grep_files(repo, "needle")
assert "a.txt:2:needle here" in result
def test_grep_files_no_matches(tmp_path):
repo = _init_repo(tmp_path)
write_file(repo, "a.txt", "hello")
assert grep_files(repo, "zzz") == "(no matches)"
def test_git_status_diff_log_and_commit(tmp_path):
repo = _init_repo(tmp_path)
write_file(repo, "a.txt", "hello")
assert "a.txt" in git_status(repo)
git_add_commit(repo, "add a.txt")
assert git_status(repo) == "(clean)"
assert "add a.txt" in git_log(repo)
def test_git_diff_after_edit(tmp_path):
repo = _init_repo(tmp_path)
write_file(repo, "a.txt", "hello")
git_add_commit(repo, "add a.txt")
edit_file(repo, "a.txt", "hello", "goodbye")
assert "goodbye" in git_diff(repo)
def test_call_tool_dispatches_by_name(tmp_path):
repo = _init_repo(tmp_path)
call_tool(repo, "write_file", {"path": "a.txt", "content": "x"})
assert read_file(repo, "a.txt") == "x"
def test_call_tool_unknown_name_raises(tmp_path):
repo = _init_repo(tmp_path)
with pytest.raises(ToolPolicyError, match="unknown tool"):
call_tool(repo, "delete_everything", {})
def test_openai_tool_schemas_cover_all_tools():
schemas = openai_tool_schemas()
names = {s["function"]["name"] for s in schemas}
assert names == {
"read_file",
"write_file",
"edit_file",
"glob_files",
"grep_files",
"git_status",
"git_diff",
"git_log",
"git_add_commit",
}