RA.Aid/tests/ra_aid/tools/test_write_file.py

201 lines
6.1 KiB
Python

import os
from unittest.mock import patch
import pytest
from ra_aid.tools.write_file import put_complete_file_contents
@pytest.fixture
def temp_test_dir(tmp_path):
"""Create a temporary test directory."""
test_dir = tmp_path / "test_write_dir"
test_dir.mkdir(exist_ok=True)
return test_dir
def test_basic_write_functionality(temp_test_dir):
"""Test basic successful file writing."""
test_file = temp_test_dir / "test.txt"
content = "Hello, World!\nTest content"
result = put_complete_file_contents(
{"filepath": str(test_file), "complete_file_contents": content}
)
# Verify file contents
assert test_file.read_text() == content
# Verify return dict format
assert isinstance(result, dict)
assert result["success"] is True
assert result["filepath"] == str(test_file)
assert result["bytes_written"] == len(content.encode("utf-8"))
assert "Successfully wrote" in result["message"]
assert "bytes" in result["message"]
def test_directory_creation(temp_test_dir):
"""Test writing to a file in a non-existent directory."""
nested_dir = temp_test_dir / "nested" / "subdirs"
test_file = nested_dir / "test.txt"
content = "Test content"
result = put_complete_file_contents(
{"filepath": str(test_file), "complete_file_contents": content}
)
assert test_file.exists()
assert test_file.read_text() == content
assert result["success"] is True
def test_different_encodings(temp_test_dir):
"""Test writing files with different encodings."""
test_file = temp_test_dir / "encoded.txt"
content = "Hello 世界" # Mixed ASCII and Unicode
# Test UTF-8
result_utf8 = put_complete_file_contents(
{
"filepath": str(test_file),
"complete_file_contents": content,
"encoding": "utf-8",
}
)
assert result_utf8["success"] is True
assert test_file.read_text(encoding="utf-8") == content
# Test UTF-16
result_utf16 = put_complete_file_contents(
{
"filepath": str(test_file),
"complete_file_contents": content,
"encoding": "utf-16",
}
)
assert result_utf16["success"] is True
assert test_file.read_text(encoding="utf-16") == content
@patch("builtins.open")
def test_permission_error(mock_open_func, temp_test_dir):
"""Test handling of permission errors."""
mock_open_func.side_effect = PermissionError("Permission denied")
test_file = temp_test_dir / "noperm.txt"
result = put_complete_file_contents(
{"filepath": str(test_file), "complete_file_contents": "test content"}
)
assert result["success"] is False
assert "Permission denied" in result["message"]
assert result["error"] is not None
@patch("builtins.open")
def test_io_error(mock_open_func, temp_test_dir):
"""Test handling of IO errors."""
mock_open_func.side_effect = IOError("IO Error occurred")
test_file = temp_test_dir / "ioerror.txt"
result = put_complete_file_contents(
{"filepath": str(test_file), "complete_file_contents": "test content"}
)
assert result["success"] is False
assert "IO Error" in result["message"]
assert result["error"] is not None
def test_empty_content(temp_test_dir):
"""Test writing empty content to a file."""
test_file = temp_test_dir / "empty.txt"
result = put_complete_file_contents({"filepath": str(test_file)})
assert test_file.exists()
assert test_file.read_text() == ""
assert result["success"] is True
assert result["bytes_written"] == 0
assert "initialized empty file" in result["message"].lower()
def test_write_empty_file_default(temp_test_dir):
"""Test creating an empty file using default parameter."""
test_file = temp_test_dir / "empty_default.txt"
result = put_complete_file_contents({"filepath": str(test_file)})
assert test_file.exists()
assert test_file.read_text() == ""
assert result["success"] is True
assert result["bytes_written"] == 0
assert "initialized empty file" in result["message"].lower()
def test_overwrite_existing_file(temp_test_dir):
"""Test overwriting an existing file."""
test_file = temp_test_dir / "overwrite.txt"
# Write initial content
test_file.write_text("Initial content")
# Overwrite with new content
new_content = "New content"
result = put_complete_file_contents(
{"filepath": str(test_file), "complete_file_contents": new_content}
)
assert test_file.read_text() == new_content
assert result["success"] is True
assert result["bytes_written"] == len(new_content.encode("utf-8"))
def test_large_file_write(temp_test_dir):
"""Test writing a large file and verify statistics."""
test_file = temp_test_dir / "large.txt"
content = "Large content\n" * 1000 # Create substantial content
result = put_complete_file_contents(
{"filepath": str(test_file), "complete_file_contents": content}
)
assert test_file.exists()
assert test_file.read_text() == content
assert result["success"] is True
assert result["bytes_written"] == len(content.encode("utf-8"))
assert os.path.getsize(test_file) == len(content.encode("utf-8"))
def test_invalid_path_characters(temp_test_dir):
"""Test handling of invalid path characters."""
invalid_path = temp_test_dir / "invalid\0file.txt"
result = put_complete_file_contents(
{"filepath": str(invalid_path), "complete_file_contents": "test content"}
)
assert result["success"] is False
assert "Invalid file path" in result["message"]
def test_write_to_readonly_directory(temp_test_dir):
"""Test writing to a readonly directory."""
readonly_dir = temp_test_dir / "readonly"
readonly_dir.mkdir()
test_file = readonly_dir / "test.txt"
# Make directory readonly
os.chmod(readonly_dir, 0o444)
try:
result = put_complete_file_contents(
{"filepath": str(test_file), "complete_file_contents": "test content"}
)
assert result["success"] is False
assert "Permission" in result["message"]
finally:
# Restore permissions for cleanup
os.chmod(readonly_dir, 0o755)