diff --git a/go/gildedrose/domain/Item.go b/go/gildedrose/domain/Item.go new file mode 100644 index 00000000..b7140a7f --- /dev/null +++ b/go/gildedrose/domain/Item.go @@ -0,0 +1,6 @@ +package domain + +type Item struct { + Name string + SellIn, Quality int +} diff --git a/go/gildedrose/gildedrose.go b/go/gildedrose/gildedrose.go index e0f17e12..70ba2477 100644 --- a/go/gildedrose/gildedrose.go +++ b/go/gildedrose/gildedrose.go @@ -1,58 +1,96 @@ package gildedrose -type Item struct { - Name string - SellIn, Quality int +import ( + "github.com/emilybache/gildedrose-refactoring-kata/gildedrose/domain" +) + +const ( + AgedBrie = "Aged Brie" + BackstagePasses = "Backstage passes to a TAFKAL80ETC concert" + Sulfuras = "Sulfuras, Hand of Ragnaros" + Conjured = "Conjured Mana Cake" + MaxQuality = 50 + MinQuality = 0 + SulfurasQuality = 80 + Expired = 0 + Backstage10Days = 10 + Backstage5Days = 5 + NormalDegradeRate = 1 + ConjuredDegradeRate = 2 +) + +func UpdateQuality(items []*domain.Item) { + for _, item := range items { + updateItem(item) + validateQuality(item) + } } - -func UpdateQuality(items []*Item) { - for i := 0; i < len(items); i++ { - - if items[i].Name != "Aged Brie" && items[i].Name != "Backstage passes to a TAFKAL80ETC concert" { - if items[i].Quality > 0 { - if items[i].Name != "Sulfuras, Hand of Ragnaros" { - items[i].Quality = items[i].Quality - 1 - } - } - } else { - if items[i].Quality < 50 { - items[i].Quality = items[i].Quality + 1 - if items[i].Name == "Backstage passes to a TAFKAL80ETC concert" { - if items[i].SellIn < 11 { - if items[i].Quality < 50 { - items[i].Quality = items[i].Quality + 1 - } - } - if items[i].SellIn < 6 { - if items[i].Quality < 50 { - items[i].Quality = items[i].Quality + 1 - } - } - } - } - } - - if items[i].Name != "Sulfuras, Hand of Ragnaros" { - items[i].SellIn = items[i].SellIn - 1 - } - - if items[i].SellIn < 0 { - if items[i].Name != "Aged Brie" { - if items[i].Name != "Backstage passes to a TAFKAL80ETC concert" { - if items[i].Quality > 0 { - if items[i].Name != "Sulfuras, Hand of Ragnaros" { - items[i].Quality = items[i].Quality - 1 - } - } - } else { - items[i].Quality = items[i].Quality - items[i].Quality - } - } else { - if items[i].Quality < 50 { - items[i].Quality = items[i].Quality + 1 - } - } +func validateQuality(item *domain.Item) { + if item.Name == Sulfuras { + if item.Quality != SulfurasQuality { + item.Quality = SulfurasQuality } + return + } + if item.Quality > MaxQuality || item.Quality < MinQuality { + item.Quality = MinQuality + } +} +func updateItem(item *domain.Item) { + switch item.Name { + case AgedBrie: + incrementQuality(item) + case BackstagePasses: + updateBackstagePasses(item) + case Sulfuras: + // Sulfuras does not change in quality or sell-in + case Conjured: + degradeQuality(item, ConjuredDegradeRate) + default: + degradeQuality(item, NormalDegradeRate) } + if item.Name != Sulfuras { + item.SellIn-- + } + + if item.SellIn < Expired { + handleExpiredItem(item) + } +} + +func incrementQuality(item *domain.Item) { + if item.Quality < MaxQuality { + item.Quality++ + } +} +func updateBackstagePasses(item *domain.Item) { + incrementQuality(item) + if item.SellIn <= Backstage10Days && item.Quality < MaxQuality { + item.Quality++ + } + if item.SellIn <= Backstage5Days && item.Quality < MaxQuality { + item.Quality++ + } +} + +func degradeQuality(item *domain.Item, degradeRate int) { + if item.Quality > MinQuality { + item.Quality -= degradeRate + } +} + +func handleExpiredItem(item *domain.Item) { + switch item.Name { + case AgedBrie: + incrementQuality(item) + case BackstagePasses: + item.Quality = MinQuality + case Conjured: + degradeQuality(item, ConjuredDegradeRate) + case Sulfuras: + // Sulfuras does not change in quality or sell-in + default: + degradeQuality(item, NormalDegradeRate) + } } diff --git a/go/gildedrose/gildedrose_test.go b/go/gildedrose/gildedrose_test.go index ec1bf49b..813f9fca 100644 --- a/go/gildedrose/gildedrose_test.go +++ b/go/gildedrose/gildedrose_test.go @@ -1,19 +1,126 @@ package gildedrose_test import ( - "testing" - "github.com/emilybache/gildedrose-refactoring-kata/gildedrose" + "github.com/emilybache/gildedrose-refactoring-kata/gildedrose/domain" + "github.com/stretchr/testify/require" + "testing" ) -func Test_Foo(t *testing.T) { - var items = []*gildedrose.Item{ - {"foo", 0, 0}, +func Test_UpdateQuality(t *testing.T) { + + type TestConfig struct { + name string + testData []*domain.Item + expected domain.Item } - gildedrose.UpdateQuality(items) + for _, tc := range []TestConfig{ + { + name: "Quality of an item is never less than 0", + testData: []*domain.Item{{Name: "Normal Item", SellIn: 10, Quality: 0}}, + expected: domain.Item{Name: "Normal Item", SellIn: 9, Quality: 0}, + }, + { + name: "Quality of an item degrade twice as sellIn date passed", + testData: []*domain.Item{{Name: "Normal Item", SellIn: 0, Quality: 10}}, + expected: domain.Item{Name: "Normal Item", SellIn: -1, Quality: 8}, + }, + { + name: "Quality of an item degrade once as sellIn date not passed", + testData: []*domain.Item{{Name: "Normal Item", SellIn: 10, Quality: 10}}, + expected: domain.Item{Name: "Normal Item", SellIn: 9, Quality: 9}, + }, - if items[0].Name != "fixme" { - t.Errorf("Name: Expected %s but got %s ", "fixme", items[0].Name) + { + name: "Sell by date not passed, increase AgedBrie quality by 1", + testData: []*domain.Item{{Name: gildedrose.AgedBrie, SellIn: 3, Quality: 40}}, + expected: domain.Item{Name: gildedrose.AgedBrie, SellIn: 2, Quality: 41}, + }, + { + name: "Quality of an AgedBrie is never more than 50", + testData: []*domain.Item{{Name: gildedrose.AgedBrie, SellIn: 10, Quality: 50}}, + expected: domain.Item{Name: gildedrose.AgedBrie, SellIn: 9, Quality: 50}, + }, + { + name: "Quality of an item upgrade twice as sellIn date passed - AgedBrie", + testData: []*domain.Item{{Name: gildedrose.AgedBrie, SellIn: 0, Quality: 40}}, + expected: domain.Item{Name: gildedrose.AgedBrie, SellIn: -1, Quality: 42}, + }, + { + name: "BackstagePasses increase in quality as SellIn approaches - 15 days", + testData: []*domain.Item{{Name: gildedrose.BackstagePasses, SellIn: 15, Quality: 20}}, + expected: domain.Item{Name: gildedrose.BackstagePasses, SellIn: 14, Quality: 21}, + }, + { + name: "BackstagePasses increase in quality by 2 when SellIn <= 10", + testData: []*domain.Item{{Name: gildedrose.BackstagePasses, SellIn: 10, Quality: 20}}, + expected: domain.Item{Name: gildedrose.BackstagePasses, SellIn: 9, Quality: 22}, + }, + { + name: "BackstagePasses increase in quality by 3 when SellIn <= 5", + testData: []*domain.Item{{Name: gildedrose.BackstagePasses, SellIn: 5, Quality: 20}}, + expected: domain.Item{Name: gildedrose.BackstagePasses, SellIn: 4, Quality: 23}, + }, + { + name: "BackstagePasses increase in quality by 3 when SellIn <= 5, quality 49", + testData: []*domain.Item{{Name: gildedrose.BackstagePasses, SellIn: 5, Quality: 49}}, + expected: domain.Item{Name: gildedrose.BackstagePasses, SellIn: 4, Quality: 50}, + }, + { + name: "BackstagePasses drop to 0 quality after concert", + testData: []*domain.Item{{Name: gildedrose.BackstagePasses, SellIn: 0, Quality: 20}}, + expected: domain.Item{Name: gildedrose.BackstagePasses, SellIn: -1, Quality: 0}, + }, + { + name: "Sulfuras never decreases in quality or SellIn, SellIn positive", + testData: []*domain.Item{{Name: gildedrose.Sulfuras, SellIn: 10, Quality: 80}}, + expected: domain.Item{Name: gildedrose.Sulfuras, SellIn: 10, Quality: 80}, + }, + { + name: "Sulfuras never decreases in quality or SellIn, SellIn negative", + testData: []*domain.Item{{Name: gildedrose.Sulfuras, SellIn: -1, Quality: 80}}, + expected: domain.Item{Name: gildedrose.Sulfuras, SellIn: -1, Quality: 80}, + }, + { + name: "Create Sulfuras item with quality different than 80", + testData: []*domain.Item{{Name: gildedrose.Sulfuras, SellIn: 10, Quality: 1000}}, + expected: domain.Item{Name: gildedrose.Sulfuras, SellIn: 10, Quality: 80}, + }, + { + name: "Conjured items degrade in quality twice as fast - before sell-by date - initial quality 6", + testData: []*domain.Item{{Name: gildedrose.Conjured, SellIn: 3, Quality: 6}}, + expected: domain.Item{Name: gildedrose.Conjured, SellIn: 2, Quality: 4}, + }, + { + name: "Conjured items degrade in quality twice as fast - before sell-by date - initial quality 1", + testData: []*domain.Item{{Name: gildedrose.Conjured, SellIn: 3, Quality: 1}}, + expected: domain.Item{Name: gildedrose.Conjured, SellIn: 2, Quality: 0}, + }, + { + name: "Conjured items degrade in quality twice as fast - before sell-by date - initial quality 0", + testData: []*domain.Item{{Name: gildedrose.Conjured, SellIn: -3, Quality: 0}}, + expected: domain.Item{Name: gildedrose.Conjured, SellIn: -4, Quality: 0}, + }, + { + name: "Conjured items degrade in quality twice as fast - after sell-by date", + testData: []*domain.Item{{Name: gildedrose.Conjured, SellIn: 0, Quality: 6}}, + expected: domain.Item{Name: gildedrose.Conjured, SellIn: -1, Quality: 2}, + }, + { + name: "Create item with quality bigger than 50", + testData: []*domain.Item{{Name: gildedrose.Conjured, SellIn: 10, Quality: 100}}, + expected: domain.Item{Name: gildedrose.Conjured, SellIn: 9, Quality: 0}, + }, + { + name: "Create item with quality less than 0", + testData: []*domain.Item{{Name: gildedrose.Conjured, SellIn: 10, Quality: -100}}, + expected: domain.Item{Name: gildedrose.Conjured, SellIn: 9, Quality: 0}, + }, + } { + t.Run(tc.name, func(t *testing.T) { + gildedrose.UpdateQuality(tc.testData) + require.Equal(t, tc.expected, *tc.testData[0]) + }) } } diff --git a/go/go.mod b/go/go.mod index 00f9da4e..2a0cf8ea 100644 --- a/go/go.mod +++ b/go/go.mod @@ -1,3 +1,10 @@ module github.com/emilybache/gildedrose-refactoring-kata go 1.18 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.9.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go/texttest_fixture.go b/go/texttest_fixture.go index 5c965064..196561dd 100644 --- a/go/texttest_fixture.go +++ b/go/texttest_fixture.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "github.com/emilybache/gildedrose-refactoring-kata/gildedrose/domain" "os" "strconv" @@ -11,7 +12,7 @@ import ( func main() { fmt.Println("OMGHAI!") - var items = []*gildedrose.Item{ + var items = []*domain.Item{ {"+5 Dexterity Vest", 10, 20}, {"Aged Brie", 2, 0}, {"Elixir of the Mongoose", 5, 7},