mirror of
https://github.com/emilybache/GildedRose-Refactoring-Kata.git
synced 2026-02-04 09:11:39 +00:00
Refactoring GildedRose app code. Rebuild main logic with factory pattern. Add items specific classes. Extract constants. Optimize logic. Add unit tests. Adapt kata configs to work with windows env and java 21.
This commit is contained in:
parent
d3057d9fb1
commit
0825883bee
13
Java/src/main/java/com/gildedrose/AgedBrieItem.java
Normal file
13
Java/src/main/java/com/gildedrose/AgedBrieItem.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
||||
32
Java/src/main/java/com/gildedrose/BackstagePassItem.java
Normal file
32
Java/src/main/java/com/gildedrose/BackstagePassItem.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
14
Java/src/main/java/com/gildedrose/ConjuredItem.java
Normal file
14
Java/src/main/java/com/gildedrose/ConjuredItem.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
19
Java/src/main/java/com/gildedrose/RegularItem.java
Normal file
19
Java/src/main/java/com/gildedrose/RegularItem.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
14
Java/src/main/java/com/gildedrose/SulfurasItem.java
Normal file
14
Java/src/main/java/com/gildedrose/SulfurasItem.java
Normal file
@ -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() {}
|
||||
}
|
||||
|
||||
41
Java/src/main/java/com/gildedrose/UpdatableItem.java
Normal file
41
Java/src/main/java/com/gildedrose/UpdatableItem.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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 "$@"
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user