add test suite for file_str_replace
This commit is contained in:
parent
5b0e759f3a
commit
afcf6553a7
|
|
@ -196,6 +196,8 @@ Instructions:
|
||||||
4. Use delete_key_facts to remove any key facts that no longer apply.
|
4. Use delete_key_facts to remove any key facts that no longer apply.
|
||||||
5. Do not add features not explicitly required.
|
5. Do not add features not explicitly required.
|
||||||
6. Only create or modify files directly related to this task.
|
6. Only create or modify files directly related to this task.
|
||||||
|
7. Use file_str_replace and write_file_tool for simple file modifications.
|
||||||
|
8. Delegate to run_programming_task for more complex programming tasks.
|
||||||
|
|
||||||
Testing:
|
Testing:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,174 @@
|
||||||
|
import os
|
||||||
|
import pytest
|
||||||
|
from pathlib import Path
|
||||||
|
from unittest.mock import patch, mock_open
|
||||||
|
from ra_aid.tools.file_str_replace import file_str_replace
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def temp_test_dir(tmp_path):
|
||||||
|
"""Create a temporary test directory."""
|
||||||
|
test_dir = tmp_path / "test_replace_dir"
|
||||||
|
test_dir.mkdir(exist_ok=True)
|
||||||
|
return test_dir
|
||||||
|
|
||||||
|
def test_basic_replacement(temp_test_dir):
|
||||||
|
"""Test basic string replacement functionality."""
|
||||||
|
test_file = temp_test_dir / "test.txt"
|
||||||
|
initial_content = "Hello world! This is a test."
|
||||||
|
test_file.write_text(initial_content)
|
||||||
|
|
||||||
|
result = file_str_replace.invoke({
|
||||||
|
"filepath": str(test_file),
|
||||||
|
"old_str": "world",
|
||||||
|
"new_str": "universe"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert result["success"] is True
|
||||||
|
assert test_file.read_text() == "Hello universe! This is a test."
|
||||||
|
assert "Successfully replaced" in result["message"]
|
||||||
|
|
||||||
|
def test_file_not_found():
|
||||||
|
"""Test handling of non-existent file."""
|
||||||
|
result = file_str_replace.invoke({
|
||||||
|
"filepath": "nonexistent.txt",
|
||||||
|
"old_str": "test",
|
||||||
|
"new_str": "replacement"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert result["success"] is False
|
||||||
|
assert "File not found" in result["message"]
|
||||||
|
|
||||||
|
def test_string_not_found(temp_test_dir):
|
||||||
|
"""Test handling of string not present in file."""
|
||||||
|
test_file = temp_test_dir / "test.txt"
|
||||||
|
test_file.write_text("Hello world!")
|
||||||
|
|
||||||
|
result = file_str_replace.invoke({
|
||||||
|
"filepath": str(test_file),
|
||||||
|
"old_str": "nonexistent",
|
||||||
|
"new_str": "replacement"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert result["success"] is False
|
||||||
|
assert "String not found" in result["message"]
|
||||||
|
|
||||||
|
def test_multiple_occurrences(temp_test_dir):
|
||||||
|
"""Test handling of multiple string occurrences."""
|
||||||
|
test_file = temp_test_dir / "test.txt"
|
||||||
|
test_file.write_text("test test test")
|
||||||
|
|
||||||
|
result = file_str_replace.invoke({
|
||||||
|
"filepath": str(test_file),
|
||||||
|
"old_str": "test",
|
||||||
|
"new_str": "replacement"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert result["success"] is False
|
||||||
|
assert "appears" in result["message"]
|
||||||
|
assert "must be unique" in result["message"]
|
||||||
|
|
||||||
|
def test_empty_strings(temp_test_dir):
|
||||||
|
"""Test handling of empty strings."""
|
||||||
|
test_file = temp_test_dir / "test.txt"
|
||||||
|
test_file.write_text("Hello world!")
|
||||||
|
|
||||||
|
# Test empty old string
|
||||||
|
result1 = file_str_replace.invoke({
|
||||||
|
"filepath": str(test_file),
|
||||||
|
"old_str": "",
|
||||||
|
"new_str": "replacement"
|
||||||
|
})
|
||||||
|
assert result1["success"] is False
|
||||||
|
|
||||||
|
# Test empty new string
|
||||||
|
result2 = file_str_replace.invoke({
|
||||||
|
"filepath": str(test_file),
|
||||||
|
"old_str": "world",
|
||||||
|
"new_str": ""
|
||||||
|
})
|
||||||
|
assert result2["success"] is True
|
||||||
|
assert test_file.read_text() == "Hello !"
|
||||||
|
|
||||||
|
def test_special_characters(temp_test_dir):
|
||||||
|
"""Test handling of special characters."""
|
||||||
|
test_file = temp_test_dir / "test.txt"
|
||||||
|
initial_content = "Hello\nworld!\t\r\nSpecial chars: $@#%"
|
||||||
|
test_file.write_text(initial_content)
|
||||||
|
|
||||||
|
result = file_str_replace.invoke({
|
||||||
|
"filepath": str(test_file),
|
||||||
|
"old_str": "Special chars: $@#%",
|
||||||
|
"new_str": "Replaced!"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert result["success"] is True
|
||||||
|
assert "Special chars: $@#%" not in test_file.read_text()
|
||||||
|
assert "Replaced!" in test_file.read_text()
|
||||||
|
|
||||||
|
@patch('pathlib.Path.read_text')
|
||||||
|
def test_io_error(mock_read_text, temp_test_dir):
|
||||||
|
"""Test handling of IO errors during read."""
|
||||||
|
# Create and write to file first
|
||||||
|
test_file = temp_test_dir / "test.txt"
|
||||||
|
test_file.write_text("some test content")
|
||||||
|
|
||||||
|
# Then mock read_text to raise error
|
||||||
|
mock_read_text.side_effect = IOError("Failed to read file")
|
||||||
|
|
||||||
|
result = file_str_replace.invoke({
|
||||||
|
"filepath": str(test_file),
|
||||||
|
"old_str": "test",
|
||||||
|
"new_str": "replacement"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert result["success"] is False
|
||||||
|
assert "Failed to read file" in result["message"]
|
||||||
|
|
||||||
|
def test_permission_error(temp_test_dir):
|
||||||
|
"""Test handling of permission errors."""
|
||||||
|
test_file = temp_test_dir / "readonly.txt"
|
||||||
|
test_file.write_text("test content")
|
||||||
|
os.chmod(test_file, 0o444) # Make file read-only
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = file_str_replace.invoke({
|
||||||
|
"filepath": str(test_file),
|
||||||
|
"old_str": "test",
|
||||||
|
"new_str": "replacement"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert result["success"] is False
|
||||||
|
assert "Permission" in result["message"] or "Error" in result["message"]
|
||||||
|
finally:
|
||||||
|
os.chmod(test_file, 0o644) # Restore permissions for cleanup
|
||||||
|
|
||||||
|
def test_unicode_strings(temp_test_dir):
|
||||||
|
"""Test handling of Unicode strings."""
|
||||||
|
test_file = temp_test_dir / "unicode.txt"
|
||||||
|
initial_content = "Hello 世界! Unicode テスト"
|
||||||
|
test_file.write_text(initial_content)
|
||||||
|
|
||||||
|
result = file_str_replace.invoke({
|
||||||
|
"filepath": str(test_file),
|
||||||
|
"old_str": "世界",
|
||||||
|
"new_str": "ワールド"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert result["success"] is True
|
||||||
|
assert "世界" not in test_file.read_text()
|
||||||
|
assert "ワールド" in test_file.read_text()
|
||||||
|
|
||||||
|
def test_long_string_truncation(temp_test_dir):
|
||||||
|
"""Test handling and truncation of very long strings."""
|
||||||
|
test_file = temp_test_dir / "test.txt"
|
||||||
|
long_string = "x" * 100
|
||||||
|
test_file.write_text(f"prefix {long_string} suffix")
|
||||||
|
|
||||||
|
result = file_str_replace.invoke({
|
||||||
|
"filepath": str(test_file),
|
||||||
|
"old_str": long_string,
|
||||||
|
"new_str": "replaced"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert result["success"] is True
|
||||||
|
assert test_file.read_text() == "prefix replaced suffix"
|
||||||
Loading…
Reference in New Issue