File size: 7,151 Bytes
d7228c8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | """
Unit tests for LawSLM Chat Engine:
- IntentDetector: classifies user prompts into correct intent categories
- KnowledgeEngine: generates natural, dynamic responses (no generic templates)
- ConversationMemory: tracks multi-turn history and resolves coreferences
- ResponseValidator: validates quality and rejects template artifacts
"""
import pytest
from slm.chat.intent import IntentDetector, KnowledgeEngine, IntentType
from slm.chat.memory import ConversationMemory
from slm.chat.validator import ResponseValidator
class TestIntentDetector:
def test_identity(self):
assert IntentDetector.detect_intent("Who created you?") == IntentType.IDENTITY
assert IntentDetector.detect_intent("who made you") == IntentType.IDENTITY
def test_about_self(self):
assert IntentDetector.detect_intent("Who are you?") == IntentType.ABOUT_SELF
assert IntentDetector.detect_intent("Tell me about yourself") == IntentType.ABOUT_SELF
assert IntentDetector.detect_intent("What can you do?") == IntentType.ABOUT_SELF
def test_greeting(self):
assert IntentDetector.detect_intent("Hello") == IntentType.GREETING
assert IntentDetector.detect_intent("hi") == IntentType.GREETING
def test_thanks(self):
assert IntentDetector.detect_intent("Thank you") == IntentType.THANKS
assert IntentDetector.detect_intent("thanks") == IntentType.THANKS
def test_farewell(self):
assert IntentDetector.detect_intent("goodbye") == IntentType.FAREWELL
def test_pdf_generation(self):
assert IntentDetector.detect_intent("Generate a PDF report") == IntentType.PDF_GENERATION
def test_legal(self):
assert IntentDetector.detect_intent("Explain Section 420 IPC") == IntentType.LEGAL
def test_programming(self):
assert IntentDetector.detect_intent("Write Python code for sorting") == IntentType.PROGRAMMING
def test_finance(self):
assert IntentDetector.detect_intent("Calculate loan interest for 10 lakh at 12%") == IntentType.FINANCE
def test_math(self):
assert IntentDetector.detect_intent("Calculate 25 * 4 + 10") == IntentType.MATH
def test_science(self):
assert IntentDetector.detect_intent("Explain photosynthesis") == IntentType.SCIENCE
class TestKnowledgeEngine:
def test_identity_response_mentions_amit(self):
result = KnowledgeEngine.generate_response("Who created you?", IntentType.IDENTITY)
assert "Amit Kumar" in result["content"]
assert result["has_pdf"] is False
def test_about_self_response(self):
result = KnowledgeEngine.generate_response("Who are you?", IntentType.ABOUT_SELF)
assert "LawSLM" in result["content"]
def test_greeting_response_is_natural(self):
result = KnowledgeEngine.generate_response("Hello", IntentType.GREETING)
assert "Hello" in result["content"]
# Must NOT contain generic template phrases
assert "Analysis & Assistance" not in result["content"]
assert "Core Concept" not in result["content"]
def test_thanks_response(self):
result = KnowledgeEngine.generate_response("Thank you", IntentType.THANKS)
assert "welcome" in result["content"].lower()
def test_pdf_has_metadata(self):
result = KnowledgeEngine.generate_response("Generate PDF report", IntentType.PDF_GENERATION)
assert result["has_pdf"] is True
assert result["pdf_meta"] is not None
def test_finance_with_numbers(self):
result = KnowledgeEngine.generate_response(
"Calculate loan interest for 100000 at 12% for 2 years", IntentType.FINANCE
)
assert "₹" in result["content"] or "Interest" in result["content"]
def test_math_calculation(self):
result = KnowledgeEngine.generate_response("Calculate 25 * 4 + 10", IntentType.MATH)
content = result["content"]
assert "110" in content # 25*4+10 = 110
def test_legal_section_420(self):
result = KnowledgeEngine.generate_response("Explain Section 420 IPC", IntentType.LEGAL)
assert "420" in result["content"]
assert "cheat" in result["content"].lower() or "Cheating" in result["content"]
def test_python_explanation(self):
result = KnowledgeEngine.generate_response("What is Python?", IntentType.GENERAL_QA)
assert "Python" in result["content"]
def test_no_generic_template_in_any_response(self):
"""Verify no response uses banned template phrases."""
test_prompts = [
("Hello", IntentType.GREETING),
("Who are you?", IntentType.ABOUT_SELF),
("Explain gravity", IntentType.SCIENCE),
("Write Python code", IntentType.PROGRAMMING),
]
banned = ["Analysis & Assistance", "Core Concept", "Key Consideration"]
for prompt, intent in test_prompts:
result = KnowledgeEngine.generate_response(prompt, intent)
for phrase in banned:
assert phrase not in result["content"], (
f"Banned phrase '{phrase}' found in response to '{prompt}'"
)
class TestConversationMemory:
def test_add_and_retrieve(self):
mem = ConversationMemory()
mem.add_message("user", "Hello")
mem.add_message("assistant", "Hi! How can I help?")
history = mem.get_history()
assert len(history) == 2
assert history[0]["role"] == "user"
assert history[1]["role"] == "assistant"
def test_coreference_resolution(self):
mem = ConversationMemory()
mem.add_message("user", "What is Python?")
mem.add_message("assistant", "Python is a programming language.")
resolved = mem.resolve_coreference("Tell me more about this")
assert "python" in resolved.lower() or "this" in resolved.lower()
class TestResponseValidator:
def test_valid_text_passes(self):
is_valid, cleaned = ResponseValidator.validate_response("Hello! I am LawSLM.")
assert is_valid is True
assert "LawSLM" in cleaned
def test_empty_text_fails(self):
is_valid, _ = ResponseValidator.validate_response("")
assert is_valid is False
def test_unk_tokens_removed(self):
is_valid, cleaned = ResponseValidator.validate_response("Hello <unk> world <pad>")
assert is_valid is True
assert "<unk>" not in cleaned
assert "<pad>" not in cleaned
def test_repetitive_loop_cleaned(self):
is_valid, cleaned = ResponseValidator.validate_response("the the the the the answer")
assert is_valid is True
assert cleaned.count("the") < 4
def test_template_phrases_stripped(self):
is_valid, cleaned = ResponseValidator.validate_response(
"Analysis & Assistance\n\nHello, I am LawSLM."
)
assert is_valid is True
assert "Analysis & Assistance" not in cleaned
def test_unbalanced_code_fence_fixed(self):
is_valid, cleaned = ResponseValidator.validate_response("```python\nprint('hello')")
assert is_valid is True
assert cleaned.count("```") % 2 == 0
|