"""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"