yannsay's picture
Deploy clean to build-small-hackathon org (32B Qwen, step-3 table)
aa1d0aa verified
Raw
History Blame Contribute Delete
3.63 kB
import pytest
from core.ports import ChatModel
from core.schemas import RouteResponse
from core.route import (
route_from_chips,
route_from_message,
resolve_route,
step1_trace_line,
Step1Result,
)
class StubChatModel(ChatModel):
"""Records the schema it was called with; returns a canned RouteResponse."""
def __init__(self, canned: RouteResponse):
self._canned = canned
self.calls = []
def structured(self, messages, schema):
self.calls.append((messages, schema))
return self._canned
def complete(self, messages): # pragma: no cover - unused here
raise NotImplementedError
def test_route_from_chips_is_identity():
r = route_from_chips(["WASH"], ["Humanitarian Conditions"], ["Context"])
assert isinstance(r, RouteResponse)
assert r.sectors == ["WASH"]
assert r.lens == ["Humanitarian Conditions"]
assert r.type == ["Context"]
def test_route_from_message_calls_model_with_route_schema():
canned = RouteResponse(sectors=["WASH"], lens=[], type=[])
stub = StubChatModel(canned)
r = route_from_message("water access in Aleppo?", stub)
assert r is canned
assert len(stub.calls) == 1
_messages, schema = stub.calls[0]
assert schema is RouteResponse
def test_route_from_message_prompt_contains_axis_labels():
stub = StubChatModel(RouteResponse(sectors=[], lens=[], type=[]))
route_from_message("q", stub)
messages, _schema = stub.calls[0]
blob = " ".join(m["content"] for m in messages)
assert "WASH" in blob and "Humanitarian Conditions" in blob and "Context" in blob
def test_resolve_route_message_partitions_out_of_scope():
canned = RouteResponse(sectors=["WASH", "Health"], lens=["Impact"], type=[])
res = resolve_route("message", "q", [], [], [], StubChatModel(canned))
assert isinstance(res, Step1Result)
assert res.route.sectors == ["WASH", "Health"] # full faithful list preserved
assert res.in_scope == ["WASH"]
assert res.out_of_scope == ["Health"]
def test_resolve_route_chips_no_model_needed():
res = resolve_route("chips", "", ["Food Security"], ["At Risk"], ["Context"], None)
assert res.route.sectors == ["Food Security"]
assert res.in_scope == ["Food Security"]
assert res.out_of_scope == []
def test_resolve_route_empty_question_raises():
with pytest.raises(ValueError, match="question"):
resolve_route("message", " ", [], [], [], StubChatModel(
RouteResponse(sectors=[], lens=[], type=[])))
def test_resolve_route_zero_in_scope_passes_through():
canned = RouteResponse(sectors=["Health"], lens=[], type=[])
res = resolve_route("message", "q", [], [], [], StubChatModel(canned))
assert res.in_scope == []
assert res.out_of_scope == ["Health"]
def test_resolve_route_chips_zero_in_scope_passes_through():
res = resolve_route("chips", "", [], ["At Risk"], [], None)
assert res.in_scope == []
def test_step1_trace_line_with_lens():
res = Step1Result(
route=RouteResponse(sectors=["WASH", "Food Security"], lens=["Humanitarian Conditions"], type=[]),
in_scope=["WASH", "Food Security"],
out_of_scope=[],
)
line = step1_trace_line(res)
assert line == "Step 1 β€” Understood request β†’ WASH, Food Security (lens: Humanitarian Conditions)"
def test_step1_trace_line_without_lens():
res = Step1Result(
route=RouteResponse(sectors=["WASH"], lens=[], type=[]),
in_scope=["WASH"],
out_of_scope=["Health"],
)
assert step1_trace_line(res) == "Step 1 β€” Understood request β†’ WASH, Health"