diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 000000000..ea1dbe7fe --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + { + "customColor": "", + "associatedIndex": 4 +} + + + + { + "keyToString": { + "ModuleVcsDetector.initialDetectionPerformed": "true", + "Python tests.Python tests for tests.test_burger.TestBurger.executor": "Run", + "Python tests.Python tests for tests.test_burger.TestBurger.test_get_price_calculation.executor": "Run", + "Python tests.Python tests for tests.test_burger.TestBurger.test_receipt_lowercase_types.executor": "Run", + "Python tests.Python tests for tests.test_burger.test_burger_add_ingredient.executor": "Run", + "Python tests.Python tests for tests.test_burger.test_clear_ingredients.executor": "Run", + "Python tests.Python tests for tests.test_burger.test_move_and_remove_ingredients_order.executor": "Run", + "Python tests.Python tests for tests.test_burger.test_receipt_format_includes_bun_and_ingredients.executor": "Run", + "Python tests.Python tests for tests.test_burger.test_set_bun_and_add_ingredients_and_price.executor": "Run", + "Python tests.Python tests in test_burger.py.executor": "Run", + "Python tests.pytest for tests.test_burger.TestBurger.executor": "Run", + "Python tests.pytest for tests.test_burger.TestBurger.test_get_receipt_includes_bun_and_ingredients.executor": "Run", + "Python tests.pytest for tests.test_burger.TestBurger.test_move_ingredient_valid_indices.executor": "Run", + "Python tests.pytest for tests.test_burger.test_clear_ingredients.executor": "Run", + "Python tests.pytest for tests.test_burger.test_get_price_with_single_ingredient.executor": "Run", + "Python tests.pytest for tests.test_burger.test_get_price_without_ingredients_and_bun.executor": "Run", + "Python tests.pytest for tests.test_burger.test_get_receipt_includes_bun_and_ingredients.executor": "Run", + "Python tests.pytest for tests.test_burger.test_move_ingredient_invalid_index.executor": "Run", + "Python tests.pytest for tests.test_burger.test_move_ingredient_valid_indices.executor": "Run", + "Python.praktikum.executor": "Run", + "Python.test_burger.executor": "Run", + "RunOnceActivity.ShowReadmeOnStart": "true", + "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true", + "RunOnceActivity.git.unshallow": "true", + "git-widget-placeholder": "main", + "last_opened_file_path": "C:/Users/Rus/PycharmProjects/Diplom/Diplom_1" + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1772262969711 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/conftest.py b/conftest.py new file mode 100644 index 000000000..18b3d45f5 --- /dev/null +++ b/conftest.py @@ -0,0 +1,19 @@ +import pytest +from praktikum.burger import Burger +from helpers import make_mock_bun, make_mock_ingredient + +@pytest.fixture +def burger(): + return Burger() + +@pytest.fixture +def mock_bun(): + return make_mock_bun() + +@pytest.fixture +def mock_ingredient(): + return make_mock_ingredient() + +@pytest.fixture +def another_mock_ingredient(): + return make_mock_ingredient(name="Tomato", ing_type="Vegetable", price=0.8) \ No newline at end of file diff --git a/helpers.py b/helpers.py new file mode 100644 index 000000000..ee88eac23 --- /dev/null +++ b/helpers.py @@ -0,0 +1,14 @@ +from unittest.mock import Mock + +def make_mock_bun(name="Sesame Bun", price=3.0): + bun = Mock() + bun.get_name.return_value = name + bun.get_price.return_value = price + return bun + +def make_mock_ingredient(name="Lettuce", ing_type="Vegetable", price=1.2): + ing = Mock() + ing.get_name.return_value = name + ing.get_type.return_value = ing_type + ing.get_price.return_value = price + return ing \ No newline at end of file diff --git a/models.py b/models.py new file mode 100644 index 000000000..13e24089a --- /dev/null +++ b/models.py @@ -0,0 +1,62 @@ +class Bun: + def __init__(self, name, price): + self.name = name + self.price = price + + def get_name(self): + return self.name + + def get_price(self): + return self.price + +class Ingredient: + def __init__(self, name, ingredient_type, price): + self.name = name + self.type = ingredient_type + self.price = price + + def get_name(self): + return self.name + + def get_type(self): + return self.type + + def get_price(self): + return self.price + +class Burger: + def __init__(self): + self.bun = None + self.ingredients = [] + + def set_buns(self, bun): + self.bun = bun + + def add_ingredient(self, ingredient): + self.ingredients.append(ingredient) + + def remove_ingredient(self, ingredient): + self.ingredients.remove(ingredient) + + def move_ingredient(self, old_index, new_index): + self.ingredients.insert(new_index, self.ingredients.pop(old_index)) + + def get_price(self): + total = 0 + if self.bun: + total += self.bun.get_price() * 2 + for ing in self.ingredients: + total += ing.get_price() + return total + + def get_receipt(self): + lines = [] + lines.append(f"(==== {self.bun.get_name()} ====)") + for ing in self.ingredients: + lines.append(f"= {str(ing.get_type()).lower()} {ing.get_name()} =") + lines.append(f"(==== {self.bun.get_name()} ====)") + lines.append(f"Price: {self.get_price()}") + return "\n".join(lines) + + def clear_ingredients(self): + self.ingredients = [] \ 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 95% rename from burger.py rename to praktikum/burger.py index 2b3b6a88b..110302ed7 100644 --- a/burger.py +++ b/praktikum/burger.py @@ -1,7 +1,6 @@ from typing import List -from praktikum.bun import Bun -from praktikum.ingredient import Ingredient +from models import Burger, Bun, Ingredient class Burger: diff --git a/database.py b/praktikum/database.py similarity index 86% rename from database.py rename to praktikum/database.py index 4c75baf71..44872889c 100644 --- a/database.py +++ b/praktikum/database.py @@ -1,8 +1,8 @@ from typing import List -from praktikum.bun import Bun -from praktikum.ingredient import Ingredient -from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING +from praktikum.praktikum import Bun +from praktikum.praktikum import Ingredient +from praktikum.praktikum import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING class Database: 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 87% rename from praktikum.py rename to praktikum/praktikum.py index ec522fa6d..9782565fe 100644 --- a/praktikum.py +++ b/praktikum/praktikum.py @@ -1,10 +1,8 @@ from typing import List -from praktikum.bun import Bun -from praktikum.burger import Burger -from praktikum.database import Database -from praktikum.ingredient import Ingredient +from database import Database +from models import Burger, Bun, Ingredient def main(): # Инициализируем базу данных diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_burger.py b/tests/test_burger.py new file mode 100644 index 000000000..476e1229d --- /dev/null +++ b/tests/test_burger.py @@ -0,0 +1,72 @@ +import pytest +from praktikum.burger import Burger +from helpers import make_mock_bun, make_mock_ingredient + +class TestBurger: + def test_get_price_without_ingredients_and_bun(self, burger, mock_bun): + burger.set_buns(mock_bun) + expected_price = mock_bun.get_price.return_value * 2 + assert burger.get_price() == expected_price + + def test_get_price_with_single_ingredient(self, burger, mock_bun, mock_ingredient): + burger.set_buns(mock_bun) + burger.add_ingredient(mock_ingredient) + expected_price = mock_bun.get_price.return_value * 2 + mock_ingredient.get_price.return_value + assert burger.get_price() == expected_price + + def test_add_ingredient_increases_ingredients_list(self, burger, mock_ingredient): + initial_count = len(burger.get_ingredients()) + burger.add_ingredient(mock_ingredient) + assert mock_ingredient in burger.get_ingredients() + assert len(burger.get_ingredients()) == initial_count + 1 + + def test_get_ingredients_returns_list(self, burger, mock_ingredient): + burger.add_ingredient(mock_ingredient) + ingredients = burger.get_ingredients() + assert isinstance(ingredients, list) + assert mock_ingredient in ingredients + + def test_move_ingredient_valid_indices(self, burger, mock_ingredient, another_mock_ingredient): + burger.add_ingredient(mock_ingredient) + burger.add_ingredient(another_mock_ingredient) + burger.move_ingredient(0, 1) + assert burger.get_ingredients()[1] == mock_ingredient + + def test_remove_ingredient_valid_index(self, burger, mock_ingredient): + burger.add_ingredient(mock_ingredient) + burger.remove_ingredient(1) + assert mock_ingredient not in burger.get_ingredients() + + def test_remove_ingredient_invalid_index_with_assert(self, burger): + with pytest.raises(IndexError): + burger.remove_ingredient(999) + + def test_clear_ingredients(self, burger, mock_ingredient): + burger.add_ingredient(mock_ingredient) + while burger.get_ingredients(): + burger.remove_ingredient(0) + assert burger.get_ingredients() == [] + + def test_get_receipt_includes_bun_and_ingredients(self, burger, mock_bun, mock_ingredient): + burger.set_buns(mock_bun) + burger.add_ingredient(mock_ingredient) + + total_price = burger.get_price() + bun_name = mock_bun.get_name() + ingredient_type = str(mock_ingredient.get_type()).lower() + ingredient_name = mock_ingredient.get_name() + + expected_receipt = ( + f"(==== {bun_name} ====)\n" + f"= {ingredient_type} {ingredient_name} =\n" + f"(==== {bun_name} ====)\n" + f"\n" + f"Price: {total_price}" + ) + + actual_receipt = burger.get_receipt() + + print("Expected receipt:\n" + expected_receipt) + print("Actual receipt:\n" + actual_receipt) + + assert actual_receipt == expected_receipt \ No newline at end of file