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>
56 lines
2.3 KiB
Python
56 lines
2.3 KiB
Python
import json
|
|
from pathlib import Path
|
|
from buddhagpt.index import chunk_text, build_index, search
|
|
|
|
|
|
def test_chunk_text_respects_max_words():
|
|
text = " ".join(f"w{i}" for i in range(700))
|
|
chunks = chunk_text(text, max_words=300, overlap=50)
|
|
assert all(len(c.split()) <= 300 for c in chunks)
|
|
assert len(chunks) == 3
|
|
|
|
|
|
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()
|