Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
GildedRose kata
ITEM_AGED_BRIE = "Aged Brie".freeze
ITEM_BACKSTAGE_PASS = "Backstage passes to a TAFKAL80ETC concert".freeze
ITEM_SULFURAS = "Sulfuras, Hand of Ragnaros".freeze
class GildedRose
def initialize(items)
@items = items
end
def update_quality()
@items.each(&:update!)
end
end
class Item
class << self
def new(name, sell_in, quality)
if self == Item
case name
when ITEM_AGED_BRIE then AgedBrie.new(name, sell_in, quality)
when ITEM_BACKSTAGE_PASS then BackstagePass.new(name, sell_in, quality)
when ITEM_SULFURAS then Sulfuras.new(name, sell_in, quality)
else BasicItem.new(name, sell_in, quality)
end
else
super
end
end
end
def initialize(name, sell_in, quality)
@name = name
@sell_in = sell_in
@quality = quality
end
def to_s()
"#{@name}, #{@sell_in}, #{@quality}"
end
def name
@name
end
def sell_in
@sell_in
end
def quality
@quality
end
def update!
update_sell_in!
update_quality!
clamp_quality!
end
def update_sell_in!
@sell_in = @sell_in - 1
end
def update_quality!
raise "Override in subclass"
end
def clamp_quality!
@quality = [@quality, 0].max
@quality = [@quality, 50].min
end
end
class BasicItem < Item
def update_quality!
if @sell_in < 0
@quality -= 2
else
@quality -= 1
end
end
end
class AgedBrie < Item
def update_quality!
if @sell_in < 0
@quality += 2
else
@quality += 1
end
end
end
class BackstagePass < Item
def update_quality!
case @sell_in
when 11..Float::INFINITY then @quality += 1
when 5..10 then @quality += 2
when 0..5 then @quality += 3
else @quality = 0
end
end
end
class Sulfuras < Item
def update_sell_in!; end
def update_quality!; end
def clamp_quality!; end
end
require File.join(File.dirname(__FILE__), 'gilded_rose')
shared_examples "ends with sell_in" do |new_sell_in|
it do
GildedRose.new(items).update_quality()
expect(items[0].sell_in).to eq(new_sell_in)
end
end
shared_examples "ends with quality" do |new_quality|
it do
GildedRose.new(items).update_quality()
expect(items[0].quality).to eq(new_quality)
end
end
describe GildedRose do
describe "#update_quality" do
let(:item_name) { "foo" }
let(:items) { [Item.new(item_name, sell_in, quality)] }
it "does not change the name" do
items = [Item.new(item_name, 0, 0)]
GildedRose.new(items).update_quality()
expect(items[0].name).to eq("foo")
end
context "when the sell by date has not passed" do
let(:sell_in) { 1 }
context "for basic item" do
context "when quality is 0" do
let(:quality) { 0 }
it_behaves_like "ends with sell_in", 0
it_behaves_like "ends with quality", 0
end
context "when quality is greater than 0" do
let(:quality) { 10 }
it_behaves_like "ends with sell_in", 0
it_behaves_like "ends with quality", 9
end
end
context "for Aged Brie" do
let(:item_name) { "Aged Brie" }
context "when quality is 50" do
let(:quality) { 50 }
it_behaves_like "ends with sell_in", 0
it_behaves_like "ends with quality", 50
end
context "when quality is less than 50" do
let(:quality) { 10 }
it_behaves_like "ends with sell_in", 0
it_behaves_like "ends with quality", 11
end
end
context "for Sulfuras" do
let(:item_name) { "Sulfuras, Hand of Ragnaros" }
let(:quality) { 80 }
it_behaves_like "ends with sell_in", 1
it_behaves_like "ends with quality", 80
end
context "for Backstage" do
let(:item_name) { "Backstage passes to a TAFKAL80ETC concert" }
let(:quality) { 10 }
context "when sell_in is more than 10" do
let(:sell_in) { 15 }
it_behaves_like "ends with sell_in", 14
it_behaves_like "ends with quality", 11
end
context "when sell_in is >5 but <=10" do
let(:sell_in) { 10 }
it_behaves_like "ends with sell_in", 9
it_behaves_like "ends with quality", 12
end
context "when sell_in is <=5" do
let(:sell_in) { 5 }
it_behaves_like "ends with sell_in", 4
it_behaves_like "ends with quality", 13
end
end
end
context "when the sell by date has passed" do
let(:sell_in) { -1 }
context "for basic item" do
context "when quality is 0" do
let(:quality) { 0 }
it_behaves_like "ends with sell_in", -2
it_behaves_like "ends with quality", 0
end
context "when quality is greater than 0" do
let(:quality) { 10 }
it_behaves_like "ends with sell_in", -2
it_behaves_like "ends with quality", 8
end
end
context "for Aged Brie" do
let(:item_name) { "Aged Brie" }
context "when quality is 50" do
let(:quality) { 50 }
it_behaves_like "ends with sell_in", -2
it_behaves_like "ends with quality", 50
end
context "when quality is less than 50" do
let(:quality) { 10 }
it_behaves_like "ends with sell_in", -2
it_behaves_like "ends with quality", 12
end
end
context "for Sulfuras" do
let(:item_name) { "Sulfuras, Hand of Ragnaros" }
let(:quality) { 80 }
it_behaves_like "ends with sell_in", -1
it_behaves_like "ends with quality", 80
end
context "for Backstage" do
let(:item_name) { "Backstage passes to a TAFKAL80ETC concert" }
let(:quality) { 10 }
it_behaves_like "ends with sell_in", -2
it_behaves_like "ends with quality", 0
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.