Files
mealie-mcp/tests/test_normalize.py
T

100 lines
3.3 KiB
Python
Raw Normal View History

2026-07-31 07:31:10 +02:00
"""Cases taken from failures verified against the live Mealie instance."""
from __future__ import annotations
import pytest
from mealie_mcp.normalize import (
clean_title,
find_english_leftovers,
has_extraction_failure,
ingredient_display_lines,
looks_mangled,
normalize_for_parser,
slugify,
)
class TestNormalizeForParser:
def test_converts_swedish_decimal_comma(self):
assert normalize_for_parser("4,7 dl basmatiris") == "4.7 dl basmatiris"
def test_leaves_list_commas_alone(self):
assert normalize_for_parser("salt, peppar") == "salt, peppar"
def test_collapses_whitespace(self):
assert normalize_for_parser(" 2 msk olja ") == "2 msk olja"
def test_is_idempotent(self):
once = normalize_for_parser("0,6 dl grädde")
assert normalize_for_parser(once) == once
class TestCleanTitle:
@pytest.mark.parametrize(
"raw,expected",
[
("Fläskfilé med svampsås - se & gör", "Fläskfilé med svampsås"),
("Kycklinggryta | Köket.se", "Kycklinggryta"),
("Pannkakor - se och gör", "Pannkakor"),
("Lax i ugn", "Lax i ugn"),
],
)
def test_strips_campaign_suffixes(self, raw, expected):
assert clean_title(raw) == expected
def test_strips_stacked_suffixes(self):
assert clean_title("Ugnslax - se & gör | Köket.se") == "Ugnslax"
class TestSlugify:
def test_transliterates_swedish_characters(self):
assert slugify("Kycklinggryta med äpple och lök") == "kycklinggryta-med-apple-och-lok"
def test_expands_ampersand(self):
assert slugify("Förrätter & tilltugg") == "forratter-och-tilltugg"
class TestFindEnglishLeftovers:
def test_flags_untranslated_units(self):
assert set(find_english_leftovers("2 cups flour, 1 tbsp butter")) == {"cups", "tbsp"}
def test_clean_swedish_line_passes(self):
assert find_english_leftovers("2 dl vetemjöl, 1 msk smör") == []
def test_does_not_match_inside_swedish_words(self):
# "klyfta" contains no English token; substring matching would be wrong here.
assert find_english_leftovers("1 klyfta vitlök") == []
class TestLooksMangled:
def test_flags_composed_fraction_from_parser(self):
assert looks_mangled("4710 liter basmatiris")
def test_flags_duplicated_unit(self):
assert looks_mangled("2 dl dl grädde")
def test_clean_line_is_not_mangled(self):
assert not looks_mangled("4,7 dl basmatiris")
class TestExtractionFailure:
def test_detects_scraper_placeholder_in_ingredients(self):
recipe = {"recipeIngredient": [{"display": "Could not detect ingredients"}]}
assert has_extraction_failure(recipe)
def test_clean_recipe_passes(self):
recipe = {"recipeIngredient": [{"display": "2 dl grädde"}]}
assert not has_extraction_failure(recipe)
class TestIngredientDisplayLines:
def test_prefers_display_then_note_then_food(self):
recipe = {
"recipeIngredient": [
{"display": "2 dl grädde", "note": "ignored"},
{"display": "", "note": "1 gul lök"},
{"display": "", "note": "", "food": {"name": "salt"}},
]
}
assert ingredient_display_lines(recipe) == ["2 dl grädde", "1 gul lök", "salt"]