diff --git a/Java/src/main/java/com/gildedrose/AgedBrieItem.java b/Java/src/main/java/com/gildedrose/AgedBrieItem.java new file mode 100644 index 00000000..46b3131b --- /dev/null +++ b/Java/src/main/java/com/gildedrose/AgedBrieItem.java @@ -0,0 +1,13 @@ +package com.gildedrose; + +class AgedBrieItem extends UpdatableItem { + public AgedBrieItem(Item item) { + super(item); + } + + @Override + public void update() { + incrementQuality(STANDARD_VALUE_CHANGE); + decrementSellIn(); + } +} diff --git a/Java/src/main/java/com/gildedrose/BackstagePassItem.java b/Java/src/main/java/com/gildedrose/BackstagePassItem.java new file mode 100644 index 00000000..c1fa1036 --- /dev/null +++ b/Java/src/main/java/com/gildedrose/BackstagePassItem.java @@ -0,0 +1,32 @@ +package com.gildedrose; + +class BackstagePassItem extends UpdatableItem { + private static final int FIRST_SELL_IN_THRESHOLD = 10; + private static final int SECOND_SELL_IN_THRESHOLD = 5; + + public BackstagePassItem(Item item) { + super(item); + } + + @Override + public void update() { + decrementSellIn(); + updateQuality(); + } + + private void updateQuality() { + if (isOutdated()) { + setZeroQuality(); + } else { + incrementQuality(getIncrementValue()); + } + } + + private int getIncrementValue() { + int increment = STANDARD_VALUE_CHANGE; + if (item.sellIn <= FIRST_SELL_IN_THRESHOLD) increment++; + if (item.sellIn <= SECOND_SELL_IN_THRESHOLD) increment++; + return increment; + } +} + diff --git a/Java/src/main/java/com/gildedrose/ConjuredItem.java b/Java/src/main/java/com/gildedrose/ConjuredItem.java new file mode 100644 index 00000000..092ba451 --- /dev/null +++ b/Java/src/main/java/com/gildedrose/ConjuredItem.java @@ -0,0 +1,14 @@ +package com.gildedrose; + +class ConjuredItem extends UpdatableItem { + + public ConjuredItem(Item item) { + super(item); + } + + @Override + public void update() { + decrementQuality(DOUBLE_VALUE_CHANGE); + decrementSellIn(); + } +} diff --git a/Java/src/main/java/com/gildedrose/GildedRose.java b/Java/src/main/java/com/gildedrose/GildedRose.java index 87a3b926..5e358465 100644 --- a/Java/src/main/java/com/gildedrose/GildedRose.java +++ b/Java/src/main/java/com/gildedrose/GildedRose.java @@ -1,6 +1,13 @@ package com.gildedrose; +import java.util.Arrays; + class GildedRose { + private static final String BACKSTAGE_PASS_NAME = "Backstage passes to a TAFKAL80ETC concert"; + private static final String SULFURAS_NAME = "Sulfuras, Hand of Ragnaros"; + private static final String AGED_BRIE_NAME = "Aged Brie"; + private static final String CONJURED_NAME = "Conjured"; + Item[] items; public GildedRose(Item[] items) { @@ -8,55 +15,18 @@ class GildedRose { } 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; + Arrays.stream(items) + .map(this::mapToUpdatableItem) + .forEach(UpdatableItem::update); + } - 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; - } - } - } - } + private UpdatableItem mapToUpdatableItem(Item item) { + return switch (item.name) { + case AGED_BRIE_NAME -> new AgedBrieItem(item); + case BACKSTAGE_PASS_NAME -> new BackstagePassItem(item); + case SULFURAS_NAME -> new SulfurasItem(item); + case CONJURED_NAME -> new ConjuredItem(item); + default -> new RegularItem(item); + }; } } diff --git a/Java/src/main/java/com/gildedrose/RegularItem.java b/Java/src/main/java/com/gildedrose/RegularItem.java new file mode 100644 index 00000000..4732c9f1 --- /dev/null +++ b/Java/src/main/java/com/gildedrose/RegularItem.java @@ -0,0 +1,19 @@ +package com.gildedrose; + +class RegularItem extends UpdatableItem { + public RegularItem(Item item) { + super(item); + } + + @Override + public void update() { + decrementSellIn(); + updateQuality(); + } + + private void updateQuality() { + int decrementAmount = isOutdated() ? DOUBLE_VALUE_CHANGE : STANDARD_VALUE_CHANGE; + decrementQuality(decrementAmount); + } +} + diff --git a/Java/src/main/java/com/gildedrose/SulfurasItem.java b/Java/src/main/java/com/gildedrose/SulfurasItem.java new file mode 100644 index 00000000..d9ea53b2 --- /dev/null +++ b/Java/src/main/java/com/gildedrose/SulfurasItem.java @@ -0,0 +1,14 @@ +package com.gildedrose; + +class SulfurasItem extends UpdatableItem { + public static final int SULFURAS_CONSTANT_QUALITY = 80; + + public SulfurasItem(Item item) { + super(item); + item.quality = SULFURAS_CONSTANT_QUALITY; + } + + @Override + public void update() {} +} + diff --git a/Java/src/main/java/com/gildedrose/UpdatableItem.java b/Java/src/main/java/com/gildedrose/UpdatableItem.java new file mode 100644 index 00000000..f1b97302 --- /dev/null +++ b/Java/src/main/java/com/gildedrose/UpdatableItem.java @@ -0,0 +1,41 @@ +package com.gildedrose; + +import static java.lang.Math.max; +import static java.lang.Math.min; + +abstract class UpdatableItem { + protected static final int DOUBLE_VALUE_CHANGE = 2; + protected static final int STANDARD_VALUE_CHANGE = 1; + protected static final int QUALITY_MAX = 50; + protected static final int QUALITY_MIN = 0; + protected static final int ZERO_SELL_IN = 0; + + protected Item item; + + protected UpdatableItem(Item item) { + this.item = item; + } + + public abstract void update(); + + protected void incrementQuality(int incrementAmount) { + item.quality = min(QUALITY_MAX, item.quality + incrementAmount); + } + + protected void setZeroQuality() { + item.quality = QUALITY_MIN; + } + + protected void decrementQuality(int decrementAmount) { + item.quality = max(QUALITY_MIN, item.quality - decrementAmount); + } + + protected void decrementSellIn() { + item.sellIn--; + } + + protected boolean isOutdated() { + return item.sellIn < ZERO_SELL_IN; + } +} + diff --git a/Java/src/test/java/com/gildedrose/GildedRoseTest.java b/Java/src/test/java/com/gildedrose/GildedRoseTest.java index 8ae29eec..8803a2c4 100644 --- a/Java/src/test/java/com/gildedrose/GildedRoseTest.java +++ b/Java/src/test/java/com/gildedrose/GildedRoseTest.java @@ -7,11 +7,123 @@ import static org.junit.jupiter.api.Assertions.assertEquals; class GildedRoseTest { @Test - void foo() { - Item[] items = new Item[] { new Item("foo", 0, 0) }; + void shouldDefaultDecreaseQualityBeforeSellIn() { + Item[] items = new Item[]{ + new Item("testProductName", 9, 30) + }; GildedRose app = new GildedRose(items); app.updateQuality(); - assertEquals("fixme", app.items[0].name); + assertEquals("testProductName", app.items[0].name); + assertEquals(29, app.items[0].quality); + } + + @Test + void shouldDoubleDecreaseQualityAfterSellIn() { + Item[] items = new Item[]{ + new Item("testProductName", -2, 30) + }; + GildedRose app = new GildedRose(items); + app.updateQuality(); + assertEquals("testProductName", app.items[0].name); + assertEquals(28, app.items[0].quality); + } + + @Test + void shouldNotDecreaseQualityBelowZero() { + Item[] items = new Item[]{ + new Item("testProductName", 9, 0) + }; + GildedRose app = new GildedRose(items); + app.updateQuality(); + assertEquals("testProductName", app.items[0].name); + assertEquals(0, app.items[0].quality); + } + + @Test + void shouldIncreaseQualityOfAgedBrie() { + Item[] items = new Item[]{ + new Item("Aged Brie", 9, 30) + }; + GildedRose app = new GildedRose(items); + app.updateQuality(); + assertEquals("Aged Brie", app.items[0].name); + assertEquals(31, app.items[0].quality); + } + + @Test + void shouldNotIncreaseQualityAboveFifty() { + Item[] items = new Item[]{ + new Item("Aged Brie", 9, 50) + }; + GildedRose app = new GildedRose(items); + app.updateQuality(); + assertEquals("Aged Brie", app.items[0].name); + assertEquals(50, app.items[0].quality); + } + + @Test + void shouldNotChangeSulfurasQuality() { + Item[] items = new Item[]{ + new Item("Sulfuras, Hand of Ragnaros", 9, 80) + }; + GildedRose app = new GildedRose(items); + app.updateQuality(); + assertEquals("Sulfuras, Hand of Ragnaros", app.items[0].name); + assertEquals(80, app.items[0].quality); + } + + @Test + void shouldIncreaseQualityBy2Below10DaysForSpecialProducts() { + Item[] items = new Item[]{ + new Item("Backstage passes to a TAFKAL80ETC concert", 9, 32) + }; + GildedRose app = new GildedRose(items); + app.updateQuality(); + assertEquals("Backstage passes to a TAFKAL80ETC concert", app.items[0].name); + assertEquals(34, app.items[0].quality); + } + + @Test + void shouldIncreaseQualityBy3AfterBelow5DaysForSpecialProducts() { + Item[] items = new Item[]{ + new Item("Backstage passes to a TAFKAL80ETC concert", 4, 32) + }; + GildedRose app = new GildedRose(items); + app.updateQuality(); + assertEquals("Backstage passes to a TAFKAL80ETC concert", app.items[0].name); + assertEquals(35, app.items[0].quality); + } + + @Test + void shouldSetZeroQualityForSpecialProductsAfterSellIn() { + Item[] items = new Item[]{ + new Item("Backstage passes to a TAFKAL80ETC concert", -2, 32) + }; + GildedRose app = new GildedRose(items); + app.updateQuality(); + assertEquals("Backstage passes to a TAFKAL80ETC concert", app.items[0].name); + assertEquals(0, app.items[0].quality); + } + + @Test + void shouldDoubleDecreaseQualityForConjuredItems() { + Item[] items = new Item[]{ + new Item("Conjured", 9, 30) + }; + GildedRose app = new GildedRose(items); + app.updateQuality(); + assertEquals("Conjured", app.items[0].name); + assertEquals(28, app.items[0].quality); + } + + @Test + void shouldNotExceedQualityLimitForBackstageItem() { + Item[] items = new Item[]{ + new Item("Backstage passes to a TAFKAL80ETC concert", 4, 49) + }; + GildedRose app = new GildedRose(items); + app.updateQuality(); + assertEquals(50, app.items[0].quality); } } diff --git a/start_texttest.sh b/start_texttest.sh index 805922b1..e1b9cdd1 100755 --- a/start_texttest.sh +++ b/start_texttest.sh @@ -3,5 +3,5 @@ if [ ! -d "venv" ]; then python -m venv venv fi -venv/bin/pip install texttest -venv/bin/texttest -d . -con "$@" +venv/Scripts/pip.exe install texttest +venv/Scripts/texttest.exe -d . -con "$@" diff --git a/texttests/config.gr b/texttests/config.gr index 9c707ffc..d0137087 100755 --- a/texttests/config.gr +++ b/texttests/config.gr @@ -18,8 +18,8 @@ diff_program:meld #executable:${TEXTTEST_HOME}/zig/zig-out/bin/zig # Settings for the Java version using Gradle wrapped in a python script -#executable:${TEXTTEST_HOME}/Java/texttest_rig.py -#interpreter:python +executable:${TEXTTEST_HOME}/Java/texttest_rig.py +interpreter:python # Settings for the Java version using the classpath #executable:com.gildedrose.TexttestFixture