""" tests/test_eval_metrics.py Tests for evaluation metrics (no GPU required). """ import sys sys.path.insert(0, "src") import pytest from ankahi.eval.metrics import compute_bleu, compute_chrf class TestBleu: def test_perfect_score(self): hyps = ["the cat sat on the mat"] refs = ["the cat sat on the mat"] score = compute_bleu(hyps, refs) assert score > 90.0 def test_zero_score(self): hyps = ["xyz xyz xyz xyz"] refs = ["the cat sat on the mat"] score = compute_bleu(hyps, refs) assert score == 0.0 def test_partial_match(self): hyps = ["I want water please"] refs = ["I want some water"] score = compute_bleu(hyps, refs) assert 0.0 < score < 100.0 def test_corpus_level(self): hyps = ["Mujhe abhi pani chahiye", "Mama jaldi yahan aao"] refs = ["Mujhe abhi paani chahiye", "Mummy jaldi yahan aao"] score = compute_bleu(hyps, refs) assert score > 0.0 def test_empty_strings(self): hyps = [""] refs = ["something"] # sacrebleu handles empty gracefully score = compute_bleu(hyps, refs) assert score == 0.0 class TestChrF: def test_perfect_score(self): hyps = ["मुझे पानी चाहिए"] refs = ["मुझे पानी चाहिए"] score = compute_chrf(hyps, refs) assert score > 95.0 def test_partial_indic(self): hyps = ["Mujhe pani chahiye"] refs = ["Mujhe paani chahida"] score = compute_chrf(hyps, refs) # chrF++ rewards character-level overlaps assert score > 30.0 def test_corpus_level(self): hyps = ["Mama mujhe bhookh lagi hai", "I am tired please"] refs = ["Mummy mujhe bhookh lagi hai", "I am very tired"] score = compute_chrf(hyps, refs) assert score > 40.0 def test_returns_float(self): score = compute_chrf(["test"], ["reference"]) assert isinstance(score, float) class TestPersonaModule: def test_all_personas_present(self): from ankahi.data.persona import PERSONAS assert len(PERSONAS) == 5 for pid in ["ananya", "arjun", "priya", "rohan", "zara"]: assert pid in PERSONAS def test_persona_system_prompt_nonempty(self): from ankahi.data.persona import PERSONAS for pid, persona in PERSONAS.items(): prompt = persona.to_system_prompt() assert len(prompt) > 50 assert persona.name in prompt assert persona.city in prompt def test_persona_serialization(self): from ankahi.data.persona import PERSONAS, Persona import json arjun = PERSONAS["arjun"] d = arjun.to_dict() assert d["name"] == "Arjun" assert d["primary_language"] == "pa" assert isinstance(d["secondary_languages"], list) def test_arjun_language_mix(self): from ankahi.data.persona import PERSONAS arjun = PERSONAS["arjun"] assert arjun.primary_language == "pa" assert "hi" in arjun.secondary_languages assert "en" in arjun.secondary_languages def test_mediapipe_lora_rank_constraint(self): """Remind us that persona lora rank must be 4 or 8.""" # This test documents the MediaPipe constraint MEDIAPIPE_SUPPORTED_RANKS = [4, 8] PERSONA_RANK = 8 # from stage2_persona.py assert PERSONA_RANK in MEDIAPIPE_SUPPORTED_RANKS, \ f"Persona LoRA rank {PERSONA_RANK} is not supported by MediaPipe ({MEDIAPIPE_SUPPORTED_RANKS})"