mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2025-12-23 18:29:23 -05:00
updated pytest and fixed ingredient parser
This commit is contained in:
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
||||
./cookbook/static
|
||||
./staticfiles
|
||||
key: |
|
||||
${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.node-version }}-collectstatic-${{ hashFiles('**/*.css', '**/*.js', 'vue/src/*') }}
|
||||
${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.node-version }}-collectstatic-${{ hashFiles('**/*.css', '**/*.js', 'vue3/src/*') }}
|
||||
|
||||
# Build Vue frontend & Dependencies
|
||||
- name: Set up Node ${{ matrix.node-version }}
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -89,3 +89,5 @@ venv/
|
||||
.idea/easy-i18n.xml
|
||||
cookbook/static/vue3
|
||||
vue3/node_modules
|
||||
cookbook/tests/other/docs/reports/tests/tests.html
|
||||
cookbook/tests/other/docs/reports/tests/pytest.xml
|
||||
|
||||
@@ -211,44 +211,46 @@ class IngredientParser:
|
||||
# three arguments if it already has a unit there can't be
|
||||
# a fraction for the amount
|
||||
if len(tokens) > 2:
|
||||
never_unit_applied = False
|
||||
if not self.ignore_rules:
|
||||
tokens, never_unit_applied = self.automation.apply_never_unit_automation(tokens)
|
||||
if never_unit_applied:
|
||||
unit = tokens[1]
|
||||
food, note = self.parse_food(tokens[2:])
|
||||
else:
|
||||
try:
|
||||
if unit is not None:
|
||||
# a unit is already found, no need to try the second argument for a fraction
|
||||
# probably not the best method to do it, but I didn't want to make an if check and paste the exact same thing in the else as already is in the except
|
||||
raise ValueError
|
||||
# try to parse second argument as amount and add that, in case of '2 1/2' or '2 ½'
|
||||
if tokens[1]:
|
||||
amount += self.parse_fraction(tokens[1])
|
||||
# assume that units can't end with a comma
|
||||
if len(tokens) > 3 and not tokens[2].endswith(','):
|
||||
# try to use third argument as unit and everything else as food, use everything as food if it fails
|
||||
try:
|
||||
food, note = self.parse_food(tokens[3:])
|
||||
unit = tokens[2]
|
||||
except ValueError:
|
||||
food, note = self.parse_food(tokens[2:])
|
||||
else:
|
||||
|
||||
if never_unit_applied:
|
||||
unit = tokens[1]
|
||||
food, note = self.parse_food(tokens[2:])
|
||||
else:
|
||||
try:
|
||||
if unit is not None:
|
||||
# a unit is already found, no need to try the second argument for a fraction
|
||||
# probably not the best method to do it, but I didn't want to make an if check and paste the exact same thing in the else as already is in the except
|
||||
raise ValueError
|
||||
# try to parse second argument as amount and add that, in case of '2 1/2' or '2 ½'
|
||||
if tokens[1]:
|
||||
amount += self.parse_fraction(tokens[1])
|
||||
# assume that units can't end with a comma
|
||||
if len(tokens) > 3 and not tokens[2].endswith(','):
|
||||
# try to use third argument as unit and everything else as food, use everything as food if it fails
|
||||
try:
|
||||
food, note = self.parse_food(tokens[3:])
|
||||
unit = tokens[2]
|
||||
except ValueError:
|
||||
food, note = self.parse_food(tokens[2:])
|
||||
except ValueError:
|
||||
# assume that units can't end with a comma
|
||||
if not tokens[1].endswith(','):
|
||||
# try to use second argument as unit and everything else as food, use everything as food if it fails
|
||||
try:
|
||||
food, note = self.parse_food(tokens[2:])
|
||||
if unit is None:
|
||||
unit = tokens[1]
|
||||
else:
|
||||
note = tokens[1]
|
||||
except ValueError:
|
||||
food, note = self.parse_food(tokens[1:])
|
||||
else:
|
||||
else:
|
||||
food, note = self.parse_food(tokens[2:])
|
||||
except ValueError:
|
||||
# assume that units can't end with a comma
|
||||
if not tokens[1].endswith(','):
|
||||
# try to use second argument as unit and everything else as food, use everything as food if it fails
|
||||
try:
|
||||
food, note = self.parse_food(tokens[2:])
|
||||
if unit is None:
|
||||
unit = tokens[1]
|
||||
else:
|
||||
note = tokens[1]
|
||||
except ValueError:
|
||||
food, note = self.parse_food(tokens[1:])
|
||||
else:
|
||||
food, note = self.parse_food(tokens[1:])
|
||||
else:
|
||||
# only two arguments, first one is the amount
|
||||
# which means this is the food
|
||||
@@ -269,6 +271,7 @@ class IngredientParser:
|
||||
|
||||
if food and not self.ignore_rules:
|
||||
food = self.automation.apply_food_automation(food)
|
||||
|
||||
if len(food) > Food._meta.get_field('name').max_length: # test if food name is to long
|
||||
# try splitting it at a space and taking only the first arg
|
||||
if len(food.split()) > 1 and len(food.split()[0]) < Food._meta.get_field('name').max_length:
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><testsuites name="pytest tests"><testsuite name="pytest" errors="4" failures="0" skipped="0" tests="4" time="34.750" timestamp="2025-07-17T12:15:15.274960+02:00" hostname="DESKTOP-RM10LP5"><testcase classname="cookbook.tests.other.test_automations" name="test_never_unit_automation[arg0]" time="22.035"><error message="failed on setup with "TypeError: type 'Factory' is not subscriptable"">args = ()
|
||||
kwargs = {'request': <SubRequest 'space_1' for <Function test_never_unit_automation[arg0]>>}
|
||||
k = 'space_1__name'
|
||||
|
||||
@functools.wraps(fixture_function)
|
||||
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
||||
for k in set(kwargs.keys()) - function_args:
|
||||
del kwargs[k]
|
||||
> return fixture_function(*args, **kwargs)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
..\..\..\venv\Lib\site-packages\pytest_factoryboy\fixturegen.py:88:
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
..\..\..\venv\Lib\site-packages\pytest_factoryboy\fixturegen.py:49: in fn
|
||||
return function(*args, **kwargs)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|
||||
request = <SubRequest 'space_1' for <Function test_never_unit_automation[arg0]>>
|
||||
factory_name = 'space_factory'
|
||||
|
||||
def model_fixture(request: SubRequest, factory_name: str) -> object:
|
||||
"""Model fixture implementation."""
|
||||
factoryboy_request: FactoryboyRequest = request.getfixturevalue("factoryboy_request")
|
||||
|
||||
# Try to evaluate as much post-generation dependencies as possible
|
||||
factoryboy_request.evaluate(request)
|
||||
|
||||
assert request.fixturename # NOTE: satisfy mypy
|
||||
fixture_name = request.fixturename
|
||||
prefix = "".join((fixture_name, SEPARATOR))
|
||||
|
||||
factory_class: type[Factory[object]] = request.getfixturevalue(factory_name)
|
||||
|
||||
# Create model fixture instance
|
||||
> NewFactory: type[Factory[object]] = cast(type[Factory[object]], type("Factory", (factory_class,), {}))
|
||||
^^^^^^^^^^^^^^^
|
||||
E TypeError: type 'Factory' is not subscriptable
|
||||
|
||||
..\..\..\venv\Lib\site-packages\pytest_factoryboy\fixture.py:360: TypeError</error></testcase><testcase classname="cookbook.tests.other.test_automations" name="test_never_unit_automation[arg2]" time="22.047"><error message="failed on setup with "TypeError: type 'Factory' is not subscriptable"">args = ()
|
||||
kwargs = {'request': <SubRequest 'space_1' for <Function test_never_unit_automation[arg2]>>}
|
||||
k = 'space_1__name'
|
||||
|
||||
@functools.wraps(fixture_function)
|
||||
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
||||
for k in set(kwargs.keys()) - function_args:
|
||||
del kwargs[k]
|
||||
> return fixture_function(*args, **kwargs)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
..\..\..\venv\Lib\site-packages\pytest_factoryboy\fixturegen.py:88:
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
..\..\..\venv\Lib\site-packages\pytest_factoryboy\fixturegen.py:49: in fn
|
||||
return function(*args, **kwargs)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|
||||
request = <SubRequest 'space_1' for <Function test_never_unit_automation[arg2]>>
|
||||
factory_name = 'space_factory'
|
||||
|
||||
def model_fixture(request: SubRequest, factory_name: str) -> object:
|
||||
"""Model fixture implementation."""
|
||||
factoryboy_request: FactoryboyRequest = request.getfixturevalue("factoryboy_request")
|
||||
|
||||
# Try to evaluate as much post-generation dependencies as possible
|
||||
factoryboy_request.evaluate(request)
|
||||
|
||||
assert request.fixturename # NOTE: satisfy mypy
|
||||
fixture_name = request.fixturename
|
||||
prefix = "".join((fixture_name, SEPARATOR))
|
||||
|
||||
factory_class: type[Factory[object]] = request.getfixturevalue(factory_name)
|
||||
|
||||
# Create model fixture instance
|
||||
> NewFactory: type[Factory[object]] = cast(type[Factory[object]], type("Factory", (factory_class,), {}))
|
||||
^^^^^^^^^^^^^^^
|
||||
E TypeError: type 'Factory' is not subscriptable
|
||||
|
||||
..\..\..\venv\Lib\site-packages\pytest_factoryboy\fixture.py:360: TypeError</error></testcase><testcase classname="cookbook.tests.other.test_automations" name="test_never_unit_automation[arg3]" time="22.106"><error message="failed on setup with "TypeError: type 'Factory' is not subscriptable"">args = ()
|
||||
kwargs = {'request': <SubRequest 'space_1' for <Function test_never_unit_automation[arg3]>>}
|
||||
k = 'space_1__name'
|
||||
|
||||
@functools.wraps(fixture_function)
|
||||
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
||||
for k in set(kwargs.keys()) - function_args:
|
||||
del kwargs[k]
|
||||
> return fixture_function(*args, **kwargs)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
..\..\..\venv\Lib\site-packages\pytest_factoryboy\fixturegen.py:88:
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
..\..\..\venv\Lib\site-packages\pytest_factoryboy\fixturegen.py:49: in fn
|
||||
return function(*args, **kwargs)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|
||||
request = <SubRequest 'space_1' for <Function test_never_unit_automation[arg3]>>
|
||||
factory_name = 'space_factory'
|
||||
|
||||
def model_fixture(request: SubRequest, factory_name: str) -> object:
|
||||
"""Model fixture implementation."""
|
||||
factoryboy_request: FactoryboyRequest = request.getfixturevalue("factoryboy_request")
|
||||
|
||||
# Try to evaluate as much post-generation dependencies as possible
|
||||
factoryboy_request.evaluate(request)
|
||||
|
||||
assert request.fixturename # NOTE: satisfy mypy
|
||||
fixture_name = request.fixturename
|
||||
prefix = "".join((fixture_name, SEPARATOR))
|
||||
|
||||
factory_class: type[Factory[object]] = request.getfixturevalue(factory_name)
|
||||
|
||||
# Create model fixture instance
|
||||
> NewFactory: type[Factory[object]] = cast(type[Factory[object]], type("Factory", (factory_class,), {}))
|
||||
^^^^^^^^^^^^^^^
|
||||
E TypeError: type 'Factory' is not subscriptable
|
||||
|
||||
..\..\..\venv\Lib\site-packages\pytest_factoryboy\fixture.py:360: TypeError</error></testcase><testcase classname="cookbook.tests.other.test_automations" name="test_never_unit_automation[arg1]" time="22.143"><error message="failed on setup with "TypeError: type 'Factory' is not subscriptable"">args = ()
|
||||
kwargs = {'request': <SubRequest 'space_1' for <Function test_never_unit_automation[arg1]>>}
|
||||
k = 'space_1__name'
|
||||
|
||||
@functools.wraps(fixture_function)
|
||||
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
||||
for k in set(kwargs.keys()) - function_args:
|
||||
del kwargs[k]
|
||||
> return fixture_function(*args, **kwargs)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
..\..\..\venv\Lib\site-packages\pytest_factoryboy\fixturegen.py:88:
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
..\..\..\venv\Lib\site-packages\pytest_factoryboy\fixturegen.py:49: in fn
|
||||
return function(*args, **kwargs)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|
||||
request = <SubRequest 'space_1' for <Function test_never_unit_automation[arg1]>>
|
||||
factory_name = 'space_factory'
|
||||
|
||||
def model_fixture(request: SubRequest, factory_name: str) -> object:
|
||||
"""Model fixture implementation."""
|
||||
factoryboy_request: FactoryboyRequest = request.getfixturevalue("factoryboy_request")
|
||||
|
||||
# Try to evaluate as much post-generation dependencies as possible
|
||||
factoryboy_request.evaluate(request)
|
||||
|
||||
assert request.fixturename # NOTE: satisfy mypy
|
||||
fixture_name = request.fixturename
|
||||
prefix = "".join((fixture_name, SEPARATOR))
|
||||
|
||||
factory_class: type[Factory[object]] = request.getfixturevalue(factory_name)
|
||||
|
||||
# Create model fixture instance
|
||||
> NewFactory: type[Factory[object]] = cast(type[Factory[object]], type("Factory", (factory_class,), {}))
|
||||
^^^^^^^^^^^^^^^
|
||||
E TypeError: type 'Factory' is not subscriptable
|
||||
|
||||
..\..\..\venv\Lib\site-packages\pytest_factoryboy\fixture.py:360: TypeError</error></testcase></testsuite></testsuites>
|
||||
File diff suppressed because one or more lines are too long
@@ -1,3 +1,4 @@
|
||||
import pytest
|
||||
from django.contrib import auth
|
||||
from django.test import RequestFactory
|
||||
from django_scopes import scope
|
||||
@@ -5,7 +6,11 @@ from django_scopes import scope
|
||||
from cookbook.helper.ingredient_parser import IngredientParser
|
||||
|
||||
|
||||
def test_ingredient_parser(u1_s1):
|
||||
@pytest.mark.parametrize("arg", [
|
||||
[True],
|
||||
[False],
|
||||
])
|
||||
def test_ingredient_parser(arg, u1_s1):
|
||||
expectations = {
|
||||
"2¼ l Wasser": (2.25, "l", "Wasser", ""),
|
||||
"3¼l Wasser": (3.25, "l", "Wasser", ""),
|
||||
@@ -67,7 +72,8 @@ def test_ingredient_parser(u1_s1):
|
||||
"1 Porreestange(n) , ca. 200 g": (1.0, None, 'Porreestange(n)', 'ca. 200 g'), # leading space before comma
|
||||
# test for over long food entries to get properly split into the note field
|
||||
"1 Lorem ipsum dolor sit amet consetetur sadipscing elitr sed diam nonumy eirmod tempor invidunt ut l Lorem ipsum dolor sit amet consetetur sadipscing elitr sed diam nonumy eirmod tempor invidunt ut l": (
|
||||
1.0, 'Lorem', 'ipsum', 'dolor sit amet consetetur sadipscing elitr sed diam nonumy eirmod tempor invidunt ut l Lorem ipsum dolor sit amet consetetur sadipscing elitr sed diam nonumy eirmod tempor invidunt ut l'),
|
||||
1.0, 'Lorem', 'ipsum',
|
||||
'dolor sit amet consetetur sadipscing elitr sed diam nonumy eirmod tempor invidunt ut l Lorem ipsum dolor sit amet consetetur sadipscing elitr sed diam nonumy eirmod tempor invidunt ut l'),
|
||||
"1 LoremipsumdolorsitametconsetetursadipscingelitrseddiamnonumyeirmodtemporinviduntutlLoremipsumdolorsitametconsetetursadipscingelitrseddiamnonumyeirmodtemporinviduntutl": (
|
||||
1.0, None, 'LoremipsumdolorsitametconsetetursadipscingelitrseddiamnonumyeirmodtemporinviduntutlLoremipsumdolorsitametconsetetursadipscingeli',
|
||||
'LoremipsumdolorsitametconsetetursadipscingelitrseddiamnonumyeirmodtemporinviduntutlLoremipsumdolorsitametconsetetursadipscingelitrseddiamnonumyeirmodtemporinviduntutl'),
|
||||
@@ -86,7 +92,7 @@ def test_ingredient_parser(u1_s1):
|
||||
request = RequestFactory()
|
||||
request.user = user
|
||||
request.space = space
|
||||
ingredient_parser = IngredientParser(request, False, ignore_automations=True)
|
||||
ingredient_parser = IngredientParser(request, False, ignore_automations=arg[0])
|
||||
|
||||
count = 0
|
||||
with scope(space=space):
|
||||
|
||||
@@ -4,4 +4,5 @@ testpaths = cookbook/tests
|
||||
python_files = tests.py test_*.py *_tests.py
|
||||
# uncomment to run coverage reports
|
||||
addopts = -n auto --cov=. --cov-report=html:docs/reports/coverage --cov-report=xml:docs/reports/coverage/coverage.xml --junitxml=docs/reports/tests/pytest.xml --html=docs/reports/tests/tests.html
|
||||
# addopts = -n auto --junitxml=docs/reports/tests/pytest.xml --html=docs/reports/tests/tests.html
|
||||
# addopts = -n auto --junitxml=docs/reports/tests/pytest.xml --html=docs/reports/tests/tests.html
|
||||
asyncio_default_fixture_loop_scope = fixture
|
||||
@@ -55,11 +55,11 @@ litellm==1.64.1
|
||||
# Development
|
||||
pytest==8.4.1
|
||||
pytest-django==4.11.0
|
||||
pytest-cov===6.0.0
|
||||
pytest-factoryboy==2.8.0
|
||||
pytest-cov===6.2.1
|
||||
pytest-factoryboy==2.8.1
|
||||
pytest-html==4.1.1
|
||||
pytest-asyncio==0.25.3
|
||||
pytest-xdist==3.7.0
|
||||
pytest-asyncio==1.1.0
|
||||
pytest-xdist==3.8.0
|
||||
autopep8==2.3.2
|
||||
flake8==7.3.0
|
||||
yapf==0.40.2
|
||||
|
||||
Reference in New Issue
Block a user