Test coverage improved to %94

This commit is contained in:
Erol Shaban 2019-08-21 16:46:20 +02:00
parent df8e2f0d36
commit 7cdd525d14
8 changed files with 182 additions and 196 deletions

View File

@ -1,12 +1,6 @@
package com.gildedrose;
public class AgedBrieUpdater extends ItemUpdater {
@Override
void updateQuality(Item item) {
if (canUpdateQuality(item)) {
item.quality += getDegradeValue(item);
}
}
@Override
void updateSellIn(Item item) {
@ -19,7 +13,7 @@ public class AgedBrieUpdater extends ItemUpdater {
}
@Override
int getDegradeValue(Item item) {
int getUpdateValue(Item item) {
return INCREASE_NORMAL;
}
}

View File

@ -1,14 +1,6 @@
package com.gildedrose;
public class BackstagePassUpdater extends ItemUpdater {
@Override
void updateQuality(Item item) {
if (sellByDateLessThan(item, 0)) {
item.quality = 0;
} else if (canUpdateQuality(item)) {
item.quality += getDegradeValue(item);
}
}
@Override
void updateSellIn(Item item) {
@ -17,12 +9,14 @@ public class BackstagePassUpdater extends ItemUpdater {
@Override
boolean canUpdateQuality(final Item item) {
return item.quality < HIGHEST_QUALITY;
return item.quality < HIGHEST_QUALITY && item.quality > MIN_QUALITY;
}
@Override
int getDegradeValue(final Item item) {
if (sellByDateLessThan(item, 6)) {
int getUpdateValue(final Item item) {
if (sellByDateLessThan(item, 0)) {
return -item.quality;
} else if (sellByDateLessThan(item, 6)) {
return INCREASE_THRICE_AS_FAST;
} else if (sellByDateLessThan(item, 11) ) {
return INCREASE_TWICE_AS_FAST;

View File

@ -1,27 +1,13 @@
package com.gildedrose;
public class ConjuredUpdater extends ItemUpdater {
public class ConjuredUpdater extends StandardItemUpdater {
@Override
void updateQuality(Item item) {
if (canUpdateQuality(item)) {
item.quality += getDegradeValue(item);
int getUpdateValue(final Item item) {
if (item.sellIn < 0) {
return DEGRADE_TWICE_AS_FAST * 2;
} else {
return DEGRADE_TWICE_AS_FAST;
}
}
@Override
void updateSellIn(Item item) {
item.sellIn -= 1;
}
@Override
boolean canUpdateQuality(Item item) {
return item.quality < HIGHEST_QUALITY && item.quality > 0;
}
@Override
int getDegradeValue(Item item) {
return item.quality + DEGRADE_TWICE_AS_FAST < 0 ?
DEGRADE_NORMAL :
DEGRADE_TWICE_AS_FAST;
}
}

View File

@ -1,62 +0,0 @@
package com.gildedrose;
class GildedRoseOld {
Item[] items;
public GildedRoseOld(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;
}
}
}
}
}
}

View File

@ -2,22 +2,28 @@ package com.gildedrose;
public abstract class ItemUpdater {
static int HIGHEST_QUALITY = 50;
static int MIN_QUALITY = 0;
static int DEGRADE_NORMAL = -1;
static int DEGRADE_TWICE_AS_FAST = -2;
static int INCREASE_NORMAL = 1;
static int INCREASE_TWICE_AS_FAST = 2;
static int INCREASE_THRICE_AS_FAST = 3;
public void updateStateFor(Item item){
void updateStateFor(Item item){
updateSellIn(item);
updateQuality(item);
}
abstract void updateQuality(Item item);
private void updateQuality(Item item) {
if (canUpdateQuality(item)) {
item.quality = Math.max(getNewQuality(item), 0);
}
}
abstract void updateSellIn(Item item);
abstract boolean canUpdateQuality(Item item);
abstract int getDegradeValue(Item item);
abstract int getUpdateValue(Item item);
public int getHighestQuality() {
return HIGHEST_QUALITY;
private int getNewQuality(Item item){
return Math.min(item.quality + getUpdateValue(item), HIGHEST_QUALITY);
}
}

View File

@ -2,13 +2,6 @@ package com.gildedrose;
public class StandardItemUpdater extends ItemUpdater {
@Override
void updateQuality(Item item) {
if (canUpdateQuality(item)) {
item.quality += getDegradeValue(item);
}
}
@Override
void updateSellIn(Item item) {
item.sellIn -= 1;
@ -16,13 +9,13 @@ public class StandardItemUpdater extends ItemUpdater {
@Override
boolean canUpdateQuality(Item item) {
return item.quality < HIGHEST_QUALITY && item.quality > 0;
return item.quality <= HIGHEST_QUALITY && item.quality > MIN_QUALITY;
}
@Override
int getDegradeValue(Item item) {
int getUpdateValue(Item item) {
if (item.sellIn < 0) {
return item.quality + DEGRADE_TWICE_AS_FAST < 0 ? DEGRADE_NORMAL : DEGRADE_TWICE_AS_FAST;
return DEGRADE_NORMAL * 2;
} else {
return DEGRADE_NORMAL;
}

View File

@ -1,17 +1,9 @@
package com.gildedrose;
public class SulfurasUpdater extends ItemUpdater {
@Override
void updateQuality(Item item) {
System.out.println("########Sulfuras is a legendary product");
// TODO
item.quality = 80;
}
@Override
void updateSellIn(Item item) {
System.out.println("########Never gets old");
System.out.print("########Never gets old ############");
}
@Override
@ -21,12 +13,8 @@ public class SulfurasUpdater extends ItemUpdater {
}
@Override
int getDegradeValue(Item item) {
// "Sulfuras", being a legendary item, never has to be sold
int getUpdateValue(Item item) {
// "Sulfuras", being a legendary item, never decreases in Quality
return 0;
}
public int getHighestQuality() {
return 80;
}
}

View File

@ -1,7 +1,5 @@
package com.gildedrose;
import static org.junit.Assert.*;
import org.junit.Test;
import java.util.Arrays;
@ -9,68 +7,138 @@ import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import static com.gildedrose.ItemUpdater.HIGHEST_QUALITY;
import static com.gildedrose.ItemUpdater.MIN_QUALITY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
public class GildedRoseTest {
/*
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
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
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
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
goblin in the corner who will insta-rage and one-shot you as he doesn't believe in shared code
ownership (you can make the UpdateQuality method and Items property static if you like, we'll cover
for you).
Just for clarification, an item can never have its Quality increase above 50, however "Sulfuras" is a
legendary item and as such its Quality is 80 and it never alters.
*/
private final Item sulfuras = new Item("Sulfuras, Hand of Ragnaros", 0, 80);
private final Item standardWithHighestQuality = new Item("Standard", 5, 50);
private final Item agedBrieWithHighestQuality = new Item("Aged Brie", 5, 50);
private final Item conjuredWithHighestQuality = new Item("Conjured Mana Cake", 5, 50);
private final Item backstageWithHighestQuality = new Item("Backstage passes to a TAFKAL80ETC concert", 5, 50);
private final Item standardWithHighestQuality = new Item("Standard", 5, HIGHEST_QUALITY);
private final Item agedBrieWithHighestQuality = new Item("Aged Brie", 5, HIGHEST_QUALITY);
private final Item conjuredWithHighestQuality = new Item("Conjured Mana Cake", 5, HIGHEST_QUALITY);
private final Item backstageWithHighestQuality = new Item("Backstage passes to a TAFKAL80ETC concert", 5, HIGHEST_QUALITY);
private final Item standardWithLowQuality = new Item("Standard", 0, 1);
private final Item agedBrieWithLowQuality = new Item("Aged Brie", 0, 1);
private final Item conjuredWithLowQuality = new Item("Conjured Mana Cake", 0, 1);
private final Item backstageWithLowQuality = new Item("Backstage passes to a TAFKAL80ETC concert", 0, 1);
private final Item standardWithLowQuality = new Item("Standard", 0, MIN_QUALITY + 1);
private final Item agedBrieWithLowQuality = new Item("Aged Brie", 0, MIN_QUALITY + 1);
private final Item conjuredWithLowQuality = new Item("Conjured Mana Cake", 0, MIN_QUALITY + 1);
private final Item backstageWithLowQuality = new Item("Backstage passes to a TAFKAL80ETC concert", 0, MIN_QUALITY + 1);
private GildedRose app;
@Test
public void backstageItem_shouldIncreaseThriceAsFast_whenLessThan5DaysLeftToSellByDate() {
final int originalQuality = 20;
final Item[] items = new Item[]{new Item("Backstage passes to a TAFKAL80ETC concert", 5, originalQuality)};
app = new GildedRose(items);
app.updateQuality();
assertEquals(4, app.items[0].sellIn);
assertEquals(originalQuality + 3, app.items[0].quality);
}
@Test
public void backstageItem_shouldIncreaseTwiceAsFast_whenLessThan10DaysLeftToSellByDate() {
final int originalQuality = 20;
final Item[] items = new Item[]{new Item("Backstage passes to a TAFKAL80ETC concert", 10, originalQuality)};
app = new GildedRose(items);
app.updateQuality();
assertEquals(9, app.items[0].sellIn);
assertEquals(originalQuality + 2, app.items[0].quality);
}
@Test
public void backstageItem_shouldIncreaseNormal_whenMoreThan10DaysLeftToSellByDate() {
final int originalQuality = 20;
final Item[] items = new Item[]{new Item("Backstage passes to a TAFKAL80ETC concert", 15, originalQuality)};
app = new GildedRose(items);
app.updateQuality();
assertEquals(14, app.items[0].sellIn);
assertEquals(originalQuality + 1, app.items[0].quality);
}
@Test
public void backstageItemQuality_shouldBeZero_whenSellByDatePassed() {
final int originalQuality = 20;
final Item[] items = new Item[]{new Item("Backstage passes to a TAFKAL80ETC concert", 0, originalQuality)};
app = new GildedRose(items);
app.updateQuality();
assertEquals(-1, app.items[0].sellIn);
assertEquals(MIN_QUALITY, app.items[0].quality);
}
@Test
public void backstageItemQuality_shouldStayZero_afterTheConcert() {
final int originalQuality = 20;
final Item[] items = new Item[]{new Item("Backstage passes to a TAFKAL80ETC concert", 0, originalQuality)};
app = new GildedRose(items);
app.updateQuality();
assertEquals(-1, app.items[0].sellIn);
assertEquals(MIN_QUALITY, app.items[0].quality);
app.updateQuality();
assertEquals(-2, app.items[0].sellIn);
assertEquals(MIN_QUALITY, app.items[0].quality);
}
@Test
public void standardItem_shouldDegradeNormal_whenSellByDateNotPassed() {
final int originalQuality = 40;
final Item[] items = new Item[] { new Item("Standard", 4, originalQuality) };
final GildedRose app = new GildedRose(items);
final Item[] items = new Item[]{new Item("Standard", 4, originalQuality)};
app = new GildedRose(items);
app.updateQuality();
assertEquals("Standard", app.items[0].name);
assertEquals(3, app.items[0].sellIn);
assertEquals(originalQuality - 1, app.items[0].quality);
}
@Test
public void agedBrie_shouldIncreaseNormal() {
final int originalQuality = agedBrieWithLowQuality.quality;
final int originalSellIn = agedBrieWithLowQuality.sellIn;
final Item[] items = new Item[]{agedBrieWithLowQuality};
app = new GildedRose(items);
app.updateQuality();
assertEquals(agedBrieWithLowQuality.name, app.items[0].name);
assertEquals(originalSellIn - 1, app.items[0].sellIn);
assertEquals(originalQuality + 1, app.items[0].quality);
}
@Test
public void agedBrie_shouldIncreaseNormal_whenOriginalQualityIsZero() {
final int originalQuality = 0;
final int originalSellIn = 2;
final Item[] items = new Item[]{new Item("Aged Brie", originalSellIn, originalQuality)};
app = new GildedRose(items);
app.updateQuality();
assertEquals("Aged Brie", app.items[0].name);
assertEquals(originalSellIn - 1, app.items[0].sellIn);
assertEquals(originalQuality + 1, app.items[0].quality);
}
@Test
public void agedBrie_shouldNotIncrease_moreThanHighestValue() {
final int originalQuality = agedBrieWithHighestQuality.quality;
final int originalSellIn = agedBrieWithHighestQuality.sellIn;
final Item[] items = new Item[]{agedBrieWithHighestQuality};
app = new GildedRose(items);
app.updateQuality();
assertEquals(agedBrieWithHighestQuality.name, app.items[0].name);
assertEquals(originalSellIn - 1, app.items[0].sellIn);
assertEquals(originalQuality, app.items[0].quality);
}
@Test
public void standardItem_shouldDegradeTwiceAsFast_whenSellByDatePassed() {
final int originalQuality = 40;
final Item[] items = new Item[] { new Item("Standard", 0, originalQuality) };
final GildedRose app = new GildedRose(items);
final Item[] items = new Item[]{new Item("Standard", 0, originalQuality)};
app = new GildedRose(items);
app.updateQuality();
assertEquals("Standard", app.items[0].name);
assertEquals(-1, app.items[0].sellIn);
@ -84,51 +152,70 @@ Pretty simple, right? Well this is where it gets interesting:
@Test
public void sulfurus_shouldNeverDegradeAndBeSold() {
final Item[] items = new Item[] { sulfuras};
final GildedRose app = new GildedRose(items);
final Item[] items = new Item[]{sulfuras};
app = new GildedRose(items);
app.updateQuality();
assertEquals("Sulfuras, Hand of Ragnaros", app.items[0].name);
assertEquals(0, app.items[0].sellIn);
assertEquals(80, app.items[0].quality);
app.updateQuality();
assertEquals(0, app.items[0].sellIn);
assertEquals(80, app.items[0].quality);
}
@Test
public void qualityOfItem_exceptLegendaryItems_cantBeMoreThan_50() {
final Item[] items = new Item[] {standardWithHighestQuality, backstageWithHighestQuality,
public void qualityOfItem_exceptLegendaryItems_cantBeMoreThanHighestValue() {
final Item[] items = new Item[]{standardWithHighestQuality, backstageWithHighestQuality,
agedBrieWithHighestQuality, conjuredWithHighestQuality};
final GildedRose app = new GildedRose(items);
app = new GildedRose(items);
app.updateQuality();
final Optional<Item> qualityHigherThan80 = Arrays.stream(app.items).filter(item -> item.quality > 50).findAny();
final Optional<Item> qualityHigherThan80 = Arrays.stream(app.items).filter(item -> item.quality > HIGHEST_QUALITY).findAny();
assertFalse(qualityHigherThan80.isPresent());
}
@Test
public void qualityOfItem_onlyLegendaryItems_cantBeMoreThan_50() {
final Item[] items = new Item[] { sulfuras, standardWithHighestQuality, backstageWithHighestQuality,
public void qualityOfItem_onlyLegendaryItems_cantBeMoreThanHighestValue() {
final Item[] items = new Item[]{sulfuras, standardWithHighestQuality, backstageWithHighestQuality,
agedBrieWithHighestQuality, conjuredWithHighestQuality};
final GildedRose app = new GildedRose(items);
app = new GildedRose(items);
app.updateQuality();
final List<Item> qualityHigherThan80List = Arrays.stream(app.items).filter(item -> item.quality > 50).collect(Collectors.toList());
final List<Item> qualityHigherThan50List = Arrays.stream(app.items).filter(item -> item.quality > HIGHEST_QUALITY).collect(Collectors.toList());
assertEquals(1, qualityHigherThan80List.size());
assertEquals(sulfuras.name, qualityHigherThan80List.get(0).name);
assertEquals(1, qualityHigherThan50List.size());
assertEquals(sulfuras.name, qualityHigherThan50List.get(0).name);
}
@Test
public void qualityOfItem_canNeverBeNegative() {
final Item[] items = new Item[] {sulfuras, standardWithLowQuality, backstageWithLowQuality,
public void qualityOfItem_canNeverBeNegative_afterMultipleUpdates() {
final Item[] items = new Item[]{sulfuras, standardWithLowQuality, backstageWithLowQuality,
agedBrieWithLowQuality, conjuredWithLowQuality};
final GildedRose app = new GildedRose(items);
app.updateQuality();
final Optional<Item> qualityNegative = Arrays.stream(app.items).filter(item -> item.quality < 0 ).findAny();
app = new GildedRose(items);
app.updateQuality();
final Optional<Item> qualityNegative = Arrays.stream(app.items).filter(item -> item.quality < MIN_QUALITY).findAny();
assertFalse(qualityNegative.isPresent());
app.updateQuality();
final Optional<Item> qualityNegativeAfter2ndUpdate = Arrays.stream(app.items).filter(item -> item.quality < 0 ).findAny();
final Optional<Item> qualityNegativeAfter2ndUpdate = Arrays.stream(app.items).filter(item -> item.quality < MIN_QUALITY).findAny();
assertFalse(qualityNegativeAfter2ndUpdate.isPresent());
final long minimumQualityItemsCount = Arrays.stream(app.items).filter(item -> item.quality == MIN_QUALITY).count();
// AgedBrie should increase in value, others' quality (3 of them) should be 0
assertEquals(3, minimumQualityItemsCount);
}
@Test
public void conjuredItems_shouldDegradeAsTwiceAsFast_thenTheStandardItems() {
final Item[] items = new Item[]{conjuredWithHighestQuality};
app = new GildedRose(items);
for (int i=0; i< 7; i++) {
app.updateQuality();
}
assertEquals(-2, app.items[0].sellIn);
assertEquals(32, app.items[0].quality);
}
}