fix(parser): adjust Brute Parser confidence logic and add unit tests

This commit is contained in:
Skye Samuels 2025-08-06 22:33:10 +00:00
commit 3be5d2614a
2 changed files with 51 additions and 5 deletions

View file

@ -12,6 +12,8 @@ from mealie.schema.recipe.recipe_ingredient import (
CreateIngredientFood,
CreateIngredientUnit,
IngredientConfidence,
IngredientFood,
IngredientUnit,
ParsedIngredient,
RegisteredParser,
)
@ -28,11 +30,11 @@ class BruteForceParser(ABCIngredientParser):
Brute force ingredient parser.
"""
async def parse_one(self, ingredient: str) -> ParsedIngredient:
bfi = brute.parse(ingredient, self)
async def parse_one(self, ingredient_string: str) -> ParsedIngredient:
bfi = brute.parse(ingredient_string, self)
parsed_ingredient = ParsedIngredient(
input=ingredient,
input=ingredient_string,
ingredient=RecipeIngredient(
unit=CreateIngredientUnit(name=bfi.unit),
food=CreateIngredientFood(name=bfi.food),
@ -45,8 +47,12 @@ class BruteForceParser(ABCIngredientParser):
qty_conf = 1
note_conf = 1
unit_conf = 1 if bfi.unit is None or matched_ingredient.ingredient.unit else 0
food_conf = 1 if bfi.food is None or matched_ingredient.ingredient.food else 0
unit_obj = matched_ingredient.ingredient.unit
food_obj = matched_ingredient.ingredient.food
unit_conf = 1 if bfi.unit is None or isinstance(unit_obj, IngredientUnit) else 0
food_conf = 1 if bfi.food is None or isinstance(food_obj, IngredientFood) else 0
avg_conf = (qty_conf + unit_conf + food_conf + note_conf) / 4

View file

@ -226,6 +226,46 @@ def test_brute_parser(
assert not comment
@pytest.mark.parametrize(
"unit, food, expect_unit_match, expect_food_match, expected_avg",
[
pytest.param("Cups", "potatoes", True, True, 1.0, id="all matched"),
pytest.param("Cups", "veryuniquefood", True, False, 0.75, id="unit matched only"),
pytest.param("veryuniqueunit", "potatoes", False, True, 0.75, id="food matched only"),
pytest.param("veryuniqueunit", "veryuniquefood", False, False, 0.5, id="neither matched"),
],
)
def test_brute_parser_confidence(
unit: str,
food: str,
expect_unit_match: bool,
expect_food_match: bool,
expected_avg: float,
unique_local_group_id: UUID4,
parsed_ingredient_data: tuple[list[IngredientFood], list[IngredientUnit]],
):
input_str = f"1 {unit} {food}"
with session_context() as session:
original_loop = asyncio.get_event_loop()
try:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
parser = get_parser(RegisteredParser.brute, unique_local_group_id, session)
parsed = loop.run_until_complete(parser.parse_one(input_str))
finally:
loop.close()
asyncio.set_event_loop(original_loop)
conf = parsed.confidence
assert conf.quantity == 1
assert conf.comment == 1
assert conf.unit == (1 if expect_unit_match or not unit else 0)
assert conf.food == (1 if expect_food_match or not food else 0)
assert conf.average == expected_avg
@pytest.mark.parametrize(
"input, expected_unit_name, expected_food_name, expect_unit_match, expect_food_match",
(