184 lines
4.7 KiB
Python
184 lines
4.7 KiB
Python
"""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
|