diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..1346d9278 --- /dev/null +++ b/.gitignore @@ -0,0 +1,239 @@ +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Python template +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.idea/ \ No newline at end of file diff --git a/conftest.py b/conftest.py new file mode 100644 index 000000000..921aaf3a3 --- /dev/null +++ b/conftest.py @@ -0,0 +1,32 @@ +from unittest.mock import Mock +import pytest +from data import MockBun, MockIngredients + + +@pytest.fixture(scope='function') +def mock_bun(): + mock_bun = Mock() + mock_bun.name = MockBun.name + mock_bun.price = MockBun.price + return mock_bun + + +@pytest.fixture(scope='function') +def mock_ingredient(): + mock_ingredient = Mock() + mock_ingredient.name = MockIngredients.name + mock_ingredient.price = MockIngredients.price + mock_ingredient.ingredient_type = MockIngredients.ingredient_type + + return mock_ingredient + + +@pytest.fixture(scope='function') +def mock_two_ingredients(mock_ingredient): + mock_ingredient_2 = Mock() + mock_ingredient_2.name = MockIngredients.name_2 + mock_ingredient_2.price = MockIngredients.price_2 + mock_ingredient_2.ingredient_type = MockIngredients.ingredient_type_2 + mock_ingredients = [mock_ingredient, mock_ingredient_2] + + return mock_ingredients \ No newline at end of file diff --git a/data.py b/data.py new file mode 100644 index 000000000..fe6a3f1ab --- /dev/null +++ b/data.py @@ -0,0 +1,27 @@ +available_buns = [["black bun", 100], ["white bun", 200], ["red bun", 300]] + +available_ingredients = [["SAUCE", "hot sauce", 100], ["SAUCE", "sour cream", 200], ["SAUCE", "chili sauce", 300], + ["FILLING", "cutlet", 100], ["FILLING", "dinosaur", 200], ["FILLING", "sausage", 300]] + + +class MockBun: + name = "black bun" + price = 100 + + +class MockIngredients: + name = "hot sauce" + price = 100 + ingredient_type = 'SAUCE' + name_2 = "dinosaur" + price_2 = 200 + ingredient_type_2 = "FILLING" + + +expected_receipt = ( + f'(==== black bun ====)\n' + f'= sauce hot sauce =\n' + f'= filling dinosaur =\n' + f'(==== black bun ====)\n\n' + f'Price: 500' + ) \ No newline at end of file diff --git a/__init__.py b/praktikum/__init__.py similarity index 100% rename from __init__.py rename to praktikum/__init__.py diff --git a/bun.py b/praktikum/bun.py similarity index 100% rename from bun.py rename to praktikum/bun.py diff --git a/burger.py b/praktikum/burger.py similarity index 100% rename from burger.py rename to praktikum/burger.py diff --git a/database.py b/praktikum/database.py similarity index 100% rename from database.py rename to praktikum/database.py diff --git a/ingredient.py b/praktikum/ingredient.py similarity index 100% rename from ingredient.py rename to praktikum/ingredient.py diff --git a/ingredient_types.py b/praktikum/ingredient_types.py similarity index 100% rename from ingredient_types.py rename to praktikum/ingredient_types.py diff --git a/praktikum.py b/praktikum/praktikum.py similarity index 100% rename from praktikum.py rename to praktikum/praktikum.py diff --git a/reguirements.txt b/reguirements.txt new file mode 100644 index 000000000..40c360612 --- /dev/null +++ b/reguirements.txt @@ -0,0 +1,23 @@ +attrs==23.2.0 +certifi==2024.2.2 +cffi==1.16.0 +colorama==0.4.6 +coverage==7.5.1 +h11==0.14.0 +idna==3.6 +iniconfig==2.0.0 +outcome==1.3.0.post0 +packaging==24.0 +pluggy==1.4.0 +pycparser==2.22 +PySocks==1.7.1 +pytest==8.1.1 +pytest-cov==5.0.0 +selenium==4.19.0 +sniffio==1.3.1 +sortedcontainers==2.4.0 +trio==0.25.0 +trio-websocket==0.11.1 +typing_extensions==4.11.0 +urllib3==2.2.1 +wsproto==1.2.0 \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/tast_database.py b/tests/tast_database.py new file mode 100644 index 000000000..d391d6b4d --- /dev/null +++ b/tests/tast_database.py @@ -0,0 +1,21 @@ +from praktikum.database import Database + + +class TestDatabase: + + def test_init_bun_list_true(self): + database = Database() + + assert database.buns[0].name == "black bun" and database.buns[0].price == 100 + assert database.buns[1].name == "white bun" and database.buns[1].price == 200 + assert database.buns[2].name == "red bun" and database.buns[2].price == 300 + + def test_init_ingredients_list_true(self): + database = Database() + + assert database.ingredients[0].name == "hot sauce" and database.ingredients[0].price == 100 + assert database.ingredients[1].name == "sour cream" and database.ingredients[1].price == 200 + assert database.ingredients[2].name == "chili sauce" and database.ingredients[2].price == 300 + assert database.ingredients[3].name == "cutlet" and database.ingredients[3].price == 100 + assert database.ingredients[4].name == "dinosaur" and database.ingredients[4].price == 200 + assert database.ingredients[5].name == "sausage" and database.ingredients[5].price == 300 \ No newline at end of file diff --git a/tests/test_bun.py b/tests/test_bun.py new file mode 100644 index 000000000..4a3eec956 --- /dev/null +++ b/tests/test_bun.py @@ -0,0 +1,20 @@ +import pytest +from praktikum.bun import Bun +import data + + +class TestBun: + + @pytest.mark.parametrize('the_bun, the_price', data.available_buns) + def test_get_name_true(self, the_bun, the_price): + bun = Bun(the_bun, the_price) + actual_result = bun.get_name() + + assert actual_result == bun.name + + @pytest.mark.parametrize('the_bun, the_price', data.available_buns) + def test_get_price_true(self, the_bun, the_price): + bun = Bun(the_bun, the_price) + actual_result = bun.get_price() + + assert actual_result == bun.price \ No newline at end of file diff --git a/tests/test_burger.py b/tests/test_burger.py new file mode 100644 index 000000000..cd7ff10de --- /dev/null +++ b/tests/test_burger.py @@ -0,0 +1,57 @@ +from praktikum.burger import Burger +from data import MockBun, MockIngredients +import data +from unittest.mock import patch + + +class TestBurger: + def test_set_buns(self, mock_bun): + burger = Burger() + burger.set_buns(mock_bun) + + assert burger.bun == mock_bun + + def test_add_ingredient(self, mock_ingredient): + burger = Burger() + burger.add_ingredient(mock_ingredient) + + assert burger.ingredients == [mock_ingredient] + + def test_remove_ingredient(self, mock_two_ingredients): + burger = Burger() + burger.ingredients = mock_two_ingredients + burger.remove_ingredient(0) + + assert len(burger.ingredients) == 1 + + def test_move_ingredient(self, mock_two_ingredients): + burger = Burger() + burger.ingredients = mock_two_ingredients.copy() + burger.move_ingredient(1, 0) + + assert burger.ingredients[0] == mock_two_ingredients[1] + + def test_get_price(self, mock_bun, mock_two_ingredients): + burger = Burger() + mock_bun.get_price.return_value = MockBun.price + mock_two_ingredients[0].get_price.return_value = MockIngredients.price + mock_two_ingredients[1].get_price.return_value = MockIngredients.price_2 + burger.bun = mock_bun + burger.ingredients = mock_two_ingredients + actual_result = burger.get_price() + + assert actual_result == 100 * 2 + 100 + 200 + + @patch('praktikum.burger.Burger.get_price', return_value=500) + def test_get_receipt(self, mock_get_price, mock_bun, mock_two_ingredients): + burger = Burger() + mock_bun.get_name.return_value = MockBun.name + mock_two_ingredients[0].get_name.return_value = MockIngredients.name + mock_two_ingredients[0].get_type.return_value = MockIngredients.ingredient_type + mock_two_ingredients[1].get_name.return_value = MockIngredients.name_2 + mock_two_ingredients[1].get_type.return_value = MockIngredients.ingredient_type_2 + burger.bun = mock_bun + burger.ingredients = mock_two_ingredients + actual_result = burger.get_receipt() + + assert actual_result == data.expected_receipt \ No newline at end of file diff --git a/tests/test_ingridient.py b/tests/test_ingridient.py new file mode 100644 index 000000000..9561cf940 --- /dev/null +++ b/tests/test_ingridient.py @@ -0,0 +1,27 @@ +from praktikum.ingredient import Ingredient +import pytest +import data + + +class TestIngredient: + + @pytest.mark.parametrize('ingredient_type, name, price', data.available_ingredients) + def test_get_price(self, ingredient_type, name, price): + ingredient = Ingredient(ingredient_type, name, price) + actual_result = ingredient.get_price() + + assert actual_result == ingredient.price + + @pytest.mark.parametrize('ingredient_type, name, price', data.available_ingredients) + def test_get_name(self, ingredient_type, name, price): + ingredient = Ingredient(ingredient_type, name, price) + actual_result = ingredient.get_name() + + assert actual_result == ingredient.name + + @pytest.mark.parametrize('ingredient_type, name, price', data.available_ingredients) + def test_get_type(self, ingredient_type, name, price): + ingredient = Ingredient(ingredient_type, name, price) + actual_result = ingredient.get_type() + + assert actual_result == ingredient.type \ No newline at end of file