From 7cdd525d14bb298cdafe35284eb44eeeb737c9ca Mon Sep 17 00:00:00 2001 From: Erol Shaban Date: Wed, 21 Aug 2019 16:46:20 +0200 Subject: [PATCH] Test coverage improved to %94 --- .../java/com/gildedrose/AgedBrieUpdater.java | 8 +- .../com/gildedrose/BackstagePassUpdater.java | 16 +- .../java/com/gildedrose/ConjuredUpdater.java | 28 +-- .../java/com/gildedrose/GildedRoseOld.java | 62 ----- .../main/java/com/gildedrose/ItemUpdater.java | 16 +- .../com/gildedrose/StandardItemUpdater.java | 13 +- .../java/com/gildedrose/SulfurasUpdater.java | 18 +- .../java/com/gildedrose/GildedRoseTest.java | 217 ++++++++++++------ 8 files changed, 182 insertions(+), 196 deletions(-) delete mode 100644 Java/src/main/java/com/gildedrose/GildedRoseOld.java diff --git a/Java/src/main/java/com/gildedrose/AgedBrieUpdater.java b/Java/src/main/java/com/gildedrose/AgedBrieUpdater.java index f923d724..4b145e7e 100644 --- a/Java/src/main/java/com/gildedrose/AgedBrieUpdater.java +++ b/Java/src/main/java/com/gildedrose/AgedBrieUpdater.java @@ -1,12 +1,6 @@ package com.gildedrose; public class AgedBrieUpdater extends ItemUpdater { - @Override - void updateQuality(Item item) { - if (canUpdateQuality(item)) { - item.quality += getDegradeValue(item); - } - } @Override void updateSellIn(Item item) { @@ -19,7 +13,7 @@ public class AgedBrieUpdater extends ItemUpdater { } @Override - int getDegradeValue(Item item) { + int getUpdateValue(Item item) { return INCREASE_NORMAL; } } diff --git a/Java/src/main/java/com/gildedrose/BackstagePassUpdater.java b/Java/src/main/java/com/gildedrose/BackstagePassUpdater.java index 7843970f..6cb499e4 100644 --- a/Java/src/main/java/com/gildedrose/BackstagePassUpdater.java +++ b/Java/src/main/java/com/gildedrose/BackstagePassUpdater.java @@ -1,14 +1,6 @@ package com.gildedrose; public class BackstagePassUpdater extends ItemUpdater { - @Override - void updateQuality(Item item) { - if (sellByDateLessThan(item, 0)) { - item.quality = 0; - } else if (canUpdateQuality(item)) { - item.quality += getDegradeValue(item); - } - } @Override void updateSellIn(Item item) { @@ -17,12 +9,14 @@ public class BackstagePassUpdater extends ItemUpdater { @Override boolean canUpdateQuality(final Item item) { - return item.quality < HIGHEST_QUALITY; + return item.quality < HIGHEST_QUALITY && item.quality > MIN_QUALITY; } @Override - int getDegradeValue(final Item item) { - if (sellByDateLessThan(item, 6)) { + int getUpdateValue(final Item item) { + if (sellByDateLessThan(item, 0)) { + return -item.quality; + } else if (sellByDateLessThan(item, 6)) { return INCREASE_THRICE_AS_FAST; } else if (sellByDateLessThan(item, 11) ) { return INCREASE_TWICE_AS_FAST; diff --git a/Java/src/main/java/com/gildedrose/ConjuredUpdater.java b/Java/src/main/java/com/gildedrose/ConjuredUpdater.java index 2cc66ef3..2ccb6983 100644 --- a/Java/src/main/java/com/gildedrose/ConjuredUpdater.java +++ b/Java/src/main/java/com/gildedrose/ConjuredUpdater.java @@ -1,27 +1,13 @@ package com.gildedrose; -public class ConjuredUpdater extends ItemUpdater { +public class ConjuredUpdater extends StandardItemUpdater { + @Override - void updateQuality(Item item) { - if (canUpdateQuality(item)) { - item.quality += getDegradeValue(item); + int getUpdateValue(final Item item) { + if (item.sellIn < 0) { + return DEGRADE_TWICE_AS_FAST * 2; + } else { + return DEGRADE_TWICE_AS_FAST; } } - - @Override - void updateSellIn(Item item) { - item.sellIn -= 1; - } - - @Override - boolean canUpdateQuality(Item item) { - return item.quality < HIGHEST_QUALITY && item.quality > 0; - } - - @Override - int getDegradeValue(Item item) { - return item.quality + DEGRADE_TWICE_AS_FAST < 0 ? - DEGRADE_NORMAL : - DEGRADE_TWICE_AS_FAST; - } } diff --git a/Java/src/main/java/com/gildedrose/GildedRoseOld.java b/Java/src/main/java/com/gildedrose/GildedRoseOld.java deleted file mode 100644 index d4e98431..00000000 --- a/Java/src/main/java/com/gildedrose/GildedRoseOld.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.gildedrose; - -class GildedRoseOld { - Item[] items; - - public GildedRoseOld(Item[] items) { - this.items = items; - } - - public void updateQuality() { - for (int i = 0; i < items.length; i++) { - if (!items[i].name.equals("Aged Brie") - && !items[i].name.equals("Backstage passes to a TAFKAL80ETC concert")) { - if (items[i].quality > 0) { - if (!items[i].name.equals("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.equals("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.equals("Sulfuras, Hand of Ragnaros")) { - items[i].sellIn = items[i].sellIn - 1; - } - - if (items[i].sellIn < 0) { - if (!items[i].name.equals("Aged Brie")) { - if (!items[i].name.equals("Backstage passes to a TAFKAL80ETC concert")) { - if (items[i].quality > 0) { - if (!items[i].name.equals("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; - } - } - } - } - } -} \ No newline at end of file diff --git a/Java/src/main/java/com/gildedrose/ItemUpdater.java b/Java/src/main/java/com/gildedrose/ItemUpdater.java index a94bda73..78aad85e 100644 --- a/Java/src/main/java/com/gildedrose/ItemUpdater.java +++ b/Java/src/main/java/com/gildedrose/ItemUpdater.java @@ -2,22 +2,28 @@ package com.gildedrose; public abstract class ItemUpdater { static int HIGHEST_QUALITY = 50; + static int MIN_QUALITY = 0; static int DEGRADE_NORMAL = -1; static int DEGRADE_TWICE_AS_FAST = -2; static int INCREASE_NORMAL = 1; static int INCREASE_TWICE_AS_FAST = 2; static int INCREASE_THRICE_AS_FAST = 3; - public void updateStateFor(Item item){ + void updateStateFor(Item item){ updateSellIn(item); updateQuality(item); } - abstract void updateQuality(Item item); + + private void updateQuality(Item item) { + if (canUpdateQuality(item)) { + item.quality = Math.max(getNewQuality(item), 0); + } + } abstract void updateSellIn(Item item); abstract boolean canUpdateQuality(Item item); - abstract int getDegradeValue(Item item); + abstract int getUpdateValue(Item item); - public int getHighestQuality() { - return HIGHEST_QUALITY; + private int getNewQuality(Item item){ + return Math.min(item.quality + getUpdateValue(item), HIGHEST_QUALITY); } } diff --git a/Java/src/main/java/com/gildedrose/StandardItemUpdater.java b/Java/src/main/java/com/gildedrose/StandardItemUpdater.java index 54d765fd..f59f332c 100644 --- a/Java/src/main/java/com/gildedrose/StandardItemUpdater.java +++ b/Java/src/main/java/com/gildedrose/StandardItemUpdater.java @@ -2,13 +2,6 @@ package com.gildedrose; public class StandardItemUpdater extends ItemUpdater { - @Override - void updateQuality(Item item) { - if (canUpdateQuality(item)) { - item.quality += getDegradeValue(item); - } - } - @Override void updateSellIn(Item item) { item.sellIn -= 1; @@ -16,13 +9,13 @@ public class StandardItemUpdater extends ItemUpdater { @Override boolean canUpdateQuality(Item item) { - return item.quality < HIGHEST_QUALITY && item.quality > 0; + return item.quality <= HIGHEST_QUALITY && item.quality > MIN_QUALITY; } @Override - int getDegradeValue(Item item) { + int getUpdateValue(Item item) { if (item.sellIn < 0) { - return item.quality + DEGRADE_TWICE_AS_FAST < 0 ? DEGRADE_NORMAL : DEGRADE_TWICE_AS_FAST; + return DEGRADE_NORMAL * 2; } else { return DEGRADE_NORMAL; } diff --git a/Java/src/main/java/com/gildedrose/SulfurasUpdater.java b/Java/src/main/java/com/gildedrose/SulfurasUpdater.java index 31f7b073..5c78755f 100644 --- a/Java/src/main/java/com/gildedrose/SulfurasUpdater.java +++ b/Java/src/main/java/com/gildedrose/SulfurasUpdater.java @@ -1,17 +1,9 @@ package com.gildedrose; public class SulfurasUpdater extends ItemUpdater { - - @Override - void updateQuality(Item item) { - System.out.println("########Sulfuras is a legendary product"); - // TODO - item.quality = 80; - } - @Override void updateSellIn(Item item) { - System.out.println("########Never gets old"); + System.out.print("########Never gets old ############"); } @Override @@ -21,12 +13,8 @@ public class SulfurasUpdater extends ItemUpdater { } @Override - int getDegradeValue(Item item) { - // "Sulfuras", being a legendary item, never has to be sold + int getUpdateValue(Item item) { + // "Sulfuras", being a legendary item, never decreases in Quality return 0; } - - public int getHighestQuality() { - return 80; - } } diff --git a/Java/src/test/java/com/gildedrose/GildedRoseTest.java b/Java/src/test/java/com/gildedrose/GildedRoseTest.java index d28d1166..f19bfd3b 100644 --- a/Java/src/test/java/com/gildedrose/GildedRoseTest.java +++ b/Java/src/test/java/com/gildedrose/GildedRoseTest.java @@ -1,7 +1,5 @@ package com.gildedrose; -import static org.junit.Assert.*; - import org.junit.Test; import java.util.Arrays; @@ -9,68 +7,138 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; +import static com.gildedrose.ItemUpdater.HIGHEST_QUALITY; +import static com.gildedrose.ItemUpdater.MIN_QUALITY; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + public class GildedRoseTest { - /* - First an introduction to our system: - - - All items have a SellIn value which denotes the number of days we have to sell the item - - All items have a Quality value which denotes how valuable the item is - - At the end of each day our system lowers both values for every item - -Pretty simple, right? Well this is where it gets interesting: - - - Once the sell by date has passed, Quality degrades twice as fast - - The Quality of an item is never negative - - "Aged Brie" actually increases in Quality the older it gets - - The Quality of an item is never more than 50 - - "Sulfuras", being a legendary item, never has to be sold or decreases in Quality - - "Backstage passes", like aged brie, increases in Quality as its SellIn value approaches; - Quality increases by 2 when there are 10 days or less and by 3 when there are 5 days or less but - Quality drops to 0 after the concert - - We have recently signed a supplier of conjured items. This requires an update to our system: - - - "Conjured" items degrade in Quality twice as fast as normal items - - Feel free to make any changes to the UpdateQuality method and add any new code as long as everything - still works correctly. However, do not alter the Item class or Items property as those belong to the - goblin in the corner who will insta-rage and one-shot you as he doesn't believe in shared code - ownership (you can make the UpdateQuality method and Items property static if you like, we'll cover - for you). - - Just for clarification, an item can never have its Quality increase above 50, however "Sulfuras" is a - legendary item and as such its Quality is 80 and it never alters. - - */ private final Item sulfuras = new Item("Sulfuras, Hand of Ragnaros", 0, 80); - private final Item standardWithHighestQuality = new Item("Standard", 5, 50); - private final Item agedBrieWithHighestQuality = new Item("Aged Brie", 5, 50); - private final Item conjuredWithHighestQuality = new Item("Conjured Mana Cake", 5, 50); - private final Item backstageWithHighestQuality = new Item("Backstage passes to a TAFKAL80ETC concert", 5, 50); + private final Item standardWithHighestQuality = new Item("Standard", 5, HIGHEST_QUALITY); + private final Item agedBrieWithHighestQuality = new Item("Aged Brie", 5, HIGHEST_QUALITY); + private final Item conjuredWithHighestQuality = new Item("Conjured Mana Cake", 5, HIGHEST_QUALITY); + private final Item backstageWithHighestQuality = new Item("Backstage passes to a TAFKAL80ETC concert", 5, HIGHEST_QUALITY); - private final Item standardWithLowQuality = new Item("Standard", 0, 1); - private final Item agedBrieWithLowQuality = new Item("Aged Brie", 0, 1); - private final Item conjuredWithLowQuality = new Item("Conjured Mana Cake", 0, 1); - private final Item backstageWithLowQuality = new Item("Backstage passes to a TAFKAL80ETC concert", 0, 1); + private final Item standardWithLowQuality = new Item("Standard", 0, MIN_QUALITY + 1); + private final Item agedBrieWithLowQuality = new Item("Aged Brie", 0, MIN_QUALITY + 1); + private final Item conjuredWithLowQuality = new Item("Conjured Mana Cake", 0, MIN_QUALITY + 1); + private final Item backstageWithLowQuality = new Item("Backstage passes to a TAFKAL80ETC concert", 0, MIN_QUALITY + 1); + + private GildedRose app; + + @Test + public void backstageItem_shouldIncreaseThriceAsFast_whenLessThan5DaysLeftToSellByDate() { + final int originalQuality = 20; + final Item[] items = new Item[]{new Item("Backstage passes to a TAFKAL80ETC concert", 5, originalQuality)}; + app = new GildedRose(items); + app.updateQuality(); + + assertEquals(4, app.items[0].sellIn); + assertEquals(originalQuality + 3, app.items[0].quality); + } + + @Test + public void backstageItem_shouldIncreaseTwiceAsFast_whenLessThan10DaysLeftToSellByDate() { + final int originalQuality = 20; + final Item[] items = new Item[]{new Item("Backstage passes to a TAFKAL80ETC concert", 10, originalQuality)}; + app = new GildedRose(items); + app.updateQuality(); + + assertEquals(9, app.items[0].sellIn); + assertEquals(originalQuality + 2, app.items[0].quality); + } + + @Test + public void backstageItem_shouldIncreaseNormal_whenMoreThan10DaysLeftToSellByDate() { + final int originalQuality = 20; + final Item[] items = new Item[]{new Item("Backstage passes to a TAFKAL80ETC concert", 15, originalQuality)}; + app = new GildedRose(items); + app.updateQuality(); + + assertEquals(14, app.items[0].sellIn); + assertEquals(originalQuality + 1, app.items[0].quality); + } + + @Test + public void backstageItemQuality_shouldBeZero_whenSellByDatePassed() { + final int originalQuality = 20; + final Item[] items = new Item[]{new Item("Backstage passes to a TAFKAL80ETC concert", 0, originalQuality)}; + app = new GildedRose(items); + app.updateQuality(); + + assertEquals(-1, app.items[0].sellIn); + assertEquals(MIN_QUALITY, app.items[0].quality); + } + + @Test + public void backstageItemQuality_shouldStayZero_afterTheConcert() { + final int originalQuality = 20; + final Item[] items = new Item[]{new Item("Backstage passes to a TAFKAL80ETC concert", 0, originalQuality)}; + app = new GildedRose(items); + app.updateQuality(); + + assertEquals(-1, app.items[0].sellIn); + assertEquals(MIN_QUALITY, app.items[0].quality); + + app.updateQuality(); + + assertEquals(-2, app.items[0].sellIn); + assertEquals(MIN_QUALITY, app.items[0].quality); + } @Test public void standardItem_shouldDegradeNormal_whenSellByDateNotPassed() { final int originalQuality = 40; - final Item[] items = new Item[] { new Item("Standard", 4, originalQuality) }; - final GildedRose app = new GildedRose(items); + final Item[] items = new Item[]{new Item("Standard", 4, originalQuality)}; + app = new GildedRose(items); app.updateQuality(); assertEquals("Standard", app.items[0].name); assertEquals(3, app.items[0].sellIn); assertEquals(originalQuality - 1, app.items[0].quality); } + @Test + public void agedBrie_shouldIncreaseNormal() { + final int originalQuality = agedBrieWithLowQuality.quality; + final int originalSellIn = agedBrieWithLowQuality.sellIn; + final Item[] items = new Item[]{agedBrieWithLowQuality}; + app = new GildedRose(items); + app.updateQuality(); + assertEquals(agedBrieWithLowQuality.name, app.items[0].name); + assertEquals(originalSellIn - 1, app.items[0].sellIn); + assertEquals(originalQuality + 1, app.items[0].quality); + } + + @Test + public void agedBrie_shouldIncreaseNormal_whenOriginalQualityIsZero() { + final int originalQuality = 0; + final int originalSellIn = 2; + final Item[] items = new Item[]{new Item("Aged Brie", originalSellIn, originalQuality)}; + app = new GildedRose(items); + app.updateQuality(); + assertEquals("Aged Brie", app.items[0].name); + assertEquals(originalSellIn - 1, app.items[0].sellIn); + assertEquals(originalQuality + 1, app.items[0].quality); + } + @Test + public void agedBrie_shouldNotIncrease_moreThanHighestValue() { + final int originalQuality = agedBrieWithHighestQuality.quality; + final int originalSellIn = agedBrieWithHighestQuality.sellIn; + final Item[] items = new Item[]{agedBrieWithHighestQuality}; + app = new GildedRose(items); + app.updateQuality(); + assertEquals(agedBrieWithHighestQuality.name, app.items[0].name); + assertEquals(originalSellIn - 1, app.items[0].sellIn); + assertEquals(originalQuality, app.items[0].quality); + } + @Test public void standardItem_shouldDegradeTwiceAsFast_whenSellByDatePassed() { final int originalQuality = 40; - final Item[] items = new Item[] { new Item("Standard", 0, originalQuality) }; - final GildedRose app = new GildedRose(items); + final Item[] items = new Item[]{new Item("Standard", 0, originalQuality)}; + app = new GildedRose(items); app.updateQuality(); assertEquals("Standard", app.items[0].name); assertEquals(-1, app.items[0].sellIn); @@ -84,51 +152,70 @@ Pretty simple, right? Well this is where it gets interesting: @Test public void sulfurus_shouldNeverDegradeAndBeSold() { - final Item[] items = new Item[] { sulfuras}; - final GildedRose app = new GildedRose(items); + final Item[] items = new Item[]{sulfuras}; + app = new GildedRose(items); app.updateQuality(); assertEquals("Sulfuras, Hand of Ragnaros", app.items[0].name); assertEquals(0, app.items[0].sellIn); assertEquals(80, app.items[0].quality); + + app.updateQuality(); + assertEquals(0, app.items[0].sellIn); + assertEquals(80, app.items[0].quality); } @Test - public void qualityOfItem_exceptLegendaryItems_cantBeMoreThan_50() { - final Item[] items = new Item[] {standardWithHighestQuality, backstageWithHighestQuality, + public void qualityOfItem_exceptLegendaryItems_cantBeMoreThanHighestValue() { + final Item[] items = new Item[]{standardWithHighestQuality, backstageWithHighestQuality, agedBrieWithHighestQuality, conjuredWithHighestQuality}; - final GildedRose app = new GildedRose(items); + app = new GildedRose(items); app.updateQuality(); - final Optional qualityHigherThan80 = Arrays.stream(app.items).filter(item -> item.quality > 50).findAny(); + final Optional qualityHigherThan80 = Arrays.stream(app.items).filter(item -> item.quality > HIGHEST_QUALITY).findAny(); assertFalse(qualityHigherThan80.isPresent()); } @Test - public void qualityOfItem_onlyLegendaryItems_cantBeMoreThan_50() { - final Item[] items = new Item[] { sulfuras, standardWithHighestQuality, backstageWithHighestQuality, + public void qualityOfItem_onlyLegendaryItems_cantBeMoreThanHighestValue() { + final Item[] items = new Item[]{sulfuras, standardWithHighestQuality, backstageWithHighestQuality, agedBrieWithHighestQuality, conjuredWithHighestQuality}; - final GildedRose app = new GildedRose(items); + app = new GildedRose(items); app.updateQuality(); - final List qualityHigherThan80List = Arrays.stream(app.items).filter(item -> item.quality > 50).collect(Collectors.toList()); + final List qualityHigherThan50List = Arrays.stream(app.items).filter(item -> item.quality > HIGHEST_QUALITY).collect(Collectors.toList()); - assertEquals(1, qualityHigherThan80List.size()); - assertEquals(sulfuras.name, qualityHigherThan80List.get(0).name); + assertEquals(1, qualityHigherThan50List.size()); + assertEquals(sulfuras.name, qualityHigherThan50List.get(0).name); } @Test - public void qualityOfItem_canNeverBeNegative() { - final Item[] items = new Item[] {sulfuras, standardWithLowQuality, backstageWithLowQuality, + public void qualityOfItem_canNeverBeNegative_afterMultipleUpdates() { + final Item[] items = new Item[]{sulfuras, standardWithLowQuality, backstageWithLowQuality, agedBrieWithLowQuality, conjuredWithLowQuality}; - final GildedRose app = new GildedRose(items); - app.updateQuality(); - final Optional qualityNegative = Arrays.stream(app.items).filter(item -> item.quality < 0 ).findAny(); + app = new GildedRose(items); + app.updateQuality(); + final Optional qualityNegative = Arrays.stream(app.items).filter(item -> item.quality < MIN_QUALITY).findAny(); assertFalse(qualityNegative.isPresent()); app.updateQuality(); - final Optional qualityNegativeAfter2ndUpdate = Arrays.stream(app.items).filter(item -> item.quality < 0 ).findAny(); - + final Optional qualityNegativeAfter2ndUpdate = Arrays.stream(app.items).filter(item -> item.quality < MIN_QUALITY).findAny(); assertFalse(qualityNegativeAfter2ndUpdate.isPresent()); + + final long minimumQualityItemsCount = Arrays.stream(app.items).filter(item -> item.quality == MIN_QUALITY).count(); + // AgedBrie should increase in value, others' quality (3 of them) should be 0 + assertEquals(3, minimumQualityItemsCount); } + @Test + public void conjuredItems_shouldDegradeAsTwiceAsFast_thenTheStandardItems() { + final Item[] items = new Item[]{conjuredWithHighestQuality}; + app = new GildedRose(items); + + for (int i=0; i< 7; i++) { + app.updateQuality(); + } + + assertEquals(-2, app.items[0].sellIn); + assertEquals(32, app.items[0].quality); + } }