Merge pull request #1 from RdelaBanda/java-refactor

Java refactor
This commit is contained in:
Roberto de la Banda 2021-09-11 15:28:39 +02:00 committed by GitHub
commit f0d37a48e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 3585 additions and 74 deletions

View File

@ -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

View File

@ -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>

View 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++;
}
}

View 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;
}
}

View 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;
}
}

View 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() {
}
}

View File

@ -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());
}
}
}

View 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--;
}
}

View 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
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View 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);
}
}

View File

@ -30,7 +30,7 @@ public class TexttestFixture {
System.out.println(item);
}
System.out.println();
app.updateQuality();
GildedRose.updateQuality(app);
}
}

View File

@ -2,5 +2,5 @@
## Gilded Rose Requirements in other languages
- [English](GildedRoseRequirements.txt)
- [English](GildedRoseRequirements_en.md)
- [Español](GildedRoseRequirements_es.md)