"""Tests for search functionality.""" from shellhist.core import HistoryEntry, HistoryStore from shellhist.core.search import fuzzy_search, rank_by_frequency class TestFuzzySearch: """Test fuzzy search functionality.""" def setup_method(self): """Set up test fixtures.""" self.store = HistoryStore() commands = [ "git status", "git commit -m 'update'", "git push origin main", "git pull", "git checkout feature", "npm install", "npm run build", "npm test", "docker ps", "docker images", ] for i, cmd in enumerate(commands): entry = HistoryEntry(command=cmd, line_number=i) self.store.add_entry(entry) def test_basic_search(self): """Test basic fuzzy search.""" results = fuzzy_search(self.store, "git status", threshold=50) assert len(results) > 0 assert any(r[0].command == "git status" for r in results) def test_search_with_threshold(self): """Test search with custom threshold.""" results = fuzzy_search(self.store, "git commit message", threshold=80) assert all(r[1] >= 80 for r in results) def test_search_no_match(self): """Test search with no matches.""" results = fuzzy_search(self.store, "xyz123nonexistent", threshold=70) assert len(results) == 0 def test_search_limit(self): """Test search result limit.""" results = fuzzy_search(self.store, "git", threshold=50, limit=3) assert len(results) <= 3 def test_search_reverse_sort(self): """Test search with reverse sorting.""" results_normal = fuzzy_search(self.store, "git", threshold=50, reverse=False) results_reverse = fuzzy_search(self.store, "git", threshold=50, reverse=True) if len(results_normal) > 1: assert results_normal != results_reverse def test_search_recent_boost(self): """Test that recent commands get boosted.""" from datetime import datetime, timedelta self.store = HistoryStore() recent_entry = HistoryEntry( command="git status", timestamp=datetime.now() - timedelta(hours=12), line_number=0 ) old_entry = HistoryEntry( command="git status", timestamp=datetime.now() - timedelta(days=5), line_number=1 ) self.store.add_entry(recent_entry) self.store.add_entry(old_entry) results_with_boost = fuzzy_search(self.store, "git status", recent=True) results_no_boost = fuzzy_search(self.store, "git status", recent=False) assert len(results_with_boost) == 1 assert len(results_no_boost) == 1 class TestRankByFrequency: """Test frequency ranking functionality.""" def setup_method(self): """Set up test fixtures.""" self.store = HistoryStore() for _ in range(5): self.store.add_entry(HistoryEntry(command="git status")) for _ in range(2): self.store.add_entry(HistoryEntry(command="git log")) self.store.add_entry(HistoryEntry(command="ls")) def test_rank_by_frequency(self): """Test ranking results by frequency.""" entry = HistoryEntry(command="git status") results = [(entry, 100)] ranked = rank_by_frequency(self.store, results) assert len(ranked) == 1 assert ranked[0][2] == 5 def test_rank_multiple(self): """Test ranking multiple results.""" entry1 = HistoryEntry(command="git status") entry2 = HistoryEntry(command="git log") results = [(entry1, 100), (entry2, 80)] ranked = rank_by_frequency(self.store, results) assert len(ranked) == 2 assert ranked[0][2] == 5 assert ranked[1][2] == 2