You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
1.5 KiB
48 lines
1.5 KiB
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from gcode.safety import REJECT_SHELL, REJECT_WRITE, SafetyGate, unified_diff
|
|
from gcode.tools.fs import make_fs_tools
|
|
from gcode.tools.shell import make_shell_tools
|
|
|
|
|
|
def test_unified_diff_contains_change() -> None:
|
|
diff = unified_diff("a.py", "print(1)\n", "print(2)\n")
|
|
assert "-print(1)" in diff
|
|
assert "+print(2)" in diff
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_unique_replace_and_reject(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
monkeypatch.chdir(tmp_path)
|
|
path = tmp_path / "a.py"
|
|
path.write_text("foo\nfoo\n", encoding="utf-8")
|
|
|
|
async def deny(kind: str, detail: str) -> bool:
|
|
return False
|
|
|
|
tools = {t.name: t for t in make_fs_tools(SafetyGate(deny), tmp_path)}
|
|
out = await tools["replace_in_file"].ainvoke(
|
|
{"path": "a.py", "old_text": "foo", "new_text": "bar"}
|
|
)
|
|
assert "出现了 2 次" in out
|
|
assert path.read_text(encoding="utf-8") == "foo\nfoo\n"
|
|
|
|
path.write_text("only-once\n", encoding="utf-8")
|
|
out = await tools["replace_in_file"].ainvoke(
|
|
{"path": "a.py", "old_text": "only-once", "new_text": "twice"}
|
|
)
|
|
assert REJECT_WRITE in out
|
|
assert path.read_text(encoding="utf-8") == "only-once\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_shell_denied_does_not_run() -> None:
|
|
async def deny(kind: str, detail: str) -> bool:
|
|
return False
|
|
|
|
tools = {t.name: t for t in make_shell_tools(SafetyGate(deny))}
|
|
out = await tools["execute_command"].ainvoke({"command": "echo should-not-run"})
|
|
assert REJECT_SHELL in out
|