mirror of
https://github.com/emilybache/GildedRose-Refactoring-Kata.git
synced 2026-10-14 18:15:41 +00:00
Conjured items degrade twice as fast as normal ones. Matched by name prefix so any "Conjured ..." item works, not just the Mana Cake. Wrote the tests first, then the updater. Only the Mana Cake lines changed in the approved output.
121 lines
4.3 KiB
Python
121 lines
4.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""Unit tests for the Gilded Rose inventory rules.
|
|
|
|
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"
|
|
CONJURED_CAKE = "Conjured Mana Cake"
|
|
|
|
|
|
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
|
|
|
|
|
|
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
|
|
|
|
|
|
class TestConjuredItem:
|
|
def test_quality_degrades_twice_as_fast_as_a_normal_item(self):
|
|
assert update(CONJURED_CAKE, 3, 6) == (2, 4)
|
|
|
|
def test_quality_degrades_four_per_day_once_sell_by_date_has_passed(self):
|
|
assert update(CONJURED_CAKE, 0, 6) == (-1, 2)
|
|
|
|
@pytest.mark.parametrize("sell_in, quality", [(3, 1), (0, 3), (-2, 0)])
|
|
def test_quality_is_never_negative(self, sell_in, quality):
|
|
_, new_quality = update(CONJURED_CAKE, sell_in, quality)
|
|
assert new_quality == 0
|
|
|
|
def test_any_item_whose_name_starts_with_conjured_is_conjured(self):
|
|
assert update("Conjured +5 Dexterity Vest", 10, 20) == (9, 18)
|
|
|
|
|
|
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),
|
|
Item(CONJURED_CAKE, 3, 6),
|
|
]
|
|
GildedRose(items).update_quality()
|
|
assert [(i.sell_in, i.quality) for i in items] == [
|
|
(9, 19),
|
|
(1, 1),
|
|
(0, 80),
|
|
(4, 23),
|
|
(2, 4),
|
|
]
|
|
|
|
|
|
def test_an_empty_inventory_is_handled():
|
|
GildedRose([]).update_quality() # must not raise
|