"""Tests for pattern detection algorithms.""" import pytest from shellhist.core import HistoryEntry, HistoryStore from shellhist.core.patterns import ( ngram_analysis, detect_repetitive_commands, detect_command_pairs, detect_command_triplets, detect_common_sequences, ) class TestNgramAnalysis: """Test n-gram analysis functionality.""" def test_empty_store(self): """Test with empty store.""" store = HistoryStore() results = ngram_analysis(store, n=2) assert len(results) == 0 def test_simple_pairs(self): """Test detecting command pairs.""" store = HistoryStore() commands = [ "git status", "git log", "git status", "git log", ] for cmd in commands: store.add_entry(HistoryEntry(command=cmd)) results = ngram_analysis(store, n=2) assert len(results) > 0 pair = results[0] assert "git status -> git log" in " -> ".join(pair.commands) def test_triplets(self): """Test detecting command triplets.""" store = HistoryStore() commands = [ "git add .", "git commit", "git push", "git add .", "git commit", "git push", ] for cmd in commands: store.add_entry(HistoryEntry(command=cmd)) results = ngram_analysis(store, n=3) assert len(results) == 1 assert results[0].frequency == 2 def test_min_frequency_filter(self): """Test minimum frequency filtering.""" store = HistoryStore() commands = [ "git status", "ls", "git status", ] for cmd in commands: store.add_entry(HistoryEntry(command=cmd)) results = ngram_analysis(store, n=2, min_frequency=3) assert len(results) == 0 class TestDetectRepetitiveCommands: """Test repetitive command detection.""" def test_detect_repetitive(self): """Test detecting repetitive single commands.""" store = HistoryStore() for _ in range(5): store.add_entry(HistoryEntry(command="git status")) for _ in range(2): store.add_entry(HistoryEntry(command="ls")) results = detect_repetitive_commands(store, min_frequency=3) assert len(results) == 1 assert results[0].commands == ("git status",) assert results[0].frequency == 5 def test_no_repetitive_commands(self): """Test when no commands are repetitive.""" store = HistoryStore() for cmd in ["git status", "ls", "pwd"]: store.add_entry(HistoryEntry(command=cmd)) results = detect_repetitive_commands(store, min_frequency=3) assert len(results) == 0 class TestDetectCommandPairs: """Test command pair detection.""" def test_detect_pairs(self): """Test detecting command pairs.""" store = HistoryStore() commands = [ "git add .", "git commit", "git add .", "git commit", ] for cmd in commands: store.add_entry(HistoryEntry(command=cmd)) results = detect_command_pairs(store, min_frequency=2) assert len(results) == 1 class TestDetectCommandTriplets: """Test command triplet detection.""" def test_detect_triplets(self): """Test detecting command triplets.""" store = HistoryStore() commands = [ "git add .", "git commit", "git push", "git add .", "git commit", "git push", ] for cmd in commands: store.add_entry(HistoryEntry(command=cmd)) results = detect_command_triplets(store, min_frequency=2) assert len(results) == 1 assert len(results[0].commands) == 3 class TestDetectCommonSequences: """Test common sequence detection.""" def test_detect_sequences_various_lengths(self): """Test detecting sequences of various lengths.""" store = HistoryStore() commands = [ "git add .", "git commit", "git push", "git add .", "git commit", "git push", ] for cmd in commands: store.add_entry(HistoryEntry(command=cmd)) results = detect_common_sequences(store, max_length=3, min_occurrences=2) assert len(results) > 0