test: add integration test for build_index/search contract (uid/title/chunk/score)

Adds test_build_index_and_search_roundtrip to verify:
- Index building and search round-trip with fixture JSONL
- Result keys exactly match {uid,title,chunk,score} contract
- Anger sutta ranks first for anger-related query

Closes plan-gap: regression coverage for Task 4 dependencies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
marcuspaico
2026-08-14 17:22:13 -07:00
parent 691d2d94f5
commit c14b314107

View File

@@ -1,4 +1,6 @@
from buddhagpt.index import chunk_text
import json
from pathlib import Path
from buddhagpt.index import chunk_text, build_index, search
def test_chunk_text_respects_max_words():
@@ -12,3 +14,42 @@ def test_chunks_overlap():
text = " ".join(f"w{i}" for i in range(400))
a, b = chunk_text(text, max_words=300, overlap=50)
assert a.split()[-50:] == b.split()[:50]
def test_build_index_and_search_roundtrip(tmp_path):
"""Integration test: build index and verify search contract (uid/title/chunk/score keys)."""
# Create fixture JSONL with 2 suttas
anger_sutta = {
"uid": "mn021",
"title": "Discourse on the Simile of the Saw",
"text": "How should one respond to anger and insults? The Buddha taught patience. Even if someone were to cut off your limbs with a saw, a practitioner should cultivate compassion. Anger breeds only suffering. Patience and forgiveness are the antidotes to hatred.",
"collection": "Middle Length Discourses"
}
breathing_sutta = {
"uid": "an10.60",
"title": "On Mindful Breathing",
"text": "Mindful breathing practice develops concentration. Sit in a quiet place and observe the breath entering and leaving. Watch the breath naturally without forcing. This simple practice leads to deep states of peace and clarity.",
"collection": "Numbered Discourses"
}
fixture_jsonl = tmp_path / "fixture.jsonl"
with open(fixture_jsonl, "w") as f:
f.write(json.dumps(anger_sutta) + "\n")
f.write(json.dumps(breathing_sutta) + "\n")
# Build index
db_path = tmp_path / "test_db"
chunk_count = build_index(fixture_jsonl, db_path)
assert chunk_count >= 2, f"Expected at least 2 chunks, got {chunk_count}"
# Search for anger-related content
results = search(db_path, "how to handle anger", k=1)
# Verify contract: exactly one result with required keys
assert len(results) == 1
result = results[0]
assert set(result.keys()) == {"uid", "title", "chunk", "score"}
# Verify anger sutta ranks first (highest relevance)
assert result["uid"] == "mn021", f"Expected mn021 first, got {result['uid']}"
assert "anger" in result["chunk"].lower() or "patience" in result["chunk"].lower()