diff --git a/Java/build.gradle b/Java/build.gradle index 616cec6a..ce07023b 100644 --- a/Java/build.gradle +++ b/Java/build.gradle @@ -10,6 +10,12 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2' testImplementation 'org.junit.jupiter:junit-jupiter-params:5.6.2' testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.6.2' + + compileOnly 'org.projectlombok:lombok:1.18.30' + annotationProcessor 'org.projectlombok:lombok:1.18.30' + + testCompileOnly 'org.projectlombok:lombok:1.18.30' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.30' } group = 'com.gildedrose' diff --git a/Java/pom.xml b/Java/pom.xml index 3bd6aff8..995dbb5f 100644 --- a/Java/pom.xml +++ b/Java/pom.xml @@ -24,6 +24,12 @@ ${junit.jupiter.version} test + + org.projectlombok + lombok + RELEASE + compile + diff --git a/Java/src/main/java/com/gildedrose/GildedRose.java b/Java/src/main/java/com/gildedrose/GildedRose.java index 87a3b926..0afb8d29 100644 --- a/Java/src/main/java/com/gildedrose/GildedRose.java +++ b/Java/src/main/java/com/gildedrose/GildedRose.java @@ -1,62 +1,43 @@ package com.gildedrose; +import static com.gildedrose.Inventory.BACKSTAGE_PASS; +import static com.gildedrose.Inventory.LEGENDARY; +import static com.gildedrose.service.InventoryHelper.*; +import static java.util.stream.IntStream.range; +import static java.util.stream.Stream.of; + class GildedRose { Item[] items; - public GildedRose(Item[] items) { + GildedRose(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; + void updateQuality() { + of(items).forEach(item -> { + // legendary items should not be sold + if (itemNotLegendary(item)) item.sellIn--; - 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; - } - } + // increase quality when quality decrease is inverted + if (includesItems(item, getInventoriesWithInvertedQualityDecrease())) { + increaseQualityBelowMaximum(item); - if (items[i].sellIn < 6) { - if (items[i].quality < 50) { - items[i].quality = items[i].quality + 1; - } - } - } - } + // increase backstage passes + increaseBackstagePass(item); + } + // decrease average (non-legendary) items + else if (itemNotLegendary(item)) { + // decrease quality based on their decrease amount + range(0, getQualityDecreaseAmount(item)).forEach(i -> decreaseQualityAboveZero(item)); } - if (!items[i].name.equals("Sulfuras, Hand of Ragnaros")) { - items[i].sellIn = items[i].sellIn - 1; - } + if (item.sellIn < 0) { + // increase quality when aged brie + if (itemAgedBrie(item)) increaseQualityBelowMaximum(item); - 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; - } - } + // when not aged brie, backstage pass or legendary, decrease quality above zero + else decreaseQualityAboveZeroItemsOtherThan(item, BACKSTAGE_PASS, LEGENDARY); } - } + }); } } diff --git a/Java/src/main/java/com/gildedrose/Inventory.java b/Java/src/main/java/com/gildedrose/Inventory.java new file mode 100644 index 00000000..89c89b57 --- /dev/null +++ b/Java/src/main/java/com/gildedrose/Inventory.java @@ -0,0 +1,17 @@ +package com.gildedrose; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum Inventory { + AGED_BRIE("Aged Brie", true, 1), + LEGENDARY("Sulfuras, Hand of Ragnaros", false, 0), + CONJURED("Conjured Mana Cake", false, 2), + BACKSTAGE_PASS("Backstage passes to a TAFKAL80ETC concert", true, 1); + + private String name; + private boolean qualityDecreaseInverted; + private int qualityDecrease; +} diff --git a/Java/src/main/java/com/gildedrose/service/InventoryHelper.java b/Java/src/main/java/com/gildedrose/service/InventoryHelper.java new file mode 100644 index 00000000..1fe310ae --- /dev/null +++ b/Java/src/main/java/com/gildedrose/service/InventoryHelper.java @@ -0,0 +1,64 @@ +package com.gildedrose.service; + +import com.gildedrose.Inventory; +import com.gildedrose.Item; + +import static com.gildedrose.Inventory.*; +import static java.util.stream.Stream.of; + +public class InventoryHelper { + private static final int MAX_QUALITY = 50; + + public static Inventory[] getInventoriesWithInvertedQualityDecrease() { + return of(Inventory.values()) + .filter(Inventory::isQualityDecreaseInverted) + .distinct() + .toArray(Inventory[]::new); + } + + public static void decreaseQualityAboveZeroItemsOtherThan(Item item, Inventory... inventories) { + if (!includesItems(item, inventories)) { + decreaseQualityAboveZero(item); + } else if (itemNotLegendary(item)) item.quality = 0; + } + + public static boolean includesItems(Item item, Inventory... inventories) { + return of(inventories).anyMatch(inventory -> item.name.equals(inventory.getName())); + } + + public static boolean itemNotLegendary(Item item) { + return !item.name.equals(LEGENDARY.getName()); + } + + public static boolean itemAgedBrie(Item item) { + return item.name.equals(AGED_BRIE.getName()); + } + + public static int getQualityDecreaseAmount(Item item) { + return of(Inventory.values()) + .filter(inventory -> inventory.getName().equals(item.name)) + .findFirst() + .map(Inventory::getQualityDecrease) + .orElse(1); + } + + public static void decreaseQualityAboveZero(Item item) { + item.quality = item.quality > 0 ? item.quality - 1 : 0; + } + + public static void increaseQualityBelowMaximum(Item item) { + if (item.quality < MAX_QUALITY) { + item.quality++; + } + } + + public static void increaseBackstagePass(Item item) { + if (item.name.equals(BACKSTAGE_PASS.getName()) && item.sellIn < 10) { + increaseQualityBelowMaximum(item); + + if (item.sellIn < 5) { + increaseQualityBelowMaximum(item); + } + } + } +} diff --git a/Java/src/test/java/com/gildedrose/GildedRoseTest.java b/Java/src/test/java/com/gildedrose/GildedRoseTest.java index 86d89bb9..8102716b 100644 --- a/Java/src/test/java/com/gildedrose/GildedRoseTest.java +++ b/Java/src/test/java/com/gildedrose/GildedRoseTest.java @@ -105,6 +105,14 @@ class GildedRoseTest { assertEquals(quality, app.items[0].quality); } + @Test + void givenConjuredItem_whenUpdateQuality_thenQualityDecreasesDouble() { + int quality = 25; + GildedRose app = updateQuality(createConjuredItem(quality)); + + assertEquals(quality - 2, app.items[0].quality); + } + private GildedRose updateQuality(Item... items) { GildedRose app = new GildedRose(items); app.updateQuality(); @@ -126,4 +134,8 @@ class GildedRoseTest { private Item createLegendaryItem(int quality) { return new Item("Sulfuras, Hand of Ragnaros", 10, quality); } + + private Item createConjuredItem(int quality) { + return new Item("Conjured Mana Cake", 6, quality); + } }