From 03f18e0c9de3618d444e3af2d3ccc1b4959d40ce Mon Sep 17 00:00:00 2001 From: Dmitry Ponosov Date: Thu, 15 Jan 2026 01:24:32 +0700 Subject: [PATCH 1/2] First load --- .gitignore | 11 + __init__.py => praktikum/__init__.py | 0 bun.py => praktikum/bun.py | 0 burger.py => praktikum/burger.py | 0 database.py => praktikum/database.py | 0 ingredient.py => praktikum/ingredient.py | 0 .../ingredient_types.py | 0 praktikum.py => praktikum/praktikum.py | 0 requirements.txt | Bin 0 -> 244 bytes test_burger.py | 232 ++++++++++++++++++ 10 files changed, 243 insertions(+) create mode 100644 .gitignore rename __init__.py => praktikum/__init__.py (100%) rename bun.py => praktikum/bun.py (100%) rename burger.py => praktikum/burger.py (100%) rename database.py => praktikum/database.py (100%) rename ingredient.py => praktikum/ingredient.py (100%) rename ingredient_types.py => praktikum/ingredient_types.py (100%) rename praktikum.py => praktikum/praktikum.py (100%) create mode 100644 requirements.txt create mode 100644 test_burger.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..58ec3c51d --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# игнорирую весь каталог __pycache__ +__pycache__ + +# игнорирую весь каталог .pytest_cache +.pytest_cache + +# игнорирую весь каталог .venv +.venv + +# игнорирую все файлы с расширением .pyc +*.pyc \ 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/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..614d33a7b2154e2e2649c64d6cdbcb8c469a2b1b GIT binary patch literal 244 zcmZXP-3o$06oltG=urySOz6UQ=oLh42~EYH3tzta&LJZR8CiC|b7uDStkkPTqe?wc z!I$W$4CUHur@K02T&EkS=uC=#LWwg2la(6&(fN%z{}8Pf+^E&(gYVzwuiQrRYcgg{ j--MtGT>8ma@oL=JeRHhozk6U)?|tkw)-uSN1mE)p^e`lx literal 0 HcmV?d00001 diff --git a/test_burger.py b/test_burger.py new file mode 100644 index 000000000..4db45d9c2 --- /dev/null +++ b/test_burger.py @@ -0,0 +1,232 @@ +import pytest +from unittest.mock import Mock, patch +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_set_buns(self): + """Тест установки булочки в бургер""" + # Arrange + burger = Burger() + mock_bun = Mock(spec=Bun) + mock_bun.name = "white bun" + mock_bun.price = 200 + + # Act + burger.set_buns(mock_bun) + + # Assert + assert burger.bun == mock_bun + + def test_add_ingredient(self): + """Тест добавления ингредиента в бургер""" + # Arrange + burger = Burger() + mock_ingredient = Mock(spec=Ingredient) + mock_ingredient.get_type.return_value = INGREDIENT_TYPE_SAUCE + mock_ingredient.get_name.return_value = "hot sauce" + mock_ingredient.get_price.return_value = 100 + + # Act + burger.add_ingredient(mock_ingredient) + + # Assert + assert len(burger.ingredients) == 1 + assert burger.ingredients[0] == mock_ingredient + + def test_remove_ingredient(self): + """Тест удаления ингредиента из бургера""" + # Arrange + burger = Burger() + + # Создаем моки ингредиентов + mock_sauce = Mock(spec=Ingredient) + mock_sauce.get_type.return_value = INGREDIENT_TYPE_SAUCE + mock_sauce.get_name.return_value = "hot sauce" + + mock_filling = Mock(spec=Ingredient) + mock_filling.get_type.return_value = INGREDIENT_TYPE_FILLING + mock_filling.get_name.return_value = "cutlet" + + # Добавляем ингредиенты + burger.add_ingredient(mock_sauce) + burger.add_ingredient(mock_filling) + + # Act + burger.remove_ingredient(0) # Удаляем первый ингредиент + + # Assert + assert len(burger.ingredients) == 1 + assert burger.ingredients[0] == mock_filling + + def test_move_ingredient(self): + """Тест перемещения ингредиента в бургере""" + # Arrange + burger = Burger() + + # Создаем моки ингредиентов + mock_sauce = Mock(spec=Ingredient) + mock_sauce.get_type.return_value = INGREDIENT_TYPE_SAUCE + mock_sauce.get_name.return_value = "hot sauce" + + mock_filling = Mock(spec=Ingredient) + mock_filling.get_type.return_value = INGREDIENT_TYPE_FILLING + mock_filling.get_name.return_value = "cutlet" + + mock_another_sauce = Mock(spec=Ingredient) + mock_another_sauce.get_type.return_value = INGREDIENT_TYPE_SAUCE + mock_another_sauce.get_name.return_value = "sour cream" + + # Добавляем ингредиенты + burger.add_ingredient(mock_sauce) + burger.add_ingredient(mock_filling) + burger.add_ingredient(mock_another_sauce) + + # Act + burger.move_ingredient(0, 2) # Перемещаем первый ингредиент в конец + + # Assert + assert len(burger.ingredients) == 3 + assert burger.ingredients[0] == mock_filling + assert burger.ingredients[1] == mock_another_sauce + assert burger.ingredients[2] == mock_sauce + + def test_get_price_calculation(self): + """Тест расчета цены бургера""" + # Arrange + burger = Burger() + + # Моки для булочки и ингредиентов + mock_bun = Mock(spec=Bun) + mock_bun.get_price.return_value = 200 + + mock_sauce = Mock(spec=Ingredient) + mock_sauce.get_price.return_value = 100 + + mock_filling = Mock(spec=Ingredient) + mock_filling.get_price.return_value = 150 + + # Устанавливаем компоненты + burger.set_buns(mock_bun) + burger.add_ingredient(mock_sauce) + burger.add_ingredient(mock_filling) + + # Act + price = burger.get_price() + + # Assert + expected_price = 200 * 2 + 100 + 150 # Булочка * 2 + соус + начинка + assert price == expected_price + + def test_get_receipt_formatting(self): + """Тест форматирования чека""" + # Arrange + burger = Burger() + + # Моки для булочки + mock_bun = Mock(spec=Bun) + mock_bun.get_name.return_value = "white bun" + + # Моки для ингредиентов + mock_sauce = Mock(spec=Ingredient) + mock_sauce.get_type.return_value = INGREDIENT_TYPE_SAUCE + mock_sauce.get_name.return_value = "hot sauce" + + mock_filling = Mock(spec=Ingredient) + mock_filling.get_type.return_value = INGREDIENT_TYPE_FILLING + mock_filling.get_name.return_value = "cutlet" + + # Устанавливаем компоненты + burger.set_buns(mock_bun) + burger.add_ingredient(mock_sauce) + burger.add_ingredient(mock_filling) + + # Настраиваем возвращаемые значения для get_price + mock_bun.get_price.return_value = 200 + mock_sauce.get_price.return_value = 100 + mock_filling.get_price.return_value = 150 + + # Act + receipt = burger.get_receipt() + + # Assert + assert "(==== white bun ====)" in receipt + assert "= sauce hot sauce =" in receipt + assert "= filling cutlet =" in receipt + assert "(==== white bun ====)" in receipt + assert "\nPrice: 650" in receipt or "Price: 650" in receipt + + def test_burger_with_only_bun_price(self): + """Тест цены бургера только с булочкой""" + # Arrange + burger = Burger() + mock_bun = Mock(spec=Bun) + mock_bun.get_price.return_value = 200 + + burger.set_buns(mock_bun) + + # Act + price = burger.get_price() + + # Assert + assert price == 400 # 200 * 2 + + def test_remove_nonexistent_ingredient(self): + """Тест попытки удаления несуществующего ингредиента""" + # Arrange + burger = Burger() + + # Act & Assert + with pytest.raises(IndexError): + burger.remove_ingredient(0) + + def test_move_nonexistent_ingredient(self): + """Тест попытки перемещения несуществующего ингредиента""" + # Arrange + burger = Burger() + + # Act & Assert + with pytest.raises(IndexError): + burger.move_ingredient(0, 1) + + def test_add_multiple_ingredients(self): + """Тест добавления нескольких ингредиентов""" + # Arrange + burger = Burger() + + # Создаем 5 моков ингредиентов + mock_ingredients = [] + for i in range(5): + mock_ingredient = Mock(spec=Ingredient) + mock_ingredient.get_type.return_value = INGREDIENT_TYPE_SAUCE if i % 2 == 0 else INGREDIENT_TYPE_FILLING + mock_ingredient.get_name.return_value = f"ingredient_{i}" + mock_ingredients.append(mock_ingredient) + + # Act + for ingredient in mock_ingredients: + burger.add_ingredient(ingredient) + + # Assert + assert len(burger.ingredients) == 5 + for i, mock_ingredient in enumerate(mock_ingredients): + assert burger.ingredients[i] == mock_ingredient + + @patch('praktikum.burger.Burger.get_price') + def test_receipt_uses_get_price(self, mock_get_price): + """Тест, что get_receipt использует метод get_price для расчета стоимости""" + # Arrange + burger = Burger() + mock_bun = Mock(spec=Bun) + mock_bun.get_name.return_value = "test bun" + + burger.set_buns(mock_bun) + mock_get_price.return_value = 500 + + # Act + receipt = burger.get_receipt() + + # Assert + mock_get_price.assert_called_once() + assert "500" in receipt \ No newline at end of file From c375096a8c2dbd18d250c09d0cd134793312bb2a Mon Sep 17 00:00:00 2001 From: Dmitry Ponosov Date: Sun, 18 Jan 2026 20:05:32 +0700 Subject: [PATCH 2/2] Second load --- .coverage | Bin 0 -> 53248 bytes test_burger.py | 17 +++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 .coverage diff --git a/.coverage b/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..7b27042a9ab26098df312c949920c6a80ee7bc85 GIT binary patch literal 53248 zcmeI)U2oG?7zc1WE(u9fxf80Qu0lPUG^G(~Xoj?{>|*Pn5(uQh2Gb^03r=#9c#G{| zJEfKOqB1o0A$GY>z_;M0`vOeb1)8{;G)=pLi#?BzotM%8?$J8wyo z=CiAp?NExA=Q~y?&S>+Ru4^9&p=nx{ZgX@?whZmeBoFAfKC(Y)H>*{CD$SXnYx(pS zn)%h-o91f1o&S6Gm;C$L>$7&IoUPCaY!H9|1R(I*2<%Zy18*}Q(W8l`0}Pu$HYob(6+iNHiYlp5KN_QGVX5*-gq7$~G0z^KHlScf~hyw;UyiuNKOkP#vH`q}_Hog;DIu9T}8` zHK<|3qd0d$Ra@V4PKTc8+HO=$H?Tw7bA{ZIjeaPbhgPu6Xvs!+qqU*3Zg7QesGRY& zMs$Xm56KxPk2AL@IM+*9hZ*_OlsSso?K^cM|GMw=xN#_lx^U=C$~h@-=*5+N;kG%X zEr<0TYtDq6TU6!hyY|h#95jAe40D#FYPeoma3!b*ygi#Pte?;|>XmXQxY?zrPBp6^ zdeP$=HGZv1clkSS9M2S%m-V|hqmIHnwYnV!gPrVHrx_fc&~^CySv4)Z>W)NRrV(EqTZ^nw)Z^74-dNB6-#%ndBJGlF1l}&ro$%GwH&{(xmFd>1x$@=lEV`CR12g z(D&4c;CYE}$HpqbM}|Y-z(Vli;rFbtBc6_(4^!a9W9h;N3zGup5NcJvPv4nOMIrxe zMEVX*`g}9SLgpjGkT1#I)orUwvq{ggeHyYf2dfo8aKffViLJWV52OCe52NnMYtJxV zRlx9ZVo#|`QF0pISG*vwX<6lED>$1R6~&Gf@GKM*Mcwnd(sI?>Kshc3bWJ-DQ4CM7 zN*@l(2zI%Q_I5FfDOp^2n!iSaE*W36<2aVvjMpn(hE=IF_w(T7>!?YDGKwM%%7BLG zfijaqXg3Mk4LbYoN56* z6L74guJOavSkF3ea@ff}p;?-qB8_$~1|Koxhw2JEBdTVvE4n0A`~)di;urY3`B$N;OBdN|}!|^O5=QR8|l{LjVF0fB*y_ z009U<00Izz00bZ~5Xc)R_2kb0shqKtjsFUuKL5Y3nfrsJ*nt29AOHafKmY;|fB*y_ z009U<;7ALs>4w%mcXsP~K;O5p)uS)13AWDLy{_lPziQR3PzGVG-uLPIk?2bn`2By~ z{7s`DY!H9|1Rwwb2tWV=5P$##AOHafOozal(a!#_*Z=tbzv*aLL1KmY;|fB*y_ z009U<00IzrNdbdCEHJ0u|9_&HPhPSVWP<<%AOHafKmY;|fB*y_009U<;7AJ?##~mt z|NlTU9~|jW5gY^{009U<00Izz00bZa0SG_<0uuz@(r2>S3*Z0q>$mqF?l