Last active
June 23, 2021 14:46
-
-
Save unixcharles/64e88dc2d409a83c994c7343ac152ec3 to your computer and use it in GitHub Desktop.
guilded_rose_kata
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ItemUpdater | |
class AgedBrie < ItemUpdater | |
def value_change | |
-super | |
end | |
end | |
class BackstagePass < ItemUpdater | |
def value_change | |
case sell_in | |
when -Float::INFINITY..0 | |
-quality | |
when 1..5 | |
3 | |
when 5..10 | |
2 | |
else | |
1 | |
end | |
end | |
end | |
class Sulfuras < ItemUpdater | |
def call | |
# no-op | |
end | |
end | |
class Conjured < ItemUpdater | |
def value_change | |
super * 2 | |
end | |
end | |
attr_reader :sell_in, :quality | |
MINIMUM_QUALITY = 0 | |
MAXIMUM_QUALITY = 50 | |
UPDATER_CLASSES = { | |
'Aged Brie' => AgedBrie, | |
'Backstage passes to a TAFKAL80ETC concert' => BackstagePass, | |
'Sulfuras, Hand of Ragnaros' => Sulfuras, | |
'Conjured Mana Cake' => Conjured, | |
} | |
UPDATER_CLASSES.default = self | |
def self.from_name(name) | |
UPDATER_CLASSES[name] | |
end | |
def initialize(sell_in, quality) | |
@sell_in = sell_in | |
@quality = quality | |
end | |
def call | |
@quality = within_boundary(quality + value_change) | |
@sell_in -= 1 | |
end | |
def value_change | |
if sell_in.zero? || sell_in.negative? | |
-2 | |
else | |
-1 | |
end | |
end | |
private | |
def within_boundary(value) | |
value_or_maximum = [MAXIMUM_QUALITY, value].min | |
[MINIMUM_QUALITY, value_or_maximum].max | |
end | |
end | |
class GildedRose | |
def initialize(items) | |
@items = items | |
end | |
def update_quality | |
@items.each do |item| | |
updater = ItemUpdater.from_name(item.name).new(item.sell_in, item.quality) | |
updater.call | |
item.sell_in = updater.sell_in | |
item.quality = updater.quality | |
end | |
end | |
end | |
class Item | |
attr_accessor :name, :sell_in, :quality | |
def initialize(name, sell_in, quality) | |
@name = name | |
@sell_in = sell_in | |
@quality = quality | |
end | |
def to_s | |
"#{@name}, #{@sell_in}, #{@quality}" | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require File.join(File.dirname(__FILE__), 'gilded_rose') | |
describe GildedRose do | |
describe '#update_quality' do | |
subject { GildedRose.new(items) } | |
let(:items) { [item] } | |
let(:item) { Item.new(object_name, 20, 20) } | |
context 'generic objects' do | |
let(:object_name) { 'foo' } | |
it 'does not change the name' do | |
expect { subject.update_quality }.not_to change { item.name } | |
end | |
it 'decrease the sell in date by one' do | |
expect { subject.update_quality }.to change { item.sell_in }.by(-1) | |
end | |
it 'decrease the quality by one' do | |
expect { subject.update_quality }.to change { item.quality }.by(-1) | |
end | |
it 'does not decrease the quality bellow zero' do | |
item.quality = 0 | |
expect { subject.update_quality }.not_to change { item.quality } | |
end | |
it 'decrease the quality by two once the sell in date reach zero' do | |
item.sell_in = 0 | |
expect { subject.update_quality }.to change { item.quality }.by(-2) | |
end | |
end | |
context 'Aged Brie' do | |
let(:object_name) { 'Aged Brie' } | |
it 'does not increase beyond 50' do | |
item.quality = 50 | |
expect { subject.update_quality }.not_to change { item.quality } | |
end | |
it 'increase the quality by one' do | |
expect { subject.update_quality }.to change { item.quality }.by(+1) | |
end | |
it 'increase the quality by two once the sell in date reach zero' do | |
item.sell_in = 0 | |
expect { subject.update_quality }.to change { item.quality }.by(+2) | |
end | |
end | |
context 'Sulfras' do | |
let(:object_name) { 'Sulfuras, Hand of Ragnaros' } | |
it 'does not change the sell in' do | |
expect { subject.update_quality }.not_to change { item.sell_in } | |
end | |
it 'does not change the quality' do | |
expect { subject.update_quality }.not_to change { item.quality } | |
end | |
it 'does not change the quality if the sell in is zero' do | |
item.sell_in = 0 | |
expect { subject.update_quality }.not_to change { item.quality } | |
end | |
end | |
context 'Backstage passes' do | |
let(:object_name) { 'Backstage passes to a TAFKAL80ETC concert' } | |
it 'increase quality by one when the sell in is more than 10 days' do | |
item.sell_in = 11 | |
expect { subject.update_quality }.to change { item.quality }.by(+1) | |
end | |
it 'increase quality by two when the sell in is at 10 days' do | |
item.sell_in = 10 | |
expect { subject.update_quality }.to change { item.quality }.by(+2) | |
end | |
it 'increase quality by three when the sell in is at 5 days' do | |
item.sell_in = 5 | |
expect { subject.update_quality }.to change { item.quality }.by(+3) | |
end | |
it 'drop quality to zero when the sell in is zero' do | |
item.sell_in = 0 | |
subject.update_quality | |
expect(item.quality).to be_zero | |
end | |
end | |
context 'Conjured' do | |
let(:object_name) { 'Conjured Mana Cake' } | |
it 'decrease the quality by two' do | |
expect { subject.update_quality }.to change { item.quality }.by(-2) | |
end | |
it 'decrease the quality by four once the sell in date reach zero' do | |
item.sell_in = 0 | |
expect { subject.update_quality }.to change { item.quality }.by(-4) | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment