Add speech-first diff review mode with navigation and tests
This commit is contained in:
135
tests/unit/test_diff_review_manager.py
Normal file
135
tests/unit/test_diff_review_manager.py
Normal file
@@ -0,0 +1,135 @@
|
||||
"""
|
||||
Unit tests for DiffReviewManager parsing and presentation behavior.
|
||||
"""
|
||||
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
|
||||
import fenrirscreenreader.core.diffReviewManager as diff_review_module
|
||||
from fenrirscreenreader.core.diffReviewManager import DiffReviewManager
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def diff_manager(monkeypatch):
|
||||
"""Create a DiffReviewManager with a minimal test environment."""
|
||||
monkeypatch.setattr(diff_review_module, "_", lambda text: text)
|
||||
|
||||
spoken_messages = []
|
||||
output_manager = Mock()
|
||||
|
||||
def _capture_message(message, **_kwargs):
|
||||
spoken_messages.append(message)
|
||||
|
||||
output_manager.present_text.side_effect = _capture_message
|
||||
settings_manager = Mock()
|
||||
settings_manager.get_setting.side_effect = (
|
||||
lambda section, setting: "compact"
|
||||
if (section, setting) == ("general", "diff_verbosity")
|
||||
else "default"
|
||||
)
|
||||
|
||||
env = {
|
||||
"runtime": {
|
||||
"DebugManager": Mock(write_debug_out=Mock()),
|
||||
"OutputManager": output_manager,
|
||||
"SettingsManager": settings_manager,
|
||||
"MemoryManager": Mock(
|
||||
is_index_list_empty=Mock(return_value=True),
|
||||
get_index_list_element=Mock(return_value=""),
|
||||
),
|
||||
},
|
||||
"bindings": {},
|
||||
"rawBindings": {},
|
||||
}
|
||||
|
||||
manager = DiffReviewManager()
|
||||
manager.initialize(env)
|
||||
return manager, spoken_messages
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestDiffReviewManager:
|
||||
"""Test diff review parsing and speech presentation edge cases."""
|
||||
|
||||
def test_parse_unified_diff_tracks_sections_and_counts(self, diff_manager):
|
||||
manager, _ = diff_manager
|
||||
lines = [
|
||||
"diff --git a/example.txt b/example.txt",
|
||||
"index 1111111..2222222 100644",
|
||||
"--- a/example.txt",
|
||||
"+++ b/example.txt",
|
||||
"@@ -1,2 +1,3 @@",
|
||||
" context line",
|
||||
"-old line",
|
||||
"+new line one",
|
||||
"+new line two",
|
||||
]
|
||||
|
||||
manager._parse_lines(lines, "/tmp/example.diff")
|
||||
|
||||
assert len(manager.file_sections) == 1
|
||||
assert len(manager.hunk_sections) == 1
|
||||
assert manager.total_added == 2
|
||||
assert manager.total_removed == 1
|
||||
assert manager.file_sections[0]["added_count"] == 2
|
||||
assert manager.file_sections[0]["removed_count"] == 1
|
||||
assert manager.hunk_sections[0]["position_in_file"] == 1
|
||||
assert manager.hunk_sections[0]["hunks_in_file"] == 1
|
||||
|
||||
def test_formats_classic_diff_markers(self, diff_manager):
|
||||
manager, _ = diff_manager
|
||||
|
||||
assert manager._format_classic_diff_command("17c17") == "line 17 changed"
|
||||
assert manager._format_classic_diff_command("17d16") == "line 17 deleted"
|
||||
assert manager._format_classic_diff_command("16a17") == "line 17 added"
|
||||
assert (
|
||||
manager._format_classic_diff_command("20,22c30,32")
|
||||
== "lines 20 through 22 changed"
|
||||
)
|
||||
assert manager._format_classic_diff_command("not a diff marker") is None
|
||||
|
||||
def test_announces_classic_marker_line_as_plain_language(self, diff_manager):
|
||||
manager, spoken_messages = diff_manager
|
||||
|
||||
manager._parse_lines(["17c17"], "/tmp/classic.diff")
|
||||
manager.current_line = 0
|
||||
manager._announce_current_line()
|
||||
|
||||
assert spoken_messages[-1] == "line 17 changed"
|
||||
|
||||
def test_marker_only_added_removed_lines_become_words(self, diff_manager):
|
||||
manager, spoken_messages = diff_manager
|
||||
|
||||
manager._parse_lines(["+++", "---"], "/tmp/markers.diff")
|
||||
manager.current_line = 0
|
||||
manager._announce_current_line()
|
||||
manager.current_line = 1
|
||||
manager._announce_current_line()
|
||||
|
||||
assert spoken_messages[-2] == "added"
|
||||
assert spoken_messages[-1] == "removed"
|
||||
|
||||
def test_large_diff_parsing_stays_consistent(self, diff_manager):
|
||||
manager, spoken_messages = diff_manager
|
||||
line_count = 1500
|
||||
lines = [
|
||||
"diff --git a/large.txt b/large.txt",
|
||||
"--- a/large.txt",
|
||||
"+++ b/large.txt",
|
||||
"@@ -1,1500 +1,1500 @@",
|
||||
]
|
||||
for index in range(1, line_count + 1):
|
||||
lines.append(f"-old value {index}")
|
||||
lines.append(f"+new value {index}")
|
||||
|
||||
manager._parse_lines(lines, "/tmp/large.diff")
|
||||
manager.next_added()
|
||||
|
||||
assert len(manager.file_sections) == 1
|
||||
assert len(manager.hunk_sections) == 1
|
||||
assert manager.total_added == line_count
|
||||
assert manager.total_removed == line_count
|
||||
assert manager.current_line == manager.added_lines[0]
|
||||
assert spoken_messages[-1].startswith("Added line.")
|
||||
|
||||
Reference in New Issue
Block a user