Files
manual_slop/tests/test_diff_viewer.py
Ed_ 125cbc6dd0 feat(patch): Add patch application and backup functions
- Add create_backup() to backup files before patching
- Add apply_patch_to_file() to apply unified diff
- Add restore_from_backup() for rollback
- Add cleanup_backup() to remove backup files
- Add 15 unit tests for all patch operations
2026-03-07 00:14:23 -05:00

181 lines
4.9 KiB
Python

import pytest
import tempfile
import os
from pathlib import Path
from src.diff_viewer import (
parse_diff, DiffFile, DiffHunk, parse_hunk_header,
get_line_color, render_diff_text_immediate,
create_backup, apply_patch_to_file, restore_from_backup, cleanup_backup
)
def test_parse_diff_empty() -> None:
result = parse_diff("")
assert result == []
def test_parse_diff_none() -> None:
result = parse_diff(None) # type: ignore
assert result == []
def test_parse_simple_diff() -> None:
diff_text = """--- a/src/test.py
+++ b/src/test.py
@@ -1 +1 @@
-old
+new"""
result = parse_diff(diff_text)
assert len(result) == 1
assert result[0].old_path == "src/test.py"
assert result[0].new_path == "src/test.py"
assert len(result[0].hunks) == 1
assert result[0].hunks[0].header == "@@ -1 +1 @@"
def test_parse_diff_with_context() -> None:
diff_text = """--- a/src/example.py
+++ b/src/example.py
@@ -10,5 +10,6 @@
def existing_function():
pass
- old_line
+ old_line
+ new_line
more_code"""
result = parse_diff(diff_text)
assert len(result) == 1
assert result[0].old_path == "src/example.py"
assert len(result[0].hunks) == 1
hunk = result[0].hunks[0]
assert hunk.old_start == 10
assert hunk.old_count == 5
assert hunk.new_start == 10
assert hunk.new_count == 6
assert "- old_line" in hunk.lines
assert "+ new_line" in hunk.lines
def test_parse_multiple_files() -> None:
diff_text = """--- a/file1.py
+++ b/file1.py
@@ -1 +1 @@
-a
+b
--- a/file2.py
+++ b/file2.py
@@ -1 +1 @@
-c
+d"""
result = parse_diff(diff_text)
assert len(result) == 2
assert result[0].old_path == "file1.py"
assert result[1].old_path == "file2.py"
def test_parse_hunk_header() -> None:
result = parse_hunk_header("@@ -10,5 +10,6 @@")
assert result == (10, 5, 10, 6)
result = parse_hunk_header("@@ -1 +1 @@")
assert result == (1, 1, 1, 1)
def test_diff_line_classification() -> None:
diff_text = """--- a/test.py
+++ b/test.py
@@ -1,3 +1,4 @@
context line
-removed line
+removed line
+added line
another context"""
result = parse_diff(diff_text)
hunk = result[0].hunks[0]
assert any(line.startswith("-") for line in hunk.lines)
assert any(line.startswith("+") for line in hunk.lines)
assert any(line.startswith(" ") or not line.startswith(("-", "+")) for line in hunk.lines)
def test_get_line_color() -> None:
assert get_line_color("+added") == "green"
assert get_line_color("-removed") == "red"
assert get_line_color("@@ -1,3 +1,4 @@") == "cyan"
assert get_line_color(" context") == None
def test_render_diff_text_immediate() -> None:
diff_text = """--- a/test.py
+++ b/test.py
@@ -1 +1 @@
-old
+new"""
diff_files = parse_diff(diff_text)
output = render_diff_text_immediate(diff_files)
assert len(output) > 0
assert ("File: test.py", "white") in output
assert ("@@ -1 +1 @@", "cyan") in output
assert ("-old", "red") in output
assert ("+new", "green") in output
def test_create_backup() -> None:
with tempfile.TemporaryDirectory() as tmpdir:
test_file = Path(tmpdir) / "test.py"
test_file.write_text("original content\n")
backup_path = create_backup(str(test_file))
assert backup_path is not None
assert Path(backup_path).exists()
assert Path(backup_path).read_text() == "original content\n"
def test_create_backup_nonexistent() -> None:
result = create_backup("/nonexistent/file.py")
assert result is None
def test_apply_patch_simple() -> None:
with tempfile.TemporaryDirectory() as tmpdir:
test_file = Path(tmpdir) / "test.py"
test_file.write_text("old\n")
patch = f"""--- a/{test_file.name}
+++ b/{test_file.name}
@@ -1 +1 @@
-old
+new"""
success, msg = apply_patch_to_file(patch, tmpdir)
assert success
assert test_file.read_text() == "new\n"
def test_apply_patch_with_context() -> None:
with tempfile.TemporaryDirectory() as tmpdir:
test_file = Path(tmpdir) / "example.py"
test_file.write_text("line 1\nline 2\nline 3\n")
patch = f"""--- a/{test_file.name}
+++ b/{test_file.name}
@@ -1,3 +1,3 @@
-line 1
-line 2
+line one
+line two
line 3"""
success, msg = apply_patch_to_file(patch, tmpdir)
assert success
content = test_file.read_text()
assert "line one" in content
assert "line two" in content
def test_restore_from_backup() -> None:
with tempfile.TemporaryDirectory() as tmpdir:
test_file = Path(tmpdir) / "test.py"
test_file.write_text("modified\n")
backup_file = test_file.with_suffix(".py.backup")
backup_file.write_text("original\n")
success = restore_from_backup(str(test_file))
assert success
assert test_file.read_text() == "original\n"
def test_cleanup_backup() -> None:
with tempfile.TemporaryDirectory() as tmpdir:
test_file = Path(tmpdir) / "test.py"
test_file.write_text("content\n")
backup_file = test_file.with_suffix(".py.backup")
backup_file.write_text("backup\n")
cleanup_backup(str(test_file))
assert not backup_file.exists()