diff --git a/__init__.py b/.gitignore similarity index 100% rename from __init__.py rename to .gitignore diff --git a/__pycache__/__init__.cpython-313.pyc b/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 000000000..a1fdc30b1 Binary files /dev/null and b/__pycache__/__init__.cpython-313.pyc differ diff --git a/praktikum/__init__.py b/praktikum/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/praktikum/__pycache__/__init__.cpython-313.pyc b/praktikum/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 000000000..dbf58887f Binary files /dev/null and b/praktikum/__pycache__/__init__.cpython-313.pyc differ diff --git a/praktikum/__pycache__/bun.cpython-313.pyc b/praktikum/__pycache__/bun.cpython-313.pyc new file mode 100644 index 000000000..10f2576c3 Binary files /dev/null and b/praktikum/__pycache__/bun.cpython-313.pyc differ diff --git a/praktikum/__pycache__/burger.cpython-313.pyc b/praktikum/__pycache__/burger.cpython-313.pyc new file mode 100644 index 000000000..e3394c8c4 Binary files /dev/null and b/praktikum/__pycache__/burger.cpython-313.pyc differ diff --git a/praktikum/__pycache__/ingredient.cpython-313.pyc b/praktikum/__pycache__/ingredient.cpython-313.pyc new file mode 100644 index 000000000..b70a5db3a Binary files /dev/null and b/praktikum/__pycache__/ingredient.cpython-313.pyc differ diff --git a/praktikum/__pycache__/ingredient_types.cpython-313.pyc b/praktikum/__pycache__/ingredient_types.cpython-313.pyc new file mode 100644 index 000000000..12bf0ab2e Binary files /dev/null and b/praktikum/__pycache__/ingredient_types.cpython-313.pyc differ 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/requirements.txt b/requirements.txt new file mode 100644 index 000000000..586301d62 Binary files /dev/null and b/requirements.txt differ diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/__pycache__/__init__.cpython-313.pyc b/tests/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 000000000..1777ba2f8 Binary files /dev/null and b/tests/__pycache__/__init__.cpython-313.pyc differ diff --git a/tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc b/tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 000000000..3a1587bd7 Binary files /dev/null and b/tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc differ diff --git a/tests/__pycache__/test_burger.cpython-313-pytest-9.0.2.pyc b/tests/__pycache__/test_burger.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 000000000..abceef82e Binary files /dev/null and b/tests/__pycache__/test_burger.cpython-313-pytest-9.0.2.pyc differ diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..58f24fe34 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,56 @@ +import pytest +from unittest.mock import Mock +import sys +import os + +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) + +from praktikum.bun import Bun +from praktikum.ingredient import Ingredient +import praktikum.ingredient_types as ingredient_types + + +@pytest.fixture +def burger(): + """Фикстура для создания бургера""" + from praktikum.burger import Burger + return Burger() + + +@pytest.fixture +def mock_bun(): + """Фикстура для создания мока булочки""" + mock = Mock(spec=Bun) + mock.get_name.return_value = "black bun" + mock.get_price.return_value = 100.0 + return mock + + +@pytest.fixture +def mock_ingredient_filling(): + """Фикстура для создания мока начинки""" + mock = Mock(spec=Ingredient) + mock.get_name.return_value = "cutlet" + mock.get_price.return_value = 100.0 + mock.get_type.return_value = ingredient_types.INGREDIENT_TYPE_FILLING + return mock + + +@pytest.fixture +def mock_ingredient_sauce(): + """Фикстура для создания мока соуса""" + mock = Mock(spec=Ingredient) + mock.get_name.return_value = "hot sauce" + mock.get_price.return_value = 100.0 + mock.get_type.return_value = ingredient_types.INGREDIENT_TYPE_SAUCE + return mock + + +@pytest.fixture +def multiple_mock_ingredients(): + """Фикстура для создания нескольких моков ингредиентов""" + mock1 = Mock(spec=Ingredient) + mock2 = Mock(spec=Ingredient) + mock3 = Mock(spec=Ingredient) + return mock1, mock2, mock3 + diff --git a/tests/test_burger.py b/tests/test_burger.py new file mode 100644 index 000000000..25fec6d1f --- /dev/null +++ b/tests/test_burger.py @@ -0,0 +1,155 @@ +import pytest +import sys +import os + +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +from unittest.mock import Mock +from praktikum.bun import Bun +from praktikum.ingredient import Ingredient + +class TestBurger: + + def test_set_buns(self, burger, mock_bun): + burger.set_buns(mock_bun) + assert burger.bun == mock_bun + + def test_add_ingredient(self, burger, mock_ingredient_filling): + burger.add_ingredient(mock_ingredient_filling) + assert len(burger.ingredients) == 1 + assert burger.ingredients[0] == mock_ingredient_filling + + def test_remove_ingredient(self, burger, mock_ingredient_filling): + burger.add_ingredient(mock_ingredient_filling) + burger.remove_ingredient(0) + assert len(burger.ingredients) == 0 + + def test_remove_ingredient_index_error(self, burger): + with pytest.raises(IndexError): + burger.remove_ingredient(0) + + def test_move_ingredient(self, burger, multiple_mock_ingredients): + mock1, mock2, mock3 = multiple_mock_ingredients + + burger.add_ingredient(mock1) + burger.add_ingredient(mock2) + burger.add_ingredient(mock3) + + burger.move_ingredient(0, 2) + assert burger.ingredients == [mock2, mock3, mock1] + + def test_move_ingredient_index_error(self, burger): + with pytest.raises(IndexError): + burger.move_ingredient(0, 0) + + def test_get_price_empty_burger(self, burger, mock_bun): + burger.set_buns(mock_bun) + assert burger.get_price() == 200.0 + + def test_get_price_with_ingredients(self, burger, mock_bun, mock_ingredient_filling, mock_ingredient_sauce): + burger.set_buns(mock_bun) + burger.add_ingredient(mock_ingredient_filling) + burger.add_ingredient(mock_ingredient_sauce) + assert burger.get_price() == 400.0 + + def test_get_price_no_bun(self, burger): + with pytest.raises(AttributeError) as exc_info: + burger.get_price() + assert "object has no attribute" in str(exc_info.value) + + def test_receipt_structure_empty_burger(self, burger, mock_bun): + burger.set_buns(mock_bun) + receipt = burger.get_receipt() + + expected_receipt = ( + "(==== black bun ====)\n" + "(==== black bun ====)\n" + "\n" + "Price: 200.0" + ) + assert receipt == expected_receipt + + def test_receipt_structure_with_ingredients(self, burger, mock_bun, mock_ingredient_filling, mock_ingredient_sauce): + burger.set_buns(mock_bun) + burger.add_ingredient(mock_ingredient_sauce) + burger.add_ingredient(mock_ingredient_filling) + + receipt = burger.get_receipt() + + expected_receipt = ( + "(==== black bun ====)\n" + "= sauce hot sauce =\n" + "= filling cutlet =\n" + "(==== black bun ====)\n" + "\n" + "Price: 400.0" + ) + assert receipt == expected_receipt + + def test_receipt_includes_correct_price_for_empty_burger(self, burger, mock_bun): + burger.set_buns(mock_bun) + receipt = burger.get_receipt() + assert "Price: 200.0" in receipt + + def test_get_receipt_no_bun(self, burger): + with pytest.raises(AttributeError) as exc_info: + burger.get_receipt() + assert "object has no attribute" in str(exc_info.value) + + @pytest.mark.parametrize("bun_price,ingredient_prices,expected_total", [ + (100.0, [], 200.0), # только булочки + (150.0, [50.0], 350.0), # булочки + 1 ингредиент + (200.0, [100.0, 50.0, 75.0], 625.0), # булочки + 3 ингредиента + ]) + def test_get_price_parameterized(self, burger, bun_price, ingredient_prices, expected_total): + mock_bun = Mock(spec=Bun) + mock_bun.get_price.return_value = bun_price + + mock_ingredients = [] + for price in ingredient_prices: + mock_ing = Mock(spec=Ingredient) + mock_ing.get_price.return_value = price + mock_ingredients.append(mock_ing) + + burger.set_buns(mock_bun) + for ingredient in mock_ingredients: + burger.add_ingredient(ingredient) + + assert burger.get_price() == expected_total + + def test_ingredient_methods_called(self, burger, mock_bun, mock_ingredient_filling): + burger.set_buns(mock_bun) + burger.add_ingredient(mock_ingredient_filling) + + burger.get_price() + burger.get_receipt() + + mock_bun.get_name.assert_called() + mock_bun.get_price.assert_called() + mock_ingredient_filling.get_name.assert_called() + mock_ingredient_filling.get_price.assert_called() + mock_ingredient_filling.get_type.assert_called() + + def test_set_buns_correctly_stores_bun(self, burger, mock_bun): + burger.set_buns(mock_bun) + assert burger.bun == mock_bun + + def test_add_ingredient_increases_count(self, burger, mock_ingredient_filling): + initial_count = len(burger.ingredients) + burger.add_ingredient(mock_ingredient_filling) + assert len(burger.ingredients) == initial_count + 1 + + def test_add_ingredient_stores_correct_ingredient(self, burger, mock_ingredient_sauce): + burger.add_ingredient(mock_ingredient_sauce) + assert burger.ingredients[0] == mock_ingredient_sauce + + def test_multiple_ingredients_stored_in_order(self, burger, mock_ingredient_sauce, mock_ingredient_filling): + burger.add_ingredient(mock_ingredient_sauce) + burger.add_ingredient(mock_ingredient_filling) + assert burger.ingredients == [mock_ingredient_sauce, mock_ingredient_filling] + + def test_get_price_for_assembled_burger(self, burger, mock_bun, mock_ingredient_filling, mock_ingredient_sauce): + burger.set_buns(mock_bun) + burger.add_ingredient(mock_ingredient_sauce) + burger.add_ingredient(mock_ingredient_filling) + + assert burger.get_price() == 400.0