163 lines
5.1 KiB
Python
163 lines
5.1 KiB
Python
import os
|
||
import sys
|
||
import tempfile
|
||
import pytest
|
||
|
||
# Add src directory to path for module import
|
||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||
|
||
# 假设您的文件名为 diff_applier_unidiff2.py
|
||
from src.llm_codegen.diff_applier import parse_diff, apply_diff
|
||
|
||
|
||
def test_parse_diff():
|
||
"""Test parsing unified diff strings to extract file paths."""
|
||
# Diff with modification and new file
|
||
diff = """--- a/file1.txt
|
||
+++ b/file1.txt
|
||
@@ -1 +1 @@
|
||
-old content
|
||
+new content
|
||
--- /dev/null
|
||
+++ b/new_file.txt
|
||
@@ -0,0 +1 @@
|
||
+new file content"""
|
||
files = parse_diff(diff)
|
||
assert set(files) == {'file1.txt', 'new_file.txt'}
|
||
|
||
# Diff with file deletion
|
||
diff_del = """--- a/deleted.txt
|
||
+++ /dev/null
|
||
@@ -1 +0,0 @@
|
||
-content to delete"""
|
||
files = parse_diff(diff_del)
|
||
# 删除操作的解析结果应为空,因为没有实际的“目标”文件被创建或修改
|
||
assert files == []
|
||
|
||
# Empty diff
|
||
assert parse_diff('') == []
|
||
assert parse_diff('\n') == []
|
||
|
||
# Diff with only new file (no old file)
|
||
diff_new_only = """--- /dev/null
|
||
+++ b/only_new.txt
|
||
@@ -0,0 +1 @@
|
||
+only new"""
|
||
files = parse_diff(diff_new_only)
|
||
assert files == ['only_new.txt']
|
||
|
||
# Invalid diff format (should still handle gracefully)
|
||
diff_invalid = "invalid diff string"
|
||
files = parse_diff(diff_invalid)
|
||
assert files == [] # No valid file paths found
|
||
|
||
def test_apply_diff_new_file():
|
||
"""Test applying a diff that creates a new file."""
|
||
with tempfile.TemporaryDirectory() as temp_dir:
|
||
diff = """--- /dev/null
|
||
+++ b/test_new.txt
|
||
@@ -0,0 +1 @@
|
||
+This is a newly created file."""
|
||
|
||
result = apply_diff(diff, temp_dir)
|
||
assert result['success']
|
||
assert 'test_new.txt' in result['applied_files']
|
||
|
||
new_file_path = os.path.join(temp_dir, 'test_new.txt')
|
||
assert os.path.exists(new_file_path)
|
||
with open(new_file_path, 'r') as f:
|
||
content = f.read()
|
||
# 修复断言,strip()会去掉行末的换行符,使内容匹配
|
||
assert content.strip() == 'This is a newly created file.'
|
||
|
||
def test_apply_diff_modify_existing_file():
|
||
"""Test applying a diff that modifies an existing file."""
|
||
with tempfile.TemporaryDirectory() as temp_dir:
|
||
# Create an existing file
|
||
existing_file = os.path.join(temp_dir, 'existing.txt')
|
||
with open(existing_file, 'w') as f:
|
||
f.write('Original line 1\nOriginal line 2\n')
|
||
|
||
diff = """--- a/existing.txt
|
||
+++ b/existing.txt
|
||
@@ -1,2 +1,2 @@
|
||
-Original line 1
|
||
+Modified line 1
|
||
Original line 2"""
|
||
|
||
result = apply_diff(diff, temp_dir)
|
||
assert result['success']
|
||
assert 'existing.txt' in result['applied_files']
|
||
|
||
with open(existing_file, 'r') as f:
|
||
content = f.read()
|
||
assert content == 'Modified line 1\nOriginal line 2\n'
|
||
|
||
def test_apply_diff_conflict_handling():
|
||
"""Test applying a diff that causes a conflict because the source doesn't match."""
|
||
with tempfile.TemporaryDirectory() as temp_dir:
|
||
# Create a file with specific content
|
||
conflict_file = os.path.join(temp_dir, 'conflict.txt')
|
||
with open(conflict_file, 'w') as f:
|
||
f.write('Different line 1\nOriginal line 2\n') # This is different from what diff expects
|
||
|
||
# This diff expects 'Initial line 1' but finds 'Different line 1'
|
||
diff = """--- a/conflict.txt
|
||
+++ b/conflict.txt
|
||
@@ -1,2 +1,2 @@
|
||
-Initial line 1
|
||
+Diff line 1
|
||
Initial line 2"""
|
||
|
||
result = apply_diff(diff, temp_dir)
|
||
assert not result['success'] # Should fail due to mismatch
|
||
# Check for conflict or error in message
|
||
assert 'error' in result['message'].lower() or 'does not match' in result['message'].lower()
|
||
assert result['error_details'] != ''
|
||
|
||
def test_apply_diff_empty_diff():
|
||
"""Test applying an empty diff string."""
|
||
result = apply_diff('', '.')
|
||
assert not result['success']
|
||
assert 'empty' in result['message'].lower()
|
||
|
||
def test_apply_diff_invalid_directory():
|
||
"""Test applying a diff to a non-existent directory."""
|
||
non_existent_dir = '/tmp/non_existent_dir_12345'
|
||
diff = """--- a/dummy.txt
|
||
+++ b/dummy.txt
|
||
@@ -1 +1 @@
|
||
-old
|
||
+new"""
|
||
|
||
result = apply_diff(diff, non_existent_dir)
|
||
assert not result['success']
|
||
assert 'does not exist' in result['message'].lower()
|
||
|
||
def test_apply_diff_no_git_repo_initialization():
|
||
"""Test applying a diff to a non-git directory. This test is now redundant as there's no git dependency."""
|
||
with tempfile.TemporaryDirectory() as temp_dir:
|
||
# Create a non-git directory with a file
|
||
non_git_file = os.path.join(temp_dir, 'non_git.txt')
|
||
with open(non_git_file, 'w') as f:
|
||
f.write('Pre-existing content\n')
|
||
|
||
diff = """--- a/non_git.txt
|
||
+++ b/non_git.txt
|
||
@@ -1 +1 @@
|
||
-Pre-existing content
|
||
+Updated content"""
|
||
|
||
result = apply_diff(diff, temp_dir)
|
||
assert result['success']
|
||
assert 'non_git.txt' in result['applied_files']
|
||
|
||
with open(non_git_file, 'r') as f:
|
||
content = f.read()
|
||
assert content == 'Updated content\n'
|
||
|
||
|
||
if __name__ == "__main__":
|
||
# Run tests if executed as script
|
||
pytest.main([__file__])
|