Public Access
feat: rapidfuzz-based ingredient<->grocery matcher with manual-pin preservation
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
import pytest
|
||||
|
||||
from app.services.matcher import build_match_pool, rank_candidates
|
||||
|
||||
|
||||
def test_build_match_pool_includes_aliases() -> None:
|
||||
ingredients = [
|
||||
{"id": "i1", "name": "Chicken Thighs", "aliases": ["chicken thigh"]},
|
||||
{"id": "i2", "name": "Chicken Breast", "aliases": []},
|
||||
]
|
||||
pool = build_match_pool(ingredients)
|
||||
# 1 name + 1 alias for i1, 1 name for i2 = 3 entries
|
||||
assert len(pool) == 3
|
||||
assert ("Chicken Thighs", "i1") in pool
|
||||
assert ("chicken thigh", "i1") in pool
|
||||
|
||||
|
||||
def test_rank_candidates_top_n_with_threshold() -> None:
|
||||
pool = [
|
||||
("Chicken Thighs", "i1"),
|
||||
("chicken thigh", "i1"),
|
||||
("Chicken Breast", "i2"),
|
||||
("Pork Chops", "i3"),
|
||||
]
|
||||
ranked = rank_candidates(
|
||||
target="Foster Farms Chicken Thighs Family Pack",
|
||||
pool=pool,
|
||||
top_n=3,
|
||||
threshold=0.75,
|
||||
)
|
||||
ids = [item["ingredient_id"] for item in ranked]
|
||||
assert ids[0] == "i1"
|
||||
assert all(item["confidence"] >= 0.75 for item in ranked)
|
||||
|
||||
|
||||
def test_rank_candidates_drops_below_threshold() -> None:
|
||||
pool = [("Pork Chops", "i3")]
|
||||
ranked = rank_candidates(
|
||||
target="Frosted Flakes Cereal 18oz",
|
||||
pool=pool,
|
||||
top_n=3,
|
||||
threshold=0.75,
|
||||
)
|
||||
assert ranked == []
|
||||
Reference in New Issue
Block a user