"""Tests for diff_analyzer module.""" import sys import os sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'scripts')) from diff_analyzer import DiffAnalyzer, ChangeCategory def test_parse_simple_addition(): diff = """diff --git a/foo.py b/foo.py new file mode 100644 --- /dev/null +++ b/foo.py @@ -0,0 +1,3 @@ +def hello(): + return "world" +# end """ analyzer = DiffAnalyzer() summary = analyzer.analyze(diff) assert summary.files_changed == 1 assert summary.files_added == 1 assert summary.files_modified == 0 assert summary.total_added == 3 assert summary.total_deleted == 0 assert summary.hunks_added == 1 assert len(summary.file_changes) == 1 assert summary.file_changes[0].is_new is True assert summary.file_changes[0].path == "foo.py" def test_parse_simple_deletion(): diff = """diff --git a/old.py b/old.py deleted file mode 100644 --- a/old.py +++ /dev/null @@ -1,2 +0,0 @@ -x = 1 -y = 2 """ analyzer = DiffAnalyzer() summary = analyzer.analyze(diff) assert summary.files_changed == 1 assert summary.files_deleted == 1 assert summary.total_deleted == 2 assert summary.total_added == 0 assert summary.hunks_deleted == 1 assert summary.file_changes[0].is_deleted is True def test_parse_modification(): diff = """diff --git a/bar.py b/bar.py --- a/bar.py +++ b/bar.py @@ -10,3 +10,4 @@ def foo(): existing() - old_call() + new_call() + extra_step() return """ analyzer = DiffAnalyzer() summary = analyzer.analyze(diff) assert summary.files_changed == 1 assert summary.files_modified == 1 assert summary.total_added == 2 # +new_call(), +extra_step() assert summary.total_deleted == 1 # -old_call() assert summary.total_context == 2 # 2 context lines assert summary.hunks_modified == 1 def test_parse_multiple_files(): diff = """diff --git a/a.py b/a.py --- a/a.py +++ b/a.py @@ -1,1 +1,2 @@ existing +added diff --git a/b.py b/b.py new file mode 100644 --- /dev/null +++ b/b.py @@ -0,0 +1,1 @@ +new file diff --git a/c.py b/c.py deleted file mode 100644 --- a/c.py +++ /dev/null @@ -1,1 +0,0 @@ -gone """ analyzer = DiffAnalyzer() summary = analyzer.analyze(diff) assert summary.files_changed == 3 assert summary.files_added == 1 assert summary.files_deleted == 1 assert summary.files_modified == 1 assert summary.total_added == 2 assert summary.total_deleted == 1 def test_parse_rename(): diff = """diff --git a/old_name.py b/new_name.py rename from old_name.py rename to new_name.py --- a/old_name.py +++ b/new_name.py @@ -1,1 +1,1 @@ -old_func() +new_func() """ analyzer = DiffAnalyzer() summary = analyzer.analyze(diff) assert summary.files_changed == 1 assert summary.files_renamed == 1 assert summary.file_changes[0].is_renamed is True assert summary.file_changes[0].old_path == "old_name.py" assert summary.file_changes[0].path == "new_name.py" def test_parse_mixed_hunks(): """A file with one add hunk and one delete hunk.""" diff = """diff --git a/mixed.py b/mixed.py --- a/mixed.py +++ b/mixed.py @@ -5,0 +6,2 @@ +new_line_1 +new_line_2 @@ -20,2 +22,0 @@ -removed_1 -removed_2 """ analyzer = DiffAnalyzer() summary = analyzer.analyze(diff) assert summary.files_changed == 1 assert summary.hunks_added == 1 assert summary.hunks_deleted == 1 assert summary.total_added == 2 assert summary.total_deleted == 2 def test_empty_diff(): analyzer = DiffAnalyzer() summary = analyzer.analyze("") assert summary.files_changed == 0 assert summary.total_added == 0 assert summary.total_deleted == 0 def test_to_dict(): diff = """diff --git a/test.py b/test.py new file mode 100644 --- /dev/null +++ b/test.py @@ -0,0 +1,2 @@ +line1 +line2 """ analyzer = DiffAnalyzer() summary = analyzer.analyze(diff) d = summary.to_dict() assert d["files_changed"] == 1 assert d["files_added"] == 1 assert d["total_added"] == 2 assert d["total_deleted"] == 0 assert len(d["files"]) == 1 assert d["files"][0]["path"] == "test.py" assert d["files"][0]["is_new"] is True def test_context_only_hunk(): """A hunk with only context lines (rare but possible).""" diff = """diff --git a/noop.py b/noop.py --- a/noop.py +++ b/noop.py @@ -5,3 +5,3 @@ context1 context2 context3 """ analyzer = DiffAnalyzer() summary = analyzer.analyze(diff) assert summary.total_context == 3 assert summary.total_added == 0 assert summary.total_deleted == 0 def test_binary_files_skipped(): """Binary file diffs have no content lines — just headers.""" diff = """diff --git a/image.png b/image.png --- a/image.png +++ b/image.png Binary files a/image.png and b/image.png differ """ analyzer = DiffAnalyzer() summary = analyzer.analyze(diff) assert summary.files_changed == 1 assert summary.total_added == 0 assert summary.total_deleted == 0 if __name__ == "__main__": test_parse_simple_addition() test_parse_simple_deletion() test_parse_modification() test_parse_multiple_files() test_parse_rename() test_parse_mixed_hunks() test_empty_diff() test_to_dict() test_context_only_hunk() test_binary_files_skipped() print("All 10 tests passed.")