mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-02-14 11:53:11 -05:00
feat: Customize Ingredient Plural Handling (#7057)
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
from unittest.mock import MagicMock
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
from pytest import MonkeyPatch
|
||||
|
||||
from mealie.lang.locale_config import LocalePluralFoodHandling
|
||||
from mealie.schema.recipe.recipe_ingredient import (
|
||||
IngredientFood,
|
||||
IngredientUnit,
|
||||
@@ -10,13 +13,13 @@ from mealie.schema.recipe.recipe_ingredient import (
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
["quantity", "quantity_display_decimal", "quantity_display_fraction", "expect_plural_unit", "expect_plural_food"],
|
||||
["quantity", "quantity_display_decimal", "quantity_display_fraction", "expect_plural_unit"],
|
||||
[
|
||||
[0, "", "", False, True],
|
||||
[0.5, "0.5", "¹/₂", False, False],
|
||||
[1, "1", "1", False, False],
|
||||
[1.5, "1.5", "1 ¹/₂", True, True],
|
||||
[2, "2", "2", True, True],
|
||||
[0, "", "", False],
|
||||
[0.5, "0.5", "¹/₂", False],
|
||||
[1, "1", "1", False],
|
||||
[1.5, "1.5", "1 ¹/₂", True],
|
||||
[2, "2", "2", True],
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
@@ -163,6 +166,14 @@ from mealie.schema.recipe.recipe_ingredient import (
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("note", ["very thin", "", None])
|
||||
@pytest.mark.parametrize(
|
||||
"plural_handling",
|
||||
[
|
||||
LocalePluralFoodHandling.ALWAYS,
|
||||
LocalePluralFoodHandling.NEVER,
|
||||
LocalePluralFoodHandling.WITHOUT_UNIT,
|
||||
],
|
||||
)
|
||||
def test_ingredient_display(
|
||||
quantity: float | None,
|
||||
quantity_display_decimal: str,
|
||||
@@ -172,12 +183,32 @@ def test_ingredient_display(
|
||||
note: str | None,
|
||||
expect_display_fraction: bool,
|
||||
expect_plural_unit: bool,
|
||||
expect_plural_food: bool,
|
||||
expected_unit_singular_string: str,
|
||||
expected_unit_plural_string: str,
|
||||
expected_food_singular_string: str,
|
||||
expected_food_plural_string: str,
|
||||
plural_handling: LocalePluralFoodHandling,
|
||||
monkeypatch: MonkeyPatch,
|
||||
):
|
||||
|
||||
mock_locale_cfg = MagicMock()
|
||||
mock_locale_cfg.plural_food_handling = plural_handling
|
||||
monkeypatch.setattr("mealie.schema.recipe.recipe_ingredient.get_locale_context", lambda: ("en-US", mock_locale_cfg))
|
||||
|
||||
# Calculate expect_plural_food based on plural_handling strategy
|
||||
if quantity and quantity <= 1:
|
||||
expect_plural_food = False
|
||||
else:
|
||||
match plural_handling:
|
||||
case LocalePluralFoodHandling.NEVER:
|
||||
expect_plural_food = False
|
||||
case LocalePluralFoodHandling.WITHOUT_UNIT:
|
||||
expect_plural_food = not (quantity and unit)
|
||||
case LocalePluralFoodHandling.ALWAYS:
|
||||
expect_plural_food = True
|
||||
case _:
|
||||
expect_plural_food = False
|
||||
|
||||
expected_components = []
|
||||
if expect_display_fraction:
|
||||
expected_components.append(quantity_display_fraction)
|
||||
|
||||
@@ -4,7 +4,7 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from mealie.lang.providers import local_provider
|
||||
from mealie.lang.providers import get_locale_provider
|
||||
from mealie.services.scraper import cleaner
|
||||
from mealie.services.scraper.scraper_strategies import RecipeScraperOpenGraph
|
||||
from tests import data as test_data
|
||||
@@ -38,7 +38,7 @@ test_cleaner_data = [
|
||||
|
||||
@pytest.mark.parametrize("json_file,num_steps", test_cleaner_data)
|
||||
def test_cleaner_clean(json_file: Path, num_steps):
|
||||
translator = local_provider()
|
||||
translator = get_locale_provider()
|
||||
recipe_data = cleaner.clean(json.loads(json_file.read_text()), translator)
|
||||
assert len(recipe_data.recipe_instructions or []) == num_steps
|
||||
|
||||
@@ -46,7 +46,7 @@ def test_cleaner_clean(json_file: Path, num_steps):
|
||||
def test_html_with_recipe_data():
|
||||
path = test_data.html_healthy_pasta_bake_60759
|
||||
url = "https://www.bbc.co.uk/food/recipes/healthy_pasta_bake_60759"
|
||||
translator = local_provider()
|
||||
translator = get_locale_provider()
|
||||
|
||||
open_graph_strategy = RecipeScraperOpenGraph(url, translator)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ from typing import Any
|
||||
|
||||
import pytest
|
||||
|
||||
from mealie.lang.providers import local_provider
|
||||
from mealie.lang.providers import get_locale_provider
|
||||
from mealie.services.scraper import cleaner
|
||||
|
||||
|
||||
@@ -477,7 +477,7 @@ time_test_cases = (
|
||||
|
||||
@pytest.mark.parametrize("case", time_test_cases, ids=(x.test_id for x in time_test_cases))
|
||||
def test_cleaner_clean_time(case: CleanerCase):
|
||||
translator = local_provider()
|
||||
translator = get_locale_provider()
|
||||
result = cleaner.clean_time(case.input, translator)
|
||||
assert case.expected == result
|
||||
|
||||
@@ -681,5 +681,5 @@ def test_cleaner_clean_nutrition(case: CleanerCase):
|
||||
],
|
||||
)
|
||||
def test_pretty_print_timedelta(t, max_components, max_decimal_places, expected):
|
||||
translator = local_provider()
|
||||
translator = get_locale_provider()
|
||||
assert cleaner.pretty_print_timedelta(t, translator, max_components, max_decimal_places) == expected
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from mealie.core import exceptions
|
||||
from mealie.lang import local_provider
|
||||
from mealie.lang import get_locale_provider
|
||||
|
||||
|
||||
def test_mealie_registered_exceptions() -> None:
|
||||
provider = local_provider()
|
||||
provider = get_locale_provider()
|
||||
|
||||
lookup = exceptions.mealie_registered_exceptions(provider)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
|
||||
from mealie.lang.providers import local_provider
|
||||
from mealie.lang.providers import get_locale_provider
|
||||
from mealie.services.scraper import scraper
|
||||
from tests.utils.recipe_data import RecipeSiteTestCase, get_recipe_test_cases
|
||||
|
||||
@@ -19,7 +19,7 @@ and then use this test case by removing the `@pytest.mark.skip` and than testing
|
||||
@pytest.mark.parametrize("recipe_test_data", test_cases)
|
||||
@pytest.mark.asyncio
|
||||
async def test_recipe_parser(recipe_test_data: RecipeSiteTestCase):
|
||||
translator = local_provider()
|
||||
translator = get_locale_provider()
|
||||
recipe, _ = await scraper.create_from_html(recipe_test_data.url, translator)
|
||||
|
||||
assert recipe.slug == recipe_test_data.expected_slug
|
||||
|
||||
Reference in New Issue
Block a user