diff --git a/python/gilded_rose.py b/python/gilded_rose.py index 52224afe..0e7cc1c9 100755 --- a/python/gilded_rose.py +++ b/python/gilded_rose.py @@ -43,6 +43,34 @@ class AgedBrieStrategy: item.quality = min(50, item.quality + 1) +class BackstagePassStrategy: + """ + Quality strategy for backstage passes. + + Quality increases as the concert approaches: + - +1/day when more than 10 days remain + - +2/day when 10 or fewer days remain + - +3/day when 5 or fewer days remain + Quality drops to 0 on concert day (sell_in == 0 at start of day) + and stays 0 afterwards. Quality never exceeds 50. + """ + + def update(self, item: "Item", days: int) -> None: + for _ in range(days): + if item.sell_in <= 0: + # Concert day or past — pass is worthless + item.quality = 0 + item.sell_in -= 1 + continue + if item.sell_in <= 5: + item.quality = min(50, item.quality + 3) + elif item.sell_in <= 10: + item.quality = min(50, item.quality + 2) + else: + item.quality = min(50, item.quality + 1) + item.sell_in -= 1 + + class GildedRose(object): def __init__(self, items): diff --git a/python/tests/test_gilded_rose.py b/python/tests/test_gilded_rose.py index 646fc626..de8ecb38 100644 --- a/python/tests/test_gilded_rose.py +++ b/python/tests/test_gilded_rose.py @@ -7,7 +7,10 @@ _EXERCISE_ROOT = Path(__file__).resolve().parent.parent if str(_EXERCISE_ROOT) not in sys.path: sys.path.insert(0, str(_EXERCISE_ROOT)) -from gilded_rose import Item, GildedRose, NormalStrategy, AgedBrieStrategy +from gilded_rose import ( + Item, GildedRose, NormalStrategy, AgedBrieStrategy, + BackstagePassStrategy, +) class GildedRoseTest(unittest.TestCase): @@ -92,5 +95,56 @@ class TestAgedBrieStrategy(unittest.TestCase): self.assertEqual(-2, item.sell_in) +class TestBackstagePassStrategy(unittest.TestCase): + """Tests for BackstagePassStrategy — tiered increase, zeroes after concert.""" + + def setUp(self): + self.strategy = BackstagePassStrategy() + + def test_quality_increments_by_1_when_more_than_10_days(self): + item = Item("Backstage passes to a TAFKAL80ETC concert", sell_in=15, quality=20) + self.strategy.update(item, days=1) + self.assertEqual(21, item.quality) + self.assertEqual(14, item.sell_in) + + def test_quality_increments_by_2_when_10_or_fewer_days(self): + item = Item("Backstage passes to a TAFKAL80ETC concert", sell_in=10, quality=20) + self.strategy.update(item, days=1) + self.assertEqual(22, item.quality) + self.assertEqual(9, item.sell_in) + + def test_quality_increments_by_3_when_5_or_fewer_days(self): + item = Item("Backstage passes to a TAFKAL80ETC concert", sell_in=5, quality=20) + self.strategy.update(item, days=1) + self.assertEqual(23, item.quality) + self.assertEqual(4, item.sell_in) + + def test_quality_drops_to_zero_on_concert_day(self): + # sell_in=0 means the concert is today — quality zeroes out + item = Item("Backstage passes to a TAFKAL80ETC concert", sell_in=0, quality=30) + self.strategy.update(item, days=1) + self.assertEqual(0, item.quality) + self.assertEqual(-1, item.sell_in) + + def test_quality_stays_zero_after_concert(self): + item = Item("Backstage passes to a TAFKAL80ETC concert", sell_in=-1, quality=0) + self.strategy.update(item, days=1) + self.assertEqual(0, item.quality) + + def test_quality_caps_at_50(self): + item = Item("Backstage passes to a TAFKAL80ETC concert", sell_in=5, quality=49) + self.strategy.update(item, days=1) + self.assertEqual(50, item.quality) + + def test_multi_day_crosses_all_thresholds(self): + # sell_in=12, quality=20, days=4 + # Day1(si=12): +1 q=21 si=11 | Day2(si=11): +1 q=22 si=10 + # Day3(si=10): +2 q=24 si=9 | Day4(si=9): +2 q=26 si=8 + item = Item("Backstage passes to a TAFKAL80ETC concert", sell_in=12, quality=20) + self.strategy.update(item, days=4) + self.assertEqual(26, item.quality) + self.assertEqual(8, item.sell_in) + + if __name__ == '__main__': unittest.main()