From b97af8ca668ed7cf66259232a637f4181611ff37 Mon Sep 17 00:00:00 2001 From: James Thompson Date: Wed, 27 Oct 2021 11:54:16 -0400 Subject: [PATCH 01/17] Wrap item struct in a decorator to give us a place to hang behavior. --- lib/gilded_rose.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index 5cced0fe..4b49ac40 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -1,5 +1,9 @@ +class ItemDecorator < SimpleDelegator; end + def update_quality(items) items.each do |item| + item = ItemDecorator.new(item) + if item.name != 'Aged Brie' && item.name != 'Backstage passes to a TAFKAL80ETC concert' if item.quality > 0 if item.name != 'Sulfuras, Hand of Ragnaros' From 1ab0a5d0b9d3b11b05d084cbfbfe0644764976dd Mon Sep 17 00:00:00 2001 From: James Thompson Date: Wed, 27 Oct 2021 11:56:45 -0400 Subject: [PATCH 02/17] Extract decrement quality behavior to ItemDecorator. --- lib/gilded_rose.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index 4b49ac40..dea5a826 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -1,4 +1,8 @@ -class ItemDecorator < SimpleDelegator; end +class ItemDecorator < SimpleDelegator + def decrement_quality + self.quality -= 1 + end +end def update_quality(items) items.each do |item| @@ -7,7 +11,7 @@ def update_quality(items) if item.name != 'Aged Brie' && item.name != 'Backstage passes to a TAFKAL80ETC concert' if item.quality > 0 if item.name != 'Sulfuras, Hand of Ragnaros' - item.quality -= 1 + item.decrement_quality end end else @@ -35,7 +39,7 @@ def update_quality(items) if item.name != 'Backstage passes to a TAFKAL80ETC concert' if item.quality > 0 if item.name != 'Sulfuras, Hand of Ragnaros' - item.quality -= 1 + item.decrement_quality end end else From e56f98f2e52961e6ac96a32d117facffc6d03a06 Mon Sep 17 00:00:00 2001 From: James Thompson Date: Wed, 27 Oct 2021 11:57:59 -0400 Subject: [PATCH 03/17] Extract increment quality behavior to ItemDecorator. --- lib/gilded_rose.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index dea5a826..343f2955 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -2,6 +2,10 @@ class ItemDecorator < SimpleDelegator def decrement_quality self.quality -= 1 end + + def increment_quality + self.quality += 1 + end end def update_quality(items) @@ -16,16 +20,17 @@ def update_quality(items) end else if item.quality < 50 - item.quality += 1 + item.increment_quality + if item.name == 'Backstage passes to a TAFKAL80ETC concert' if item.sell_in < 11 if item.quality < 50 - item.quality += 1 + item.increment_quality end end if item.sell_in < 6 if item.quality < 50 - item.quality += 1 + item.increment_quality end end end @@ -47,7 +52,7 @@ def update_quality(items) end else if item.quality < 50 - item.quality += 1 + item.increment_quality end end end From 2cd52a167f37d44df0e5e5ae420b8e897d03a340 Mon Sep 17 00:00:00 2001 From: James Thompson Date: Wed, 27 Oct 2021 11:58:53 -0400 Subject: [PATCH 04/17] Extract decrement sell-in behavior to ItemDecorator. --- lib/gilded_rose.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index 343f2955..17a49bae 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -6,6 +6,10 @@ def decrement_quality def increment_quality self.quality += 1 end + + def decrement_sell_in + self.sell_in -= 1 + end end def update_quality(items) @@ -37,7 +41,7 @@ def update_quality(items) end end if item.name != 'Sulfuras, Hand of Ragnaros' - item.sell_in -= 1 + item.decrement_sell_in end if item.sell_in < 0 if item.name != "Aged Brie" From 53915d76e9dd52efe76d8f33ee5f96261cf434cb Mon Sep 17 00:00:00 2001 From: James Thompson Date: Wed, 27 Oct 2021 11:59:52 -0400 Subject: [PATCH 05/17] Extract behavior for zeroing out quality to ItemDecorator. --- lib/gilded_rose.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index 17a49bae..51250e77 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -10,6 +10,10 @@ def increment_quality def decrement_sell_in self.sell_in -= 1 end + + def zero_out_quality + self.quality = 0 + end end def update_quality(items) @@ -52,7 +56,7 @@ def update_quality(items) end end else - item.quality = item.quality - item.quality + item.zero_out_quality end else if item.quality < 50 From af5209e285211c9db5e7fd6efa34d993d73fdce7 Mon Sep 17 00:00:00 2001 From: James Thompson Date: Thu, 28 Oct 2021 11:44:09 -0400 Subject: [PATCH 06/17] Moved quality guard clauses into ItemDecorator. --- lib/gilded_rose.rb | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index 51250e77..f530a84f 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -1,10 +1,10 @@ class ItemDecorator < SimpleDelegator def decrement_quality - self.quality -= 1 + self.quality -= 1 if self.quality > 0 end def increment_quality - self.quality += 1 + self.quality += 1 if self.quality < 50 end def decrement_sell_in @@ -21,26 +21,18 @@ def update_quality(items) item = ItemDecorator.new(item) if item.name != 'Aged Brie' && item.name != 'Backstage passes to a TAFKAL80ETC concert' - if item.quality > 0 - if item.name != 'Sulfuras, Hand of Ragnaros' - item.decrement_quality - end + if item.name != 'Sulfuras, Hand of Ragnaros' + item.decrement_quality end else - if item.quality < 50 - item.increment_quality + item.increment_quality - if item.name == 'Backstage passes to a TAFKAL80ETC concert' - if item.sell_in < 11 - if item.quality < 50 - item.increment_quality - end - end - if item.sell_in < 6 - if item.quality < 50 - item.increment_quality - end - end + if item.name == 'Backstage passes to a TAFKAL80ETC concert' + if item.sell_in < 11 + item.increment_quality + end + if item.sell_in < 6 + item.increment_quality end end end @@ -50,18 +42,14 @@ def update_quality(items) if item.sell_in < 0 if item.name != "Aged Brie" if item.name != 'Backstage passes to a TAFKAL80ETC concert' - if item.quality > 0 - if item.name != 'Sulfuras, Hand of Ragnaros' - item.decrement_quality - end + if item.name != 'Sulfuras, Hand of Ragnaros' + item.decrement_quality end else item.zero_out_quality end else - if item.quality < 50 - item.increment_quality - end + item.increment_quality end end end From d0961d1573495781e82f527fe736eb8b87aab9ce Mon Sep 17 00:00:00 2001 From: James Thompson Date: Thu, 28 Oct 2021 11:58:21 -0400 Subject: [PATCH 07/17] Restructure conditionals into flatter case statement. --- lib/gilded_rose.rb | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index f530a84f..5bc92519 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -20,36 +20,35 @@ def update_quality(items) items.each do |item| item = ItemDecorator.new(item) - if item.name != 'Aged Brie' && item.name != 'Backstage passes to a TAFKAL80ETC concert' - if item.name != 'Sulfuras, Hand of Ragnaros' - item.decrement_quality - end - else + case item.name + when 'NORMAL ITEM' + item.decrement_quality + when 'Aged Brie' item.increment_quality - - if item.name == 'Backstage passes to a TAFKAL80ETC concert' - if item.sell_in < 11 - item.increment_quality - end - if item.sell_in < 6 - item.increment_quality - end + when 'Backstage passes to a TAFKAL80ETC concert' + item.increment_quality + if item.sell_in < 11 + item.increment_quality + end + if item.sell_in < 6 + item.increment_quality end end + if item.name != 'Sulfuras, Hand of Ragnaros' item.decrement_sell_in end + if item.sell_in < 0 - if item.name != "Aged Brie" - if item.name != 'Backstage passes to a TAFKAL80ETC concert' - if item.name != 'Sulfuras, Hand of Ragnaros' - item.decrement_quality - end - else - item.zero_out_quality - end - else + case item.name + when "Aged Brie" item.increment_quality + when 'Backstage passes to a TAFKAL80ETC concert' + item.zero_out_quality + when 'Sulfuras, Hand of Ragnaros' + # No-Op + else + item.decrement_quality end end end From 6d7614772b89a7eb0080fa104372011dc7cc0cc1 Mon Sep 17 00:00:00 2001 From: James Thompson Date: Thu, 28 Oct 2021 12:01:00 -0400 Subject: [PATCH 08/17] Consolidate case statements to capture type differentiation. --- lib/gilded_rose.rb | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index 5bc92519..d6aa8e97 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -23,8 +23,12 @@ def update_quality(items) case item.name when 'NORMAL ITEM' item.decrement_quality + item.decrement_sell_in + item.decrement_quality if item.sell_in < 0 when 'Aged Brie' item.increment_quality + item.decrement_sell_in + item.increment_quality if item.sell_in < 0 when 'Backstage passes to a TAFKAL80ETC concert' item.increment_quality if item.sell_in < 11 @@ -33,23 +37,10 @@ def update_quality(items) if item.sell_in < 6 item.increment_quality end - end - - if item.name != 'Sulfuras, Hand of Ragnaros' item.decrement_sell_in - end - - if item.sell_in < 0 - case item.name - when "Aged Brie" - item.increment_quality - when 'Backstage passes to a TAFKAL80ETC concert' - item.zero_out_quality - when 'Sulfuras, Hand of Ragnaros' - # No-Op - else - item.decrement_quality - end + item.zero_out_quality if item.sell_in < 0 + else # Legendary Items + # No-Op end end end From 52d025c8e758ffdd697b59ab362d9cd7c408da75 Mon Sep 17 00:00:00 2001 From: James Thompson Date: Thu, 28 Oct 2021 12:03:37 -0400 Subject: [PATCH 09/17] Move conditional into ItemDecorator#update method. --- lib/gilded_rose.rb | 50 ++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index d6aa8e97..7d207c62 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -1,4 +1,29 @@ class ItemDecorator < SimpleDelegator + def update + case self.name + when 'NORMAL ITEM' + decrement_quality + decrement_sell_in + decrement_quality if self.sell_in < 0 + when 'Aged Brie' + increment_quality + decrement_sell_in + increment_quality if self.sell_in < 0 + when 'Backstage passes to a TAFKAL80ETC concert' + increment_quality + if self.sell_in < 11 + increment_quality + end + if self.sell_in < 6 + increment_quality + end + decrement_sell_in + zero_out_quality if self.sell_in < 0 + else # Legendary Items + # No-Op + end + end + def decrement_quality self.quality -= 1 if self.quality > 0 end @@ -18,30 +43,7 @@ def zero_out_quality def update_quality(items) items.each do |item| - item = ItemDecorator.new(item) - - case item.name - when 'NORMAL ITEM' - item.decrement_quality - item.decrement_sell_in - item.decrement_quality if item.sell_in < 0 - when 'Aged Brie' - item.increment_quality - item.decrement_sell_in - item.increment_quality if item.sell_in < 0 - when 'Backstage passes to a TAFKAL80ETC concert' - item.increment_quality - if item.sell_in < 11 - item.increment_quality - end - if item.sell_in < 6 - item.increment_quality - end - item.decrement_sell_in - item.zero_out_quality if item.sell_in < 0 - else # Legendary Items - # No-Op - end + ItemDecorator.new(item).update end end From 049d1e762160639b73fc6d16690fb733f11fb533 Mon Sep 17 00:00:00 2001 From: James Thompson Date: Thu, 28 Oct 2021 12:15:56 -0400 Subject: [PATCH 10/17] Make internal methods for ItemDecorator private. --- lib/gilded_rose.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index 7d207c62..965c4870 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -24,6 +24,8 @@ def update end end + private + def decrement_quality self.quality -= 1 if self.quality > 0 end From b92abb364188cf4daf3e03109a9cc206ef9bea85 Mon Sep 17 00:00:00 2001 From: James Thompson Date: Thu, 28 Oct 2021 12:17:01 -0400 Subject: [PATCH 11/17] Isolate Aged Brie's update logic into subclass. --- lib/gilded_rose.rb | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index 965c4870..ca8663a3 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -5,10 +5,6 @@ def update decrement_quality decrement_sell_in decrement_quality if self.sell_in < 0 - when 'Aged Brie' - increment_quality - decrement_sell_in - increment_quality if self.sell_in < 0 when 'Backstage passes to a TAFKAL80ETC concert' increment_quality if self.sell_in < 11 @@ -43,9 +39,22 @@ def zero_out_quality end end +class AgedBrie < ItemDecorator + def update + increment_quality + decrement_sell_in + increment_quality if self.sell_in < 0 + end +end + def update_quality(items) items.each do |item| - ItemDecorator.new(item).update + case item.name + when 'Aged Brie' + AgedBrie.new(item).update + else + ItemDecorator.new(item).update + end end end From e2077fd8fb0b3e08b1fd3a5670513aef451419db Mon Sep 17 00:00:00 2001 From: James Thompson Date: Thu, 28 Oct 2021 12:19:04 -0400 Subject: [PATCH 12/17] Isolate Backstage Pass' update logic into subclass. --- lib/gilded_rose.rb | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index ca8663a3..3b5f74d7 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -5,16 +5,6 @@ def update decrement_quality decrement_sell_in decrement_quality if self.sell_in < 0 - when 'Backstage passes to a TAFKAL80ETC concert' - increment_quality - if self.sell_in < 11 - increment_quality - end - if self.sell_in < 6 - increment_quality - end - decrement_sell_in - zero_out_quality if self.sell_in < 0 else # Legendary Items # No-Op end @@ -47,11 +37,27 @@ def update end end +class BackstagePass < ItemDecorator + def update + increment_quality + if self.sell_in < 11 + increment_quality + end + if self.sell_in < 6 + increment_quality + end + decrement_sell_in + zero_out_quality if self.sell_in < 0 + end +end + def update_quality(items) items.each do |item| case item.name when 'Aged Brie' AgedBrie.new(item).update + when 'Backstage passes to a TAFKAL80ETC concert' + BackstagePass.new(item).update else ItemDecorator.new(item).update end From f0ec6217735e56becd4b3a63ddd92b55aa1f4bf3 Mon Sep 17 00:00:00 2001 From: James Thompson Date: Thu, 28 Oct 2021 12:20:55 -0400 Subject: [PATCH 13/17] Isolate Legendary item update logic into subclass and clean up normal item update logic. --- lib/gilded_rose.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index 3b5f74d7..74c2d290 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -1,13 +1,8 @@ class ItemDecorator < SimpleDelegator def update - case self.name - when 'NORMAL ITEM' - decrement_quality - decrement_sell_in - decrement_quality if self.sell_in < 0 - else # Legendary Items - # No-Op - end + decrement_quality + decrement_sell_in + decrement_quality if self.sell_in < 0 end private @@ -51,6 +46,10 @@ def update end end +class LegendaryItem < ItemDecorator + def update; end # No-Op +end + def update_quality(items) items.each do |item| case item.name @@ -58,6 +57,8 @@ def update_quality(items) AgedBrie.new(item).update when 'Backstage passes to a TAFKAL80ETC concert' BackstagePass.new(item).update + when 'Sulfuras, Hand of Ragnaros' + LegendaryItem.new(item).update else ItemDecorator.new(item).update end From faf7bc4e6b6c7a219b48d75fafb25f780711bcaf Mon Sep 17 00:00:00 2001 From: James Thompson Date: Thu, 28 Oct 2021 12:21:45 -0400 Subject: [PATCH 14/17] Inlined guard clauses for Backstage Pass' update method. --- lib/gilded_rose.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index 74c2d290..62c30073 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -35,12 +35,8 @@ def update class BackstagePass < ItemDecorator def update increment_quality - if self.sell_in < 11 - increment_quality - end - if self.sell_in < 6 - increment_quality - end + increment_quality if self.sell_in < 11 + increment_quality if self.sell_in < 6 decrement_sell_in zero_out_quality if self.sell_in < 0 end From 01e20ca74ab151feac80fd16cf6fa6a38cd89d7d Mon Sep 17 00:00:00 2001 From: James Thompson Date: Thu, 28 Oct 2021 12:25:23 -0400 Subject: [PATCH 15/17] Isolate factory behavior in ItemDecorator.decorate class method. --- lib/gilded_rose.rb | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index 62c30073..2ae0d79a 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -1,4 +1,17 @@ class ItemDecorator < SimpleDelegator + def self.decorate(item) + case item.name + when 'Aged Brie' + AgedBrie.new(item) + when 'Backstage passes to a TAFKAL80ETC concert' + BackstagePass.new(item) + when 'Sulfuras, Hand of Ragnaros' + LegendaryItem.new(item) + else + ItemDecorator.new(item) + end + end + def update decrement_quality decrement_sell_in @@ -48,16 +61,7 @@ def update; end # No-Op def update_quality(items) items.each do |item| - case item.name - when 'Aged Brie' - AgedBrie.new(item).update - when 'Backstage passes to a TAFKAL80ETC concert' - BackstagePass.new(item).update - when 'Sulfuras, Hand of Ragnaros' - LegendaryItem.new(item).update - else - ItemDecorator.new(item).update - end + ItemDecorator.decorate(item).update end end From c278d359fbe4952453c1ec306a7129649919899d Mon Sep 17 00:00:00 2001 From: James Thompson Date: Thu, 28 Oct 2021 12:28:23 -0400 Subject: [PATCH 16/17] Introduce Conjured items into the Gilded Rose. --- lib/gilded_rose.rb | 12 ++++++++++++ spec/gilded_rose_spec.rb | 12 ++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index 2ae0d79a..e38bee24 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -7,6 +7,8 @@ def self.decorate(item) BackstagePass.new(item) when 'Sulfuras, Hand of Ragnaros' LegendaryItem.new(item) + when 'Conjured Mana Cake' + ConjuredItem.new(item) else ItemDecorator.new(item) end @@ -59,6 +61,16 @@ class LegendaryItem < ItemDecorator def update; end # No-Op end +class ConjuredItem < ItemDecorator + def update + decrement_quality + decrement_quality + decrement_sell_in + decrement_quality if self.sell_in < 0 + decrement_quality if self.sell_in < 0 + end +end + def update_quality(items) items.each do |item| ItemDecorator.decorate(item).update diff --git a/spec/gilded_rose_spec.rb b/spec/gilded_rose_spec.rb index 0503195f..ceb6e7ac 100644 --- a/spec/gilded_rose_spec.rb +++ b/spec/gilded_rose_spec.rb @@ -191,36 +191,36 @@ context 'before the sell date' do let(:initial_sell_in) { 5 } - xit { expect(item.quality).to eq(initial_quality - 2) } + it { expect(item.quality).to eq(initial_quality - 2) } context 'at zero quality' do let(:initial_quality) { 0 } - xit { expect(item.quality).to eq(initial_quality) } + it { expect(item.quality).to eq(initial_quality) } end end context 'on sell date' do let(:initial_sell_in) { 0 } - xit { expect(item.quality).to eq(initial_quality - 4) } + it { expect(item.quality).to eq(initial_quality - 4) } context 'at zero quality' do let(:initial_quality) { 0 } - xit { expect(item.quality).to eq(initial_quality) } + it { expect(item.quality).to eq(initial_quality) } end end context 'after sell date' do let(:initial_sell_in) { -10 } - xit { expect(item.quality).to eq(initial_quality - 4) } + it { expect(item.quality).to eq(initial_quality - 4) } context 'at zero quality' do let(:initial_quality) { 0 } - xit { expect(item.quality).to eq(initial_quality) } + it { expect(item.quality).to eq(initial_quality) } end end end From c0923a2f9c73121b1d23ef2c564984d1062d46b4 Mon Sep 17 00:00:00 2001 From: James Thompson Date: Thu, 28 Oct 2021 13:57:32 -0400 Subject: [PATCH 17/17] Fix issue with SimpleDelegator inclusion for Ruby 2.7+ --- lib/gilded_rose.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/gilded_rose.rb b/lib/gilded_rose.rb index e38bee24..3445e3ad 100644 --- a/lib/gilded_rose.rb +++ b/lib/gilded_rose.rb @@ -1,3 +1,5 @@ +require 'delegate' + class ItemDecorator < SimpleDelegator def self.decorate(item) case item.name