diff --git a/tests/test_explainer.py b/tests/test_explainer.py new file mode 100644 index 0000000..dc07b2b --- /dev/null +++ b/tests/test_explainer.py @@ -0,0 +1,127 @@ +"""Tests for the explainer module.""" + +import pytest +from cli_explain_fix.parser import ErrorParser, ParsedError +from cli_explain_fix.explainer import Explainer +from cli_explain_fix.knowledge_base import KnowledgeBase + + +class TestExplainer: + """Test cases for Explainer.""" + + def setup_method(self): + """Set up explainer instance for each test.""" + self.parser = ErrorParser() + self.kb = KnowledgeBase() + self.explainer = Explainer(self.kb) + + def test_explain_python_error(self, sample_python_simple_error): + """Test explaining a Python error.""" + parsed = self.parser.parse(sample_python_simple_error) + explanation = self.explainer.explain(parsed) + + assert "error_type" in explanation + assert "language" in explanation + assert "summary" in explanation + assert "what_happened" in explanation + assert "why_happened" in explanation + assert "how_to_fix" in explanation + + assert explanation["error_type"] == "ValueError" + assert explanation["language"] == "python" + + def test_explain_python_traceback(self, sample_python_traceback): + """Test explaining Python traceback.""" + parsed = self.parser.parse(sample_python_traceback) + explanation = self.explainer.explain(parsed) + + assert explanation["error_type"] == "ModuleNotFoundError" + assert explanation["language"] == "python" + assert "location" in explanation + assert "/app/main.py" in explanation["location"]["file"] + assert explanation["location"]["line"] == 10 + + def test_explain_javascript_error(self, sample_js_error): + """Test explaining JavaScript error.""" + parsed = self.parser.parse(sample_js_error) + explanation = self.explainer.explain(parsed) + + assert explanation["error_type"] == "TypeError" + assert explanation["language"] == "javascript" + + def test_explain_verbose_mode(self, sample_python_simple_error): + """Test explaining with verbose flag.""" + parsed = self.parser.parse(sample_python_simple_error) + explanation = self.explainer.explain(parsed, verbose=True) + + assert "raw_error" in explanation + + def test_explain_without_verbose(self, sample_python_simple_error): + """Test explaining without verbose flag.""" + parsed = self.parser.parse(sample_python_simple_error) + explanation = self.explainer.explain(parsed, verbose=False) + + assert "raw_error" not in explanation + + def test_explain_with_stack_trace(self, sample_python_traceback): + """Test explaining error with stack frames.""" + parsed = self.parser.parse(sample_python_traceback) + explanation = self.explainer.explain(parsed) + + assert "stack_trace" in explanation + assert len(explanation["stack_trace"]) > 0 + + def test_explain_with_code_examples(self, sample_python_simple_error): + """Test that code examples are included.""" + parsed = self.parser.parse(sample_python_simple_error) + explanation = self.explainer.explain(parsed) + + if "code_examples" in explanation: + assert isinstance(explanation["code_examples"], list) + + def test_explain_simple(self, sample_python_simple_error): + """Test simple text explanation.""" + result = self.explainer.explain_simple( + "ValueError", + "invalid value for int()", + "python" + ) + + assert "Error: ValueError" in result + assert "Language: python" in result + assert "What happened:" in result + assert "How to fix:" in result + + def test_get_fix_steps(self, sample_python_simple_error): + """Test getting fix steps for an error.""" + parsed = self.parser.parse(sample_python_simple_error) + steps = self.explainer.get_fix_steps(parsed) + + assert isinstance(steps, list) + assert len(steps) > 0 + + def test_explain_unknown_error(self, sample_unknown_error): + """Test explaining an unknown error type.""" + parsed = self.parser.parse(sample_unknown_error) + explanation = self.explainer.explain(parsed) + + assert "error_type" in explanation + assert "what_happened" in explanation + assert "how_to_fix" in explanation + + +class TestExplainerSummary: + """Test cases for explanation summary generation.""" + + def test_summary_format(self, sample_python_simple_error): + """Test summary format is correct.""" + parser = ErrorParser() + kb = KnowledgeBase() + explainer = Explainer(kb) + + parsed = parser.parse(sample_python_simple_error) + explanation = explainer.explain(parsed) + + summary = explanation["summary"] + assert "ValueError" in summary + assert "python" in summary