development-hub/tests/test_terminal_search.py

240 lines
7.7 KiB
Python

"""Tests for terminal search functionality."""
import pytest
from development_hub.terminal_display import TerminalDisplay
class TestTerminalSearch:
"""Tests for terminal display search."""
def test_search_empty_pattern(self, qtbot):
"""Empty search pattern returns no matches."""
display = TerminalDisplay(rows=10, cols=40)
qtbot.addWidget(display)
count = display.search("")
assert count == 0
assert display.search_match_count == 0
def test_search_no_matches(self, qtbot):
"""Search with no matches returns 0."""
display = TerminalDisplay(rows=10, cols=40)
qtbot.addWidget(display)
display.feed(b"Hello world\r\n")
count = display.search("xyz")
assert count == 0
assert display.current_match_number == 0
def test_search_single_match(self, qtbot):
"""Search finds a single match."""
display = TerminalDisplay(rows=10, cols=40)
qtbot.addWidget(display)
display.feed(b"Hello world\r\n")
count = display.search("world")
assert count == 1
assert display.current_match_number == 1
def test_search_multiple_matches(self, qtbot):
"""Search finds multiple matches."""
display = TerminalDisplay(rows=10, cols=40)
qtbot.addWidget(display)
display.feed(b"test one test two test three\r\n")
count = display.search("test")
assert count == 3
assert display.current_match_number == 1
def test_search_case_insensitive(self, qtbot):
"""Search is case-insensitive by default."""
display = TerminalDisplay(rows=10, cols=40)
qtbot.addWidget(display)
display.feed(b"Hello HELLO hello\r\n")
count = display.search("hello")
assert count == 3
def test_search_case_sensitive(self, qtbot):
"""Case-sensitive search works."""
display = TerminalDisplay(rows=10, cols=40)
qtbot.addWidget(display)
display.feed(b"Hello HELLO hello\r\n")
count = display.search("Hello", case_sensitive=True)
assert count == 1
def test_next_match_cycles(self, qtbot):
"""Next match cycles through matches."""
display = TerminalDisplay(rows=10, cols=40)
qtbot.addWidget(display)
display.feed(b"a b a c a\r\n")
display.search("a")
assert display.current_match_number == 1
display.next_match()
assert display.current_match_number == 2
display.next_match()
assert display.current_match_number == 3
display.next_match() # Cycles back
assert display.current_match_number == 1
def test_prev_match_cycles(self, qtbot):
"""Previous match cycles through matches backwards."""
display = TerminalDisplay(rows=10, cols=40)
qtbot.addWidget(display)
display.feed(b"a b a c a\r\n")
display.search("a")
assert display.current_match_number == 1
display.prev_match() # Cycles to end
assert display.current_match_number == 3
display.prev_match()
assert display.current_match_number == 2
def test_clear_search(self, qtbot):
"""Clear search removes matches."""
display = TerminalDisplay(rows=10, cols=40)
qtbot.addWidget(display)
display.feed(b"test test test\r\n")
display.search("test")
assert display.search_match_count == 3
display.clear_search()
assert display.search_match_count == 0
assert display.current_match_number == 0
def test_next_match_no_matches(self, qtbot):
"""Next match returns False when no matches."""
display = TerminalDisplay(rows=10, cols=40)
qtbot.addWidget(display)
result = display.next_match()
assert result is False
def test_prev_match_no_matches(self, qtbot):
"""Previous match returns False when no matches."""
display = TerminalDisplay(rows=10, cols=40)
qtbot.addWidget(display)
result = display.prev_match()
assert result is False
class TestProjectFilter:
"""Tests for project list filtering."""
def test_filter_by_title(self, qtbot, tmp_path):
"""Filter matches project titles."""
from pathlib import Path
from development_hub.project_list import ProjectListWidget
from unittest.mock import patch
from development_hub.project_discovery import Project
# Create temp directories so exists() works
p1 = tmp_path / "p1"
p2 = tmp_path / "p2"
p3 = tmp_path / "p3"
p1.mkdir()
p2.mkdir()
p3.mkdir()
mock_projects = [
Project(key="project-one", path=p1, title="Project One"),
Project(key="project-two", path=p2, title="Project Two"),
Project(key="other-thing", path=p3, title="Other Thing"),
]
with patch('development_hub.project_list.discover_projects', return_value=mock_projects):
widget = ProjectListWidget()
qtbot.addWidget(widget)
# Initially shows all
assert widget.list_widget.count() == 3
# Filter by "one"
widget.filter_input.setText("one")
assert widget.list_widget.count() == 1
assert widget.list_widget.item(0).text() == "Project One"
def test_filter_by_key(self, qtbot, tmp_path):
"""Filter matches project keys."""
from development_hub.project_list import ProjectListWidget
from unittest.mock import patch
from development_hub.project_discovery import Project
p1 = tmp_path / "p1"
p2 = tmp_path / "p2"
p1.mkdir()
p2.mkdir()
mock_projects = [
Project(key="dev-hub", path=p1, title="Development Hub"),
Project(key="cmd-forge", path=p2, title="CmdForge"),
]
with patch('development_hub.project_list.discover_projects', return_value=mock_projects):
widget = ProjectListWidget()
qtbot.addWidget(widget)
widget.filter_input.setText("hub")
assert widget.list_widget.count() == 1
assert widget.list_widget.item(0).text() == "Development Hub"
def test_filter_case_insensitive(self, qtbot, tmp_path):
"""Filter is case-insensitive."""
from development_hub.project_list import ProjectListWidget
from unittest.mock import patch
from development_hub.project_discovery import Project
p1 = tmp_path / "p1"
p1.mkdir()
mock_projects = [
Project(key="test", path=p1, title="Test Project"),
]
with patch('development_hub.project_list.discover_projects', return_value=mock_projects):
widget = ProjectListWidget()
qtbot.addWidget(widget)
widget.filter_input.setText("TEST")
assert widget.list_widget.count() == 1
def test_filter_clears(self, qtbot, tmp_path):
"""Clearing filter shows all projects."""
from development_hub.project_list import ProjectListWidget
from unittest.mock import patch
from development_hub.project_discovery import Project
p1 = tmp_path / "a"
p2 = tmp_path / "b"
p1.mkdir()
p2.mkdir()
mock_projects = [
Project(key="a", path=p1, title="Alpha"),
Project(key="b", path=p2, title="Beta"),
]
with patch('development_hub.project_list.discover_projects', return_value=mock_projects):
widget = ProjectListWidget()
qtbot.addWidget(widget)
widget.filter_input.setText("alpha")
assert widget.list_widget.count() == 1
widget.filter_input.clear()
assert widget.list_widget.count() == 2
if __name__ == "__main__":
pytest.main([__file__, "-v"])