Initial upload: shell-speak CLI tool with natural language to shell command conversion
This commit is contained in:
140
tests/test_pattern_matching.py
Normal file
140
tests/test_pattern_matching.py
Normal file
@@ -0,0 +1,140 @@
|
||||
"""Tests for pattern matching engine."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
|
||||
class TestNLP:
|
||||
"""Tests for NLP preprocessing functions."""
|
||||
|
||||
def test_normalize_text(self):
|
||||
from shell_speak.nlp import normalize_text
|
||||
|
||||
assert normalize_text(" Hello World ") == "hello world"
|
||||
assert normalize_text("Hello\tWorld") == "hello world"
|
||||
assert normalize_text("multiple spaces") == "multiple spaces"
|
||||
|
||||
def test_tokenize(self):
|
||||
from shell_speak.nlp import tokenize
|
||||
|
||||
assert tokenize("hello world") == ["hello", "world"]
|
||||
assert tokenize("List running containers") == ["list", "running", "containers"]
|
||||
assert tokenize("") == []
|
||||
|
||||
def test_extract_keywords(self):
|
||||
from shell_speak.nlp import extract_keywords
|
||||
|
||||
keywords = extract_keywords("list running containers")
|
||||
assert "list" in keywords
|
||||
assert "running" in keywords
|
||||
assert "containers" in keywords
|
||||
|
||||
def test_extract_keywords_removes_stopwords(self):
|
||||
from shell_speak.nlp import extract_keywords
|
||||
|
||||
keywords = extract_keywords("the a is are")
|
||||
assert len(keywords) == 0
|
||||
|
||||
def test_calculate_similarity(self):
|
||||
from shell_speak.nlp import calculate_similarity
|
||||
|
||||
assert calculate_similarity("list containers", "list containers") == 1.0
|
||||
assert calculate_similarity("list containers", "show running containers") > 0.1
|
||||
assert calculate_similarity("list containers", "git commit") == 0.0
|
||||
|
||||
|
||||
class TestPatternMatcher:
|
||||
"""Tests for pattern matching functionality."""
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup(self, tmp_path, sample_docker_yaml):
|
||||
from shell_speak.config import ensure_data_dir
|
||||
from shell_speak.library import get_loader
|
||||
|
||||
docker_file = tmp_path / "docker.yaml"
|
||||
docker_file.write_text(sample_docker_yaml)
|
||||
|
||||
os.environ["SHELL_SPEAK_DATA_DIR"] = str(tmp_path)
|
||||
|
||||
loader = get_loader()
|
||||
loader._loaded = False
|
||||
loader._patterns = []
|
||||
|
||||
def test_match_existing_pattern(self):
|
||||
from shell_speak.matcher import get_matcher
|
||||
|
||||
matcher = get_matcher()
|
||||
match = matcher.match("list running containers")
|
||||
|
||||
assert match is not None
|
||||
assert match.command == "docker ps"
|
||||
assert match.confidence > 0.5
|
||||
|
||||
def test_match_partial_pattern(self):
|
||||
from shell_speak.matcher import get_matcher
|
||||
|
||||
matcher = get_matcher()
|
||||
match = matcher.match("show running containers")
|
||||
|
||||
assert match is not None
|
||||
assert "docker" in match.command.lower()
|
||||
|
||||
def test_match_no_match(self):
|
||||
from shell_speak.matcher import get_matcher
|
||||
|
||||
matcher = get_matcher()
|
||||
match = matcher.match("xyz unknown query that does not exist")
|
||||
|
||||
assert match is None
|
||||
|
||||
def test_match_with_tool_filter(self):
|
||||
from shell_speak.matcher import get_matcher
|
||||
|
||||
matcher = get_matcher()
|
||||
match = matcher.match("list running containers", tool="docker")
|
||||
|
||||
assert match is not None
|
||||
assert match.pattern.tool == "docker"
|
||||
|
||||
def test_template_substitution(self):
|
||||
from shell_speak.matcher import get_matcher
|
||||
|
||||
matcher = get_matcher()
|
||||
match = matcher.match("run a container named test with image nginx")
|
||||
|
||||
assert match is not None
|
||||
assert "docker" in match.command.lower()
|
||||
|
||||
|
||||
class TestCommandMatch:
|
||||
"""Tests for CommandMatch dataclass."""
|
||||
|
||||
def test_command_match_creation(self):
|
||||
from shell_speak.models import CommandMatch, CommandPattern
|
||||
|
||||
pattern = CommandPattern(
|
||||
name="test_pattern",
|
||||
tool="test",
|
||||
description="Test pattern",
|
||||
patterns=["test query"],
|
||||
template="echo test",
|
||||
explanation="Test explanation",
|
||||
)
|
||||
|
||||
match = CommandMatch(
|
||||
pattern=pattern,
|
||||
confidence=0.9,
|
||||
matched_query="test query",
|
||||
command="echo test",
|
||||
explanation="Test explanation",
|
||||
)
|
||||
|
||||
assert match.pattern.name == "test_pattern"
|
||||
assert match.confidence == 0.9
|
||||
assert match.command == "echo test"
|
||||
Reference in New Issue
Block a user