"""Tests for sage.core.models — dataclass construction and methods.""" from sage.core.models import ( ExplanationResult, EvidenceQuality, NewItem, ProductScore, RetrievedChunk, StreamingExplanation, ) class TestNewItem: def test_minimal_construction(self): item = NewItem(product_id="P1", title="Test Product") assert item.product_id == "P1" assert item.title == "Test Product" assert item.brand is None assert item.category is None def test_full_construction(self): item = NewItem( product_id="P1", title="Test Product", description="A test", category="Electronics", price=29.99, features=["feature1"], brand="TestBrand", ) assert item.brand == "TestBrand" assert item.price == 29.99 class TestProductScore: def test_top_evidence_returns_highest(self): chunks = [ RetrievedChunk( text="low", score=0.5, product_id="P1", rating=4.0, review_id="r1" ), RetrievedChunk( text="high", score=0.9, product_id="P1", rating=4.0, review_id="r2" ), RetrievedChunk( text="mid", score=0.7, product_id="P1", rating=4.0, review_id="r3" ), ] product = ProductScore( product_id="P1", score=0.9, chunk_count=3, avg_rating=4.0, evidence=chunks, ) assert product.top_evidence.text == "high" assert product.top_evidence.score == 0.9 def test_top_evidence_empty(self): product = ProductScore( product_id="P1", score=0.5, chunk_count=0, avg_rating=4.0, ) assert product.top_evidence is None class TestExplanationResult: def test_to_evidence_dicts(self): result = ExplanationResult( explanation="test", product_id="P1", query="q", evidence_texts=["text1", "text2"], evidence_ids=["id1", "id2"], tokens_used=100, model="test-model", ) dicts = result.to_evidence_dicts() assert len(dicts) == 2 assert dicts[0] == {"id": "id1", "text": "text1"} assert dicts[1] == {"id": "id2", "text": "text2"} def test_to_evidence_dicts_empty(self): result = ExplanationResult( explanation="test", product_id="P1", query="q", evidence_texts=[], evidence_ids=[], tokens_used=0, model="test-model", ) assert result.to_evidence_dicts() == [] class TestStreamingExplanation: def test_collects_tokens(self): tokens = ["Hello", " ", "world"] stream = StreamingExplanation( token_iterator=iter(tokens), product_id="P1", query="q", evidence_texts=["ev"], evidence_ids=["id1"], model="test", ) collected = list(stream) assert collected == tokens result = stream.get_complete_result() assert result.explanation == "Hello world" assert result.product_id == "P1" def test_empty_stream(self): stream = StreamingExplanation( token_iterator=iter([]), product_id="P1", query="q", evidence_texts=[], evidence_ids=[], model="test", ) list(stream) result = stream.get_complete_result() assert result.explanation == "" class TestEvidenceQuality: def test_sufficient(self): eq = EvidenceQuality( is_sufficient=True, chunk_count=3, total_tokens=150, top_score=0.9, ) assert eq.is_sufficient is True assert eq.failure_reason is None def test_insufficient_with_reason(self): eq = EvidenceQuality( is_sufficient=False, chunk_count=1, total_tokens=20, top_score=0.3, failure_reason="insufficient_chunks", ) assert eq.is_sufficient is False assert eq.failure_reason == "insufficient_chunks"