mirror of
https://github.com/emilybache/GildedRose-Refactoring-Kata.git
synced 2026-02-16 06:51:27 +00:00
commit
f0d37a48e2
@ -1,6 +1,4 @@
|
||||
======================================
|
||||
Gilded Rose Requirements Specification
|
||||
======================================
|
||||
# Gilded Rose Requirements Specification
|
||||
|
||||
Hi and welcome to team Gilded Rose. As you know, we are a small inn with a prime location in a
|
||||
prominent city ran by a friendly innkeeper named Allison. We also buy and sell only the finest goods.
|
||||
@ -9,24 +7,24 @@ have a system in place that updates our inventory for us. It was developed by a
|
||||
Leeroy, who has moved on to new adventures. Your task is to add the new feature to our system so that
|
||||
we can begin selling a new category of items. 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
|
||||
* 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
|
||||
* 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
|
||||
* "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
|
||||
@ -10,8 +10,8 @@
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<junit.jupiter.version>5.6.2</junit.jupiter.version>
|
||||
<java.version>16</java.version>
|
||||
<junit.jupiter.version>5.7.2</junit.jupiter.version>
|
||||
<maven.maven-surefire-plugin.version>3.0.0-M4</maven.maven-surefire-plugin.version>
|
||||
</properties>
|
||||
|
||||
|
||||
18
Java/src/main/java/com/gildedrose/AgedBrie.java
Normal file
18
Java/src/main/java/com/gildedrose/AgedBrie.java
Normal file
@ -0,0 +1,18 @@
|
||||
package com.gildedrose;
|
||||
|
||||
import static com.gildedrose.Constants.MAX_QUALITY;
|
||||
|
||||
public class AgedBrie extends InventoryItem {
|
||||
public AgedBrie(Item item) {
|
||||
super(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
void age() {
|
||||
if (item.quality < MAX_QUALITY) {
|
||||
item.quality++;
|
||||
}
|
||||
decreaseSellIn();
|
||||
if (item.sellIn < Constants.SELLIN_DAY && item.quality < MAX_QUALITY) item.quality++;
|
||||
}
|
||||
}
|
||||
19
Java/src/main/java/com/gildedrose/Backstage.java
Normal file
19
Java/src/main/java/com/gildedrose/Backstage.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.gildedrose;
|
||||
|
||||
public class Backstage extends InventoryItem {
|
||||
|
||||
public Backstage(Item item) {
|
||||
super(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
void age() {
|
||||
if (item.quality < Constants.MAX_QUALITY) {
|
||||
item.quality = item.quality + 1;
|
||||
if (item.sellIn < 11 && item.quality < Constants.MAX_QUALITY) item.quality++;
|
||||
if (item.sellIn < 6 && item.quality < Constants.MAX_QUALITY) item.quality++;
|
||||
}
|
||||
decreaseSellIn();
|
||||
if (item.sellIn < Constants.SELLIN_DAY) item.quality = Constants.MIN_QUALITY;
|
||||
}
|
||||
}
|
||||
19
Java/src/main/java/com/gildedrose/Conjured.java
Normal file
19
Java/src/main/java/com/gildedrose/Conjured.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.gildedrose;
|
||||
|
||||
public class Conjured extends InventoryItem {
|
||||
public Conjured(Item item) {
|
||||
super(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
void age() {
|
||||
decreaseQuality();
|
||||
decreaseSellIn();
|
||||
if (item.sellIn < Constants.SELLIN_DAY) decreaseQuality();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decreaseQuality() {
|
||||
if (item.quality > Constants.MIN_QUALITY) item.quality -= 2;
|
||||
}
|
||||
}
|
||||
14
Java/src/main/java/com/gildedrose/Constants.java
Normal file
14
Java/src/main/java/com/gildedrose/Constants.java
Normal file
@ -0,0 +1,14 @@
|
||||
package com.gildedrose;
|
||||
|
||||
public final class Constants {
|
||||
public static final String BACKSTAGE = "Backstage passes to a TAFKAL80ETC concert";
|
||||
public static final String AGED_BRIE = "Aged Brie";
|
||||
public static final String SULFURAS = "Sulfuras, Hand of Ragnaros";
|
||||
public static final String CONJURED = "Conjured Mana Cake";
|
||||
public static final int MAX_QUALITY = 50;
|
||||
public static final int MIN_QUALITY = 0;
|
||||
public static final int SELLIN_DAY = 0;
|
||||
|
||||
private Constants() {
|
||||
}
|
||||
}
|
||||
@ -1,62 +1,17 @@
|
||||
package com.gildedrose;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
class GildedRose {
|
||||
|
||||
Item[] items;
|
||||
|
||||
public 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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void updateQuality(GildedRose gildedRose) {
|
||||
Arrays.stream(gildedRose.items).forEach(item -> InventoryItem.createInventoryItem(item).age());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
33
Java/src/main/java/com/gildedrose/InventoryItem.java
Normal file
33
Java/src/main/java/com/gildedrose/InventoryItem.java
Normal file
@ -0,0 +1,33 @@
|
||||
package com.gildedrose;
|
||||
|
||||
import static com.gildedrose.Constants.*;
|
||||
|
||||
public class InventoryItem {
|
||||
protected final Item item;
|
||||
|
||||
InventoryItem(Item item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
public static InventoryItem createInventoryItem(Item item) {
|
||||
if (item.name.equals(SULFURAS)) return new Sulfuras(item);
|
||||
if (item.name.equals(AGED_BRIE)) return new AgedBrie(item);
|
||||
if (item.name.equals(BACKSTAGE)) return new Backstage(item);
|
||||
if (item.name.equals(CONJURED)) return new Conjured(item);
|
||||
return new InventoryItem(item);
|
||||
}
|
||||
|
||||
void age() {
|
||||
decreaseQuality();
|
||||
decreaseSellIn();
|
||||
if (item.sellIn < Constants.SELLIN_DAY) decreaseQuality();
|
||||
}
|
||||
|
||||
protected void decreaseSellIn() {
|
||||
item.sellIn--;
|
||||
}
|
||||
|
||||
protected void decreaseQuality() {
|
||||
if (item.quality > Constants.MIN_QUALITY) item.quality--;
|
||||
}
|
||||
}
|
||||
12
Java/src/main/java/com/gildedrose/Sulfuras.java
Normal file
12
Java/src/main/java/com/gildedrose/Sulfuras.java
Normal file
@ -0,0 +1,12 @@
|
||||
package com.gildedrose;
|
||||
|
||||
public class Sulfuras extends InventoryItem {
|
||||
public Sulfuras(Item item) {
|
||||
super(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
void age() {
|
||||
// Sulfuras never changes its properties
|
||||
}
|
||||
}
|
||||
@ -8,10 +8,70 @@ class GildedRoseTest {
|
||||
|
||||
@Test
|
||||
void foo() {
|
||||
Item[] items = new Item[] { new Item("foo", 0, 0) };
|
||||
Item[] items = new Item[]{new Item("foo", 0, 0)};
|
||||
GildedRose app = new GildedRose(items);
|
||||
app.updateQuality();
|
||||
assertEquals("fixme", app.items[0].name);
|
||||
GildedRose.updateQuality(app);
|
||||
assertEquals("foo", app.items[0].name);
|
||||
}
|
||||
|
||||
@Test
|
||||
void degradesTwiceAsFastAfterSellInDateHasPassed() {
|
||||
Item[] items = new Item[]{new Item("foo", 0, 2)};
|
||||
GildedRose.updateQuality(new GildedRose(items));
|
||||
assertEquals(0, items[0].quality);
|
||||
}
|
||||
|
||||
@Test
|
||||
void neverMustHaveNegativeQuality() {
|
||||
Item[] items = new Item[]{new Item("foo", 0, 0)};
|
||||
GildedRose.updateQuality(new GildedRose(items));
|
||||
assertEquals(0, items[0].quality);
|
||||
}
|
||||
|
||||
@Test
|
||||
void increaseAgedBrieQualityWhenItGetsOlder() {
|
||||
Item[] items = new Item[]{new Item(Constants.AGED_BRIE, 0, 2)};
|
||||
GildedRose.updateQuality(new GildedRose(items));
|
||||
assertEquals(4, items[0].quality);
|
||||
}
|
||||
|
||||
@Test
|
||||
void neverMustHaveAnItemWithMoreThan50OfQuality() {
|
||||
Item[] items = new Item[]{new Item(Constants.AGED_BRIE, 0, 50)};
|
||||
GildedRose.updateQuality(new GildedRose(items));
|
||||
assertEquals(50, items[0].quality);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void neverModifySulfurasQuality() {
|
||||
Item[] items = new Item[]{new Item(Constants.SULFURAS, 0, 50)};
|
||||
GildedRose.updateQuality(new GildedRose(items));
|
||||
assertEquals(50, items[0].quality);
|
||||
}
|
||||
|
||||
@Test
|
||||
void neverModifySulfurasQualityEvenISGreaterThan50() {
|
||||
Item[] items = new Item[]{new Item(Constants.SULFURAS, 0, 80)};
|
||||
GildedRose.updateQuality(new GildedRose(items));
|
||||
assertEquals(80, items[0].quality);
|
||||
}
|
||||
|
||||
@Test
|
||||
void mustIncreaseBackstagePassesQualityWhenItsSellInApproaches() {
|
||||
Item[] items = new Item[]{new Item(Constants.BACKSTAGE, 15, 20),
|
||||
new Item(Constants.BACKSTAGE, 10, 20),
|
||||
new Item(Constants.BACKSTAGE, 5, 20)};
|
||||
GildedRose.updateQuality(new GildedRose(items));
|
||||
assertEquals(21, items[0].quality);
|
||||
assertEquals(22, items[1].quality);
|
||||
assertEquals(23, items[2].quality);
|
||||
}
|
||||
|
||||
@Test
|
||||
void mustDecreaseQualityTwiceAsFastIfItemIsConjured() {
|
||||
Item[] items = new Item[]{new Item(Constants.CONJURED, 0, 20)};
|
||||
GildedRose.updateQuality(new GildedRose(items));
|
||||
assertEquals(16, items[0].quality);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,42 @@
|
||||
package com.gildedrose;
|
||||
|
||||
import org.approvaltests.combinations.CombinationApprovals;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
class GoldenMasterApprovalTest {
|
||||
|
||||
@Test
|
||||
void
|
||||
gildedRoseApprovalTest() {
|
||||
CombinationApprovals.verifyAllCombinations(
|
||||
this::updateItem,
|
||||
itemTypes(),
|
||||
qualityRangeValues(),
|
||||
sellInRangeValues()
|
||||
);
|
||||
}
|
||||
|
||||
private String[] itemTypes() {
|
||||
return new String[]{Constants.AGED_BRIE, Constants.BACKSTAGE, "Common item", Constants.CONJURED, Constants.SULFURAS};
|
||||
}
|
||||
|
||||
private Integer[] sellInRangeValues() {
|
||||
return IntStream.range(-1, 12).boxed().toArray(Integer[]::new);
|
||||
}
|
||||
|
||||
private Integer[] qualityRangeValues() {
|
||||
return IntStream.range(0, 51).boxed().toArray(Integer[]::new);
|
||||
}
|
||||
|
||||
private Item updateItem(String name, int quality, int sellIn) {
|
||||
final Item item = new ItemBuilder()
|
||||
.setName(name)
|
||||
.setSellIn(sellIn)
|
||||
.setQuality(quality)
|
||||
.createItem();
|
||||
GildedRose.updateQuality(new GildedRose(new Item[]{item}));
|
||||
return item;
|
||||
}
|
||||
}
|
||||
26
Java/src/test/java/com/gildedrose/ItemBuilder.java
Normal file
26
Java/src/test/java/com/gildedrose/ItemBuilder.java
Normal file
@ -0,0 +1,26 @@
|
||||
package com.gildedrose;
|
||||
|
||||
public class ItemBuilder {
|
||||
private String name;
|
||||
private int sellIn;
|
||||
private int quality;
|
||||
|
||||
public ItemBuilder setName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder setSellIn(int sellIn) {
|
||||
this.sellIn = sellIn;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder setQuality(int quality) {
|
||||
this.quality = quality;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Item createItem() {
|
||||
return new Item(name, sellIn, quality);
|
||||
}
|
||||
}
|
||||
@ -30,7 +30,7 @@ public class TexttestFixture {
|
||||
System.out.println(item);
|
||||
}
|
||||
System.out.println();
|
||||
app.updateQuality();
|
||||
GildedRose.updateQuality(app);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user