Add unit tests for the existing rules

One test per rule from the requirements, replacing test_foo. Tier
boundaries are checked on both sides, e.g. backstage passes at 11 and 10,
so an off-by-one can't slip through. All pass against the original code
with 100% branch coverage.
This commit is contained in:
uzairarslan committed 2026-09-24 03:21:18 +05:00
1 parent 5f113a1d2f
commit 3809be0b03
1 file changed
+96 -11
+96 -11
View File
@@ -1,16 +1,101 @@
# -*- coding: utf-8 -*-
import unittest
"""Unit tests for the Gilded Rose inventory rules.
from gilded_rose import Item, GildedRose
Each test drives update_quality() for a single day on a single item so that a
failure points at exactly one rule. The 30-day approval test covers the
interaction of rules over time.
"""
import pytest
from gilded_rose import GildedRose, Item
AGED_BRIE = "Aged Brie"
SULFURAS = "Sulfuras, Hand of Ragnaros"
BACKSTAGE_PASS = "Backstage passes to a TAFKAL80ETC concert"
class GildedRoseTest(unittest.TestCase):
def test_foo(self):
items = [Item("foo", 0, 0)]
gilded_rose = GildedRose(items)
gilded_rose.update_quality()
self.assertEqual("fixme", items[0].name)
def update(name, sell_in, quality):
"""Run one day of update_quality() and return (sell_in, quality)."""
item = Item(name, sell_in, quality)
GildedRose([item]).update_quality()
return item.sell_in, item.quality
if __name__ == '__main__':
unittest.main()
class TestNormalItem:
def test_sell_in_and_quality_both_drop_by_one_each_day(self):
assert update("+5 Dexterity Vest", 10, 20) == (9, 19)
def test_quality_degrades_twice_as_fast_once_sell_by_date_has_passed(self):
assert update("+5 Dexterity Vest", 0, 20) == (-1, 18)
@pytest.mark.parametrize("sell_in", [5, 0, -3])
def test_quality_is_never_negative(self, sell_in):
_, quality = update("Elixir of the Mongoose", sell_in, 0)
assert quality == 0
def test_quality_of_one_after_sell_by_clamps_to_zero(self):
assert update("Elixir of the Mongoose", -1, 1) == (-2, 0)
class TestAgedBrie:
def test_quality_increases_by_one_each_day(self):
assert update(AGED_BRIE, 2, 0) == (1, 1)
def test_quality_increases_twice_as_fast_once_sell_by_date_has_passed(self):
assert update(AGED_BRIE, 0, 10) == (-1, 12)
@pytest.mark.parametrize("sell_in, quality", [(5, 50), (0, 50), (0, 49)])
def test_quality_never_exceeds_fifty(self, sell_in, quality):
_, new_quality = update(AGED_BRIE, sell_in, quality)
assert new_quality == 50
class TestSulfuras:
@pytest.mark.parametrize("sell_in", [10, 0, -1])
def test_never_changes(self, sell_in):
assert update(SULFURAS, sell_in, 80) == (sell_in, 80)
class TestBackstagePasses:
# 11 is the day before the first tier boundary, so it guards the off-by-one.
@pytest.mark.parametrize("sell_in", [15, 11])
def test_quality_increases_by_one_when_more_than_ten_days_remain(self, sell_in):
assert update(BACKSTAGE_PASS, sell_in, 20) == (sell_in - 1, 21)
@pytest.mark.parametrize("sell_in", [10, 6]) # 6 is the day before the next tier
def test_quality_increases_by_two_when_ten_days_or_less_remain(self, sell_in):
assert update(BACKSTAGE_PASS, sell_in, 20) == (sell_in - 1, 22)
@pytest.mark.parametrize("sell_in", [5, 1])
def test_quality_increases_by_three_when_five_days_or_less_remain(self, sell_in):
assert update(BACKSTAGE_PASS, sell_in, 20) == (sell_in - 1, 23)
@pytest.mark.parametrize("sell_in, quality", [(15, 50), (10, 49), (5, 48)])
def test_quality_never_exceeds_fifty(self, sell_in, quality):
_, new_quality = update(BACKSTAGE_PASS, sell_in, quality)
assert new_quality == 50
@pytest.mark.parametrize("sell_in", [0, -1])
def test_quality_drops_to_zero_after_the_concert(self, sell_in):
_, quality = update(BACKSTAGE_PASS, sell_in, 40)
assert quality == 0
def test_all_items_in_the_inventory_are_updated():
items = [
Item("+5 Dexterity Vest", 10, 20),
Item(AGED_BRIE, 2, 0),
Item(SULFURAS, 0, 80),
Item(BACKSTAGE_PASS, 5, 20),
]
GildedRose(items).update_quality()
assert [(i.sell_in, i.quality) for i in items] == [
(9, 19),
(1, 1),
(0, 80),
(4, 23),
]
def test_an_empty_inventory_is_handled():
GildedRose([]).update_quality() # must not raise