- Fixed undefined 'tool' variable in display_history function - Changed '[tool]' markup tag usage to proper Rich syntax - All tests now pass (38/38 unit tests) - Type checking passes with mypy --strict
251 lines
6.7 KiB
Python
251 lines
6.7 KiB
Python
"""Tests for the diff parser module."""
|
|
|
|
import pytest
|
|
from cli_diff_auditor.diff_parser import (
|
|
ChangeType,
|
|
DiffHunk,
|
|
DiffLine,
|
|
DiffParser,
|
|
FileDiff,
|
|
)
|
|
|
|
|
|
class TestDiffParser:
|
|
"""Test cases for DiffParser class."""
|
|
|
|
def setup_method(self):
|
|
"""Set up test fixtures."""
|
|
self.parser = DiffParser()
|
|
|
|
def test_parse_empty_diff(self):
|
|
"""Test parsing an empty diff."""
|
|
result = self.parser.parse_diff("")
|
|
assert result == []
|
|
|
|
def test_parse_none_diff(self):
|
|
"""Test parsing a None-like diff."""
|
|
result = self.parser.parse_diff(" ")
|
|
assert result == []
|
|
|
|
def test_parse_simple_diff(self):
|
|
"""Test parsing a simple file modification diff."""
|
|
diff_output = """diff --git a/test.py b/test.py
|
|
index 1234567..89abcdef 100644
|
|
--- a/test.py
|
|
+++ b/test.py
|
|
@@ -1,3 +1,3 @@
|
|
line 1
|
|
-old line
|
|
+new line
|
|
line 3
|
|
"""
|
|
result = self.parser.parse_diff(diff_output)
|
|
|
|
assert len(result) == 1
|
|
assert result[0].file_path == "test.py"
|
|
assert result[0].change_type == ChangeType.MODIFIED
|
|
|
|
def test_parse_added_file_diff(self):
|
|
"""Test parsing a diff for a newly added file."""
|
|
diff_output = """diff --git a/newfile.py b/newfile.py
|
|
new file mode 100644
|
|
index 0000000..1234567
|
|
--- /dev/null
|
|
+++ b/newfile.py
|
|
@@ -0,0 +1,2 @@
|
|
+line 1
|
|
+line 2
|
|
"""
|
|
result = self.parser.parse_diff(diff_output)
|
|
|
|
assert len(result) == 1
|
|
assert result[0].change_type == ChangeType.ADDED
|
|
assert result[0].file_path == "newfile.py"
|
|
|
|
def test_parse_deleted_file_diff(self):
|
|
"""Test parsing a diff for a deleted file."""
|
|
diff_output = """diff --git a/oldfile.py b/oldfile.py
|
|
deleted file mode 100644
|
|
index 1234567..0000000
|
|
--- a/oldfile.py
|
|
+++ /dev/null
|
|
@@ -1,2 +0,0 @@
|
|
-line 1
|
|
-line 2
|
|
"""
|
|
result = self.parser.parse_diff(diff_output)
|
|
|
|
assert len(result) == 1
|
|
assert result[0].change_type == ChangeType.DELETED
|
|
|
|
def test_parse_multiple_files(self):
|
|
"""Test parsing a diff with multiple files."""
|
|
diff_output = """diff --git a/file1.py b/file1.py
|
|
index 1234567..89abcdef 100644
|
|
--- a/file1.py
|
|
+++ b/file1.py
|
|
@@ -1,2 +1,2 @@
|
|
-old
|
|
+new
|
|
|
|
diff --git a/file2.py b/file2.py
|
|
index abcdefg..1234567 100644
|
|
--- a/file2.py
|
|
+++ b/file2.py
|
|
@@ -1,2 +1,2 @@
|
|
-old2
|
|
+new2
|
|
"""
|
|
result = self.parser.parse_diff(diff_output)
|
|
|
|
assert len(result) == 2
|
|
assert result[0].file_path == "file1.py"
|
|
assert result[1].file_path == "file2.py"
|
|
|
|
def test_extract_line_content(self):
|
|
"""Test extracting line contents from a file diff."""
|
|
diff_output = """diff --git a/test.py b/test.py
|
|
index 1234567..89abcdef 100644
|
|
--- a/test.py
|
|
+++ b/test.py
|
|
@@ -1,5 +1,5 @@
|
|
context line
|
|
-old line
|
|
+new line 1
|
|
+new line 2
|
|
context line 2
|
|
-old line 2
|
|
+new line 3
|
|
context line 3
|
|
"""
|
|
result = self.parser.parse_diff(diff_output)
|
|
|
|
assert len(result) == 1
|
|
file_diff = result[0]
|
|
|
|
lines = self.parser.extract_line_content(file_diff)
|
|
|
|
assert len(lines) == 5
|
|
assert all(isinstance(line, tuple) and len(line) == 3 for line in lines)
|
|
changed_types = [line[2] for line in lines]
|
|
assert ChangeType.ADDED in changed_types
|
|
assert ChangeType.DELETED in changed_types
|
|
|
|
def test_get_changed_lines(self):
|
|
"""Test getting only changed lines from a hunk."""
|
|
diff_output = """diff --git a/test.py b/test.py
|
|
index 1234567..89abcdef 100644
|
|
--- a/test.py
|
|
+++ b/test.py
|
|
@@ -1,4 +1,5 @@
|
|
context
|
|
-added
|
|
+modified
|
|
+another added
|
|
context again
|
|
-deleted
|
|
final context
|
|
"""
|
|
result = self.parser.parse_diff(diff_output)
|
|
|
|
assert len(result) == 1
|
|
file_diff = result[0]
|
|
|
|
assert len(file_diff.hunks) == 1
|
|
hunk = file_diff.hunks[0]
|
|
|
|
changed_lines = hunk.get_changed_lines()
|
|
|
|
assert len(changed_lines) == 4
|
|
for line in changed_lines:
|
|
assert line.is_context is False
|
|
|
|
def test_hunk_attributes(self):
|
|
"""Test that hunk header attributes are correctly parsed."""
|
|
diff_output = """diff --git a/test.py b/test.py
|
|
index 1234567..89abcdef 100644
|
|
--- a/test.py
|
|
+++ b/test.py
|
|
@@ -5,10 +7,15 @@
|
|
"""
|
|
result = self.parser.parse_diff(diff_output)
|
|
|
|
assert len(result) == 1
|
|
hunk = result[0].hunks[0]
|
|
|
|
assert hunk.old_start == 5
|
|
assert hunk.old_lines == 10
|
|
assert hunk.new_start == 7
|
|
assert hunk.new_lines == 15
|
|
|
|
|
|
class TestDiffLine:
|
|
"""Test cases for DiffLine class."""
|
|
|
|
def test_diff_line_creation(self):
|
|
"""Test creating a DiffLine instance."""
|
|
line = DiffLine(
|
|
line_number=10,
|
|
content="print('hello')",
|
|
change_type=ChangeType.ADDED
|
|
)
|
|
|
|
assert line.line_number == 10
|
|
assert line.content == "print('hello')"
|
|
assert line.change_type == ChangeType.ADDED
|
|
assert line.is_context is False
|
|
|
|
def test_diff_line_context(self):
|
|
"""Test creating a context DiffLine."""
|
|
line = DiffLine(
|
|
line_number=5,
|
|
content="def foo():",
|
|
change_type=ChangeType.MODIFIED,
|
|
is_context=True
|
|
)
|
|
|
|
assert line.is_context is True
|
|
|
|
|
|
class TestFileDiff:
|
|
"""Test cases for FileDiff class."""
|
|
|
|
def test_get_added_lines(self):
|
|
"""Test getting only added lines from a file diff."""
|
|
file_diff = FileDiff(
|
|
file_path="test.py",
|
|
change_type=ChangeType.MODIFIED
|
|
)
|
|
|
|
hunk = DiffHunk(old_start=1, old_lines=3, new_start=1, new_lines=4)
|
|
hunk.lines = [
|
|
DiffLine(line_number=1, content="old", change_type=ChangeType.DELETED),
|
|
DiffLine(line_number=2, content="new", change_type=ChangeType.ADDED),
|
|
DiffLine(line_number=3, content="context", change_type=ChangeType.MODIFIED, is_context=True),
|
|
]
|
|
file_diff.hunks.append(hunk)
|
|
|
|
added_lines = file_diff.get_added_lines()
|
|
|
|
assert len(added_lines) == 1
|
|
assert added_lines[0].change_type == ChangeType.ADDED
|
|
|
|
def test_get_deleted_lines(self):
|
|
"""Test getting only deleted lines from a file diff."""
|
|
file_diff = FileDiff(
|
|
file_path="test.py",
|
|
change_type=ChangeType.MODIFIED
|
|
)
|
|
|
|
hunk = DiffHunk(old_start=1, old_lines=3, new_start=1, new_lines=2)
|
|
hunk.lines = [
|
|
DiffLine(line_number=1, content="old", change_type=ChangeType.DELETED),
|
|
DiffLine(line_number=2, content="new", change_type=ChangeType.ADDED),
|
|
]
|
|
file_diff.hunks.append(hunk)
|
|
|
|
deleted_lines = file_diff.get_deleted_lines()
|
|
|
|
assert len(deleted_lines) == 1
|
|
assert deleted_lines[0].change_type == ChangeType.DELETED
|