This commit is contained in:
128
shellhist/tests/test_search.py
Normal file
128
shellhist/tests/test_search.py
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
"""Tests for search functionality."""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
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
|
||||||
Reference in New Issue
Block a user