diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..96229d8e1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +.venv/ +venv/ +env/ + +__pycache__/ +*.py[cod] +*.egg-info/ + +.pytest_cache/ +.coverage +.coverage.* +htmlcov/ +coverage.xml + +.idea/ +.vscode/ +.DS_Store +Thumbs.db diff --git a/praktikum.py b/praktikum.py index ec522fa6d..0d2826829 100644 --- a/praktikum.py +++ b/praktikum.py @@ -5,37 +5,24 @@ from praktikum.database import Database from praktikum.ingredient import Ingredient - def main(): - # Инициализируем базу данных database: Database = Database() - - # Создадим новый бургер burger: Burger = Burger() - # Считаем список доступных булок из базы данных - buns: List[Bun] = database.available_buns() - - # Считаем список доступных ингредиентов из базы данных - ingredients: List[Ingredient] = database.available_ingredients() + buns: List[Bun] = database.available_buns() # Считаем список доступных булок из БД + ingredients: List[Ingredient] = database.available_ingredients() # Считаем список доступных ингредиентов из БД - # Соберём бургер + # Сборка бургера burger.set_buns(buns[0]) - burger.add_ingredient(ingredients[1]) burger.add_ingredient(ingredients[4]) burger.add_ingredient(ingredients[3]) burger.add_ingredient(ingredients[5]) - # Переместим слой с ингредиентом burger.move_ingredient(2, 1) - - # Удалим ингредиент burger.remove_ingredient(3) - # Распечатаем рецепт бургера print(burger.get_receipt()) - if __name__ == "__main__": main() diff --git a/praktikum/__init__.py b/praktikum/__init__.py new file mode 100644 index 000000000..e69de29bb 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/requirements.txt b/requirements.txt new file mode 100644 index 000000000..9955deccd --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pytest +pytest-cov diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/bun_test.py b/tests/bun_test.py new file mode 100644 index 000000000..c0e797bae --- /dev/null +++ b/tests/bun_test.py @@ -0,0 +1,16 @@ +from praktikum.bun import Bun + +class TestBun: + + def test_bun_creation(self): + bun = Bun("white bun", 150.5) + assert bun.name == "white bun" + assert bun.price == 150.5 + + def test_get_name(self): + bun = Bun("black bun", 100) + assert bun.get_name() == "black bun" + + def test_get_price(self): + bun = Bun("red bun", 200) + assert bun.get_price() == 200 diff --git a/tests/burger_test.py b/tests/burger_test.py new file mode 100644 index 000000000..b242344ab --- /dev/null +++ b/tests/burger_test.py @@ -0,0 +1,115 @@ +import pytest +from unittest.mock import Mock +from praktikum.burger import Burger +from praktikum.bun import Bun +from praktikum.ingredient import Ingredient +from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING + +class TestBurger: + + def test_init_default_values(self): # Проверка того, что при инициализации булочка и список ингредиентов пустые + burger = Burger() + assert burger.bun is None + assert burger.ingredients == [] + + def test_set_buns(self): # Проверка корректности установки булочки в бургер + burger = Burger() + mock_bun = Mock(spec=Bun) + + burger.set_buns(mock_bun) + + assert burger.bun == mock_bun + + def test_add_ingredient(self): # Проверка добавления ингредиента в бургер + burger = Burger() + mock_ingredient = Mock(spec=Ingredient) + burger.add_ingredient(mock_ingredient) + assert mock_ingredient in burger.ingredients + assert len(burger.ingredients) == 1 + + def test_remove_ingredient(self): # Проверка удаления ингредиента по индексу + burger = Burger() + mock_ingredient1 = Mock(spec=Ingredient) + mock_ingredient2 = Mock(spec=Ingredient) + burger.add_ingredient(mock_ingredient1) + burger.add_ingredient(mock_ingredient2) + burger.remove_ingredient(0) + + assert mock_ingredient1 not in burger.ingredients + assert burger.ingredients == [mock_ingredient2] + + def test_move_ingredient(self): # Проверка перемещения ингредиента с одной позиции на другую + burger = Burger() + mock_ingredient1 = Mock(spec=Ingredient) + mock_ingredient2 = Mock(spec=Ingredient) + mock_ingredient3 = Mock(spec=Ingredient) + + burger.add_ingredient(mock_ingredient1) + burger.add_ingredient(mock_ingredient2) + burger.add_ingredient(mock_ingredient3) + burger.move_ingredient(2, 0) # Перемещение ингредиента с индекса 2 на индекс 0 + + assert burger.ingredients == [mock_ingredient3, mock_ingredient1, mock_ingredient2] + + @pytest.mark.parametrize( + "bun_price, ingredient_prices, expected_price", + [ + (100, [50, 75], 325), # Булочка (100*2) + два ингредиента + (200, [], 400), # Только булочка (200*2), без ингредиентов + (50, [10, 20, 30], 160) # Булочка (50*2) + три ингредиента + ] + ) + def test_get_price(self, bun_price, ingredient_prices, expected_price): # Проверка корректности подсчета стоимости бургера + параметризация + burger = Burger() + mock_bun = Mock(spec=Bun) + mock_bun.get_price.return_value = bun_price + burger.set_buns(mock_bun) + + for price in ingredient_prices: + mock_ing = Mock(spec=Ingredient) + mock_ing.get_price.return_value = price + burger.add_ingredient(mock_ing) + + assert burger.get_price() == expected_price + + @pytest.mark.parametrize("ing_type, expected_type_str", [ + (INGREDIENT_TYPE_SAUCE, "sauce"), + (INGREDIENT_TYPE_FILLING, "filling")]) + + def test_get_receipt_with_one_ingredient(self, ing_type, expected_type_str): # Проверка генерации чека с одним ингредиентом + параметриз. + burger = Burger() + mock_bun = Mock(spec=Bun) + mock_bun.get_name.return_value = "black bun" + mock_bun.get_price.return_value = 100 + + mock_ing = Mock(spec=Ingredient) + mock_ing.get_type.return_value = ing_type + mock_ing.get_name.return_value = "test ingredient" + mock_ing.get_price.return_value = 50 + + burger.set_buns(mock_bun) + burger.add_ingredient(mock_ing) + + # Ожидаемая строка чека + expected_receipt = ( + "(==== black bun ====)\n" + f"= {expected_type_str} test ingredient =\n" + "(==== black bun ====)\n" + "\n" + "Price: 250") + assert burger.get_receipt() == expected_receipt + + def test_get_receipt_without_ingredients(self): # Проверка генерации чека без ингредиентов + burger = Burger() + mock_bun = Mock(spec=Bun) + mock_bun.get_name.return_value = "white bun" + mock_bun.get_price.return_value = 200 + + burger.set_buns(mock_bun) + + expected_receipt = ( + "(==== white bun ====)\n" + "(==== white bun ====)\n" + "\n" + "Price: 400") + assert burger.get_receipt() == expected_receipt diff --git a/tests/database_test.py b/tests/database_test.py new file mode 100644 index 000000000..44e8f9942 --- /dev/null +++ b/tests/database_test.py @@ -0,0 +1,33 @@ +from praktikum.database import Database +from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING + +class TestDatabase: + + def test_database_initialization(self): + db = Database() + assert len(db.buns) == 3 # Проверка того, что булочки созданы (3 шт.) + assert len(db.ingredients) == 6 # Проверка того, что ингредиенты созданы (6 шт.) + + def test_available_buns(self): + db = Database() + buns = db.available_buns() + assert len(buns) == 3 + assert buns[0].get_name() == "black bun" + assert buns[0].get_price() == 100 + assert buns[1].get_name() == "white bun" + assert buns[2].get_name() == "red bun" + + def test_available_ingredients(self): + db = Database() + ingredients = db.available_ingredients() + assert len(ingredients) == 6 + + # Проверка первых трех соусов + assert ingredients[0].get_type() == INGREDIENT_TYPE_SAUCE + assert ingredients[0].get_name() == "hot sauce" + assert ingredients[0].get_price() == 100 + + # Проверка первых трех начинок (индексы 3,4,5) + assert ingredients[3].get_type() == INGREDIENT_TYPE_FILLING + assert ingredients[3].get_name() == "cutlet" + assert ingredients[3].get_price() == 100 diff --git a/tests/ingredient_test.py b/tests/ingredient_test.py new file mode 100644 index 000000000..bf8d15b4c --- /dev/null +++ b/tests/ingredient_test.py @@ -0,0 +1,26 @@ +import pytest +from praktikum.ingredient import Ingredient +from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING + +class TestIngredient: + @pytest.mark.parametrize("ing_type, name, price", [ + (INGREDIENT_TYPE_SAUCE, "chili sauce", 50.0), + (INGREDIENT_TYPE_FILLING, "cutlet", 120.0),]) + + def test_ingredient_creation(self, ing_type, name, price): + ingredient = Ingredient(ing_type, name, price) + assert ingredient.type == ing_type + assert ingredient.name == name + assert ingredient.price == price + + def test_get_price(self): + ingredient = Ingredient(INGREDIENT_TYPE_SAUCE, "sour cream", 75.5) + assert ingredient.get_price() == 75.5 + + def test_get_name(self): + ingredient = Ingredient(INGREDIENT_TYPE_FILLING, "dinosaur", 200) + assert ingredient.get_name() == "dinosaur" + + def test_get_type(self): + ingredient = Ingredient(INGREDIENT_TYPE_SAUCE, "hot sauce", 100) + assert ingredient.get_type() == INGREDIENT_TYPE_SAUCE