diff --git a/Java/pom.xml b/Java/pom.xml
index 3bd6aff8..1c55a873 100644
--- a/Java/pom.xml
+++ b/Java/pom.xml
@@ -10,10 +10,12 @@
0.0.1-SNAPSHOT
- 1.8
+ 1.9
5.8.2
3.1
3.0.0-M4
+ 1.18.38
+ 2.0.17
UTF-8
@@ -24,6 +26,22 @@
${junit.jupiter.version}
test
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ true
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+ org.slf4j
+ slf4j-simple
+ ${slf4j.version}
+
diff --git a/Java/src/main/java/com/gildedrose/GildedRose.java b/Java/src/main/java/com/gildedrose/GildedRose.java
index 87a3b926..fc3a5eb6 100644
--- a/Java/src/main/java/com/gildedrose/GildedRose.java
+++ b/Java/src/main/java/com/gildedrose/GildedRose.java
@@ -1,61 +1,61 @@
package com.gildedrose;
-class GildedRose {
- Item[] items;
+import com.gildedrose.enums.ItemName;
+import com.gildedrose.service.AgedBrieQualityUpdater;
+import com.gildedrose.service.BackstagePassesQualityUpdater;
+import com.gildedrose.service.ConjuredQualityUpdater;
+import com.gildedrose.service.GeneralQualityUpdater;
+import com.gildedrose.service.QualityUpdater;
+import lombok.Data;
- public GildedRose(Item[] items) {
- this.items = items;
- }
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.gildedrose.enums.ItemName.AGED_BRIE;
+import static com.gildedrose.enums.ItemName.BACKSTAGE_PASSES;
+import static com.gildedrose.enums.ItemName.CONJURED;
+import static com.gildedrose.enums.ItemName.GENERAL;
+
+@Data
+public class GildedRose {
+
+ private static final Map qualityUpdaters =
+ Map.of(AGED_BRIE, new AgedBrieQualityUpdater(),
+ BACKSTAGE_PASSES, new BackstagePassesQualityUpdater(),
+ CONJURED, new ConjuredQualityUpdater(),
+ GENERAL, new GeneralQualityUpdater());
+
+ private final List- 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;
+ Set itemNames = items.stream().map(item -> ItemName.resolve(item.getName())).collect(Collectors.toSet());
- 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;
- }
- }
+ for (ItemName itemName : itemNames) {
+ QualityUpdater qualityUpdater = null;
- if (items[i].sellIn < 6) {
- if (items[i].quality < 50) {
- items[i].quality = items[i].quality + 1;
- }
- }
- }
- }
+ switch (itemName) {
+ case AGED_BRIE:
+ qualityUpdater = qualityUpdaters.get(AGED_BRIE);
+ break;
+ case BACKSTAGE_PASSES:
+ qualityUpdater = qualityUpdaters.get(BACKSTAGE_PASSES);
+ break;
+ case SULFURAS_HAND_RANGAROS:
+ // nothing has to be done in that case - this is immutable object
+ break;
+ case CONJURED:
+ qualityUpdater = qualityUpdaters.get(CONJURED);
+ break;
+ default:
+ qualityUpdater = qualityUpdaters.get(GENERAL);
}
- 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;
- }
- }
+ if (qualityUpdater != null) {
+ List
- properItems =
+ items.stream().filter(item -> itemName.equals(ItemName.resolve(item.getName()))).collect(Collectors.toList());
+ qualityUpdater.updateQuality(properItems);
}
}
}
diff --git a/Java/src/main/java/com/gildedrose/Item.java b/Java/src/main/java/com/gildedrose/Item.java
index 465729ec..5aa1b301 100644
--- a/Java/src/main/java/com/gildedrose/Item.java
+++ b/Java/src/main/java/com/gildedrose/Item.java
@@ -1,21 +1,14 @@
package com.gildedrose;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
public class Item {
- public String name;
+ private String name;
+ private int sellIn;
+ private int quality;
- public int sellIn;
-
- public int quality;
-
- public Item(String name, int sellIn, int quality) {
- this.name = name;
- this.sellIn = sellIn;
- this.quality = quality;
- }
-
- @Override
- public String toString() {
- return this.name + ", " + this.sellIn + ", " + this.quality;
- }
}
diff --git a/Java/src/main/java/com/gildedrose/enums/BorderDays.java b/Java/src/main/java/com/gildedrose/enums/BorderDays.java
new file mode 100644
index 00000000..27a780a6
--- /dev/null
+++ b/Java/src/main/java/com/gildedrose/enums/BorderDays.java
@@ -0,0 +1,18 @@
+package com.gildedrose.enums;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@Getter
+@RequiredArgsConstructor
+public enum BorderDays {
+
+ INCREASE_QUALITY_BY_TWO_WHEN_LESS_THEN_OR_EQUAL_TEN_DAYS(10),
+ INCREASE_QUALITY_BY_THREE_WHEN_LESS_THEN_OR_EQUAL_FIVE_DAYS(5),
+ INCREASE_BY_TWO_DAYS(2),
+ INCREASE_BY_THREE_DAYS(3),
+ DATE_HAS_PASSED(0);
+
+ private final int days;
+
+}
diff --git a/Java/src/main/java/com/gildedrose/enums/BorderQualities.java b/Java/src/main/java/com/gildedrose/enums/BorderQualities.java
new file mode 100644
index 00000000..499bdd6a
--- /dev/null
+++ b/Java/src/main/java/com/gildedrose/enums/BorderQualities.java
@@ -0,0 +1,15 @@
+package com.gildedrose.enums;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@Getter
+@RequiredArgsConstructor
+public enum BorderQualities {
+
+ MIN_QUALITY(0),
+ MAX_QUALITY(50);
+
+ private final int quality;
+
+}
diff --git a/Java/src/main/java/com/gildedrose/enums/ItemName.java b/Java/src/main/java/com/gildedrose/enums/ItemName.java
new file mode 100644
index 00000000..874c9f32
--- /dev/null
+++ b/Java/src/main/java/com/gildedrose/enums/ItemName.java
@@ -0,0 +1,27 @@
+package com.gildedrose.enums;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.Set;
+
+@Getter
+@RequiredArgsConstructor
+public enum ItemName {
+
+ BACKSTAGE_PASSES("Backstage passes to a TAFKAL80ETC concert"),
+ SULFURAS_HAND_RANGAROS("Sulfuras, Hand of Ragnaros"),
+ AGED_BRIE("Aged Brie"),
+ GENERAL("General item"),
+ CONJURED("Conjured Mana Cake");
+
+ private final String name;
+
+ public static ItemName resolve(String name) {
+ return Set.of(ItemName.values()).stream()
+ .filter(itemName -> name.equalsIgnoreCase(itemName.getName()))
+ .findFirst()
+ .orElse(GENERAL);
+ }
+
+}
diff --git a/Java/src/main/java/com/gildedrose/service/AgedBrieQualityUpdater.java b/Java/src/main/java/com/gildedrose/service/AgedBrieQualityUpdater.java
new file mode 100644
index 00000000..acbc2f93
--- /dev/null
+++ b/Java/src/main/java/com/gildedrose/service/AgedBrieQualityUpdater.java
@@ -0,0 +1,32 @@
+package com.gildedrose.service;
+
+import com.gildedrose.Item;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+import static com.gildedrose.enums.BorderQualities.MAX_QUALITY;
+import static com.gildedrose.enums.BorderQualities.MIN_QUALITY;
+
+@NoArgsConstructor
+public class AgedBrieQualityUpdater implements QualityUpdater {
+
+ @Override
+ public void updateQuality(List
- items) {
+ for (Item item : items) {
+ item.setSellIn(item.getSellIn() - 1);
+ // quantity actually always increases as the item becomes older
+ if (item.getQuality() < MAX_QUALITY.getQuality() && item.getQuality() >= MIN_QUALITY.getQuality()) {
+ // Once the sell by date has passed, quality degrades twice as fast - should this have to happen, because it is logical contradiction ???
+ /*if (item.getSellIn() < DATE_HAS_PASSED.getDays()) {
+ item.setQuality(item.getQuality() / 2);
+ } else {*/
+ if (item.getSellIn() < 0) {
+ item.setQuality(item.getQuality() + 2);
+ } else {
+ item.setQuality(item.getQuality() + 1);
+ }
+ }
+ }
+ }
+}
diff --git a/Java/src/main/java/com/gildedrose/service/BackstagePassesQualityUpdater.java b/Java/src/main/java/com/gildedrose/service/BackstagePassesQualityUpdater.java
new file mode 100644
index 00000000..7103c670
--- /dev/null
+++ b/Java/src/main/java/com/gildedrose/service/BackstagePassesQualityUpdater.java
@@ -0,0 +1,44 @@
+package com.gildedrose.service;
+
+import com.gildedrose.Item;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+import static com.gildedrose.enums.BorderDays.DATE_HAS_PASSED;
+import static com.gildedrose.enums.BorderDays.INCREASE_BY_THREE_DAYS;
+import static com.gildedrose.enums.BorderDays.INCREASE_BY_TWO_DAYS;
+import static com.gildedrose.enums.BorderDays.INCREASE_QUALITY_BY_THREE_WHEN_LESS_THEN_OR_EQUAL_FIVE_DAYS;
+import static com.gildedrose.enums.BorderDays.INCREASE_QUALITY_BY_TWO_WHEN_LESS_THEN_OR_EQUAL_TEN_DAYS;
+import static com.gildedrose.enums.BorderQualities.MAX_QUALITY;
+import static com.gildedrose.enums.BorderQualities.MIN_QUALITY;
+
+@NoArgsConstructor
+public class BackstagePassesQualityUpdater implements QualityUpdater {
+
+ @Override
+ public void updateQuality(List
- items) {
+ for (Item item : items) {
+ item.setSellIn(item.getSellIn() - 1);
+
+ if (item.getSellIn() < DATE_HAS_PASSED.getDays()) {
+ item.setQuality(0);
+ }
+
+ // quantity actually always increases as the item becomes older (if sellIn < 0 decreases twice by general condition!)
+ if (item.getQuality() < MAX_QUALITY.getQuality() && item.getQuality() > MIN_QUALITY.getQuality()) {
+ // Once the sell by date has passed, quality degrades twice as fast - - should this have to happen, because it is logical contradiction ???
+ if (item.getSellIn() >= INCREASE_QUALITY_BY_THREE_WHEN_LESS_THEN_OR_EQUAL_FIVE_DAYS.getDays() &&
+ item.getSellIn() < INCREASE_QUALITY_BY_TWO_WHEN_LESS_THEN_OR_EQUAL_TEN_DAYS.getDays() &&
+ item.getQuality() + INCREASE_BY_TWO_DAYS.getDays() <= MAX_QUALITY.getQuality()) {
+ item.setQuality(item.getQuality() + INCREASE_BY_TWO_DAYS.getDays());
+ } else if (item.getSellIn() < INCREASE_QUALITY_BY_THREE_WHEN_LESS_THEN_OR_EQUAL_FIVE_DAYS.getDays() &&
+ item.getQuality() + INCREASE_BY_THREE_DAYS.getDays() <= MAX_QUALITY.getQuality()) {
+ item.setQuality(item.getQuality() + INCREASE_BY_THREE_DAYS.getDays());
+ } else {
+ item.setQuality(item.getQuality() + 1);
+ }
+ }
+ }
+ }
+}
diff --git a/Java/src/main/java/com/gildedrose/service/ConjuredQualityUpdater.java b/Java/src/main/java/com/gildedrose/service/ConjuredQualityUpdater.java
new file mode 100644
index 00000000..26c82d44
--- /dev/null
+++ b/Java/src/main/java/com/gildedrose/service/ConjuredQualityUpdater.java
@@ -0,0 +1,24 @@
+package com.gildedrose.service;
+
+import com.gildedrose.Item;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+import static com.gildedrose.enums.BorderQualities.MAX_QUALITY;
+import static com.gildedrose.enums.BorderQualities.MIN_QUALITY;
+
+@NoArgsConstructor
+public class ConjuredQualityUpdater implements QualityUpdater {
+ @Override
+ public void updateQuality(List
- items) {
+ for (Item item : items) {
+ item.setSellIn(item.getSellIn() - 1);
+ if (item.getQuality() < MAX_QUALITY.getQuality() &&
+ item.getQuality() > MIN_QUALITY.getQuality() &&
+ item.getQuality() - 2 >= MIN_QUALITY.getQuality()) {
+ item.setQuality(item.getQuality() - 2);
+ }
+ }
+ }
+}
diff --git a/Java/src/main/java/com/gildedrose/service/GeneralQualityUpdater.java b/Java/src/main/java/com/gildedrose/service/GeneralQualityUpdater.java
new file mode 100644
index 00000000..462e2baf
--- /dev/null
+++ b/Java/src/main/java/com/gildedrose/service/GeneralQualityUpdater.java
@@ -0,0 +1,28 @@
+package com.gildedrose.service;
+
+import com.gildedrose.Item;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+import static com.gildedrose.enums.BorderDays.DATE_HAS_PASSED;
+import static com.gildedrose.enums.BorderQualities.MAX_QUALITY;
+import static com.gildedrose.enums.BorderQualities.MIN_QUALITY;
+
+@NoArgsConstructor
+public class GeneralQualityUpdater implements QualityUpdater {
+
+ @Override
+ public void updateQuality(List
- items) {
+ for (Item item : items) {
+ item.setSellIn(item.getSellIn() - 1);
+ // at the end of each day decrease quantity and sellIn (quality > 0 and quantity <= 50 always)
+ if (item.getSellIn() < DATE_HAS_PASSED.getDays() &&
+ item.getQuality() - 2 >= MIN_QUALITY.getQuality()) {
+ item.setQuality(item.getQuality() - 2);
+ } else if (item.getQuality() < MAX_QUALITY.getQuality() && item.getQuality() > MIN_QUALITY.getQuality()) {
+ item.setQuality(item.getQuality() - 1);
+ }
+ }
+ }
+}
diff --git a/Java/src/main/java/com/gildedrose/service/QualityUpdater.java b/Java/src/main/java/com/gildedrose/service/QualityUpdater.java
new file mode 100644
index 00000000..52b4875a
--- /dev/null
+++ b/Java/src/main/java/com/gildedrose/service/QualityUpdater.java
@@ -0,0 +1,11 @@
+package com.gildedrose.service;
+
+import com.gildedrose.Item;
+
+import java.util.List;
+
+public interface QualityUpdater {
+
+ void updateQuality(List
- items);
+
+}
diff --git a/Java/src/test/java/com/gildedrose/GildedRoseTest.java b/Java/src/test/java/com/gildedrose/GildedRoseTest.java
index 8ae29eec..e520293b 100644
--- a/Java/src/test/java/com/gildedrose/GildedRoseTest.java
+++ b/Java/src/test/java/com/gildedrose/GildedRoseTest.java
@@ -1,6 +1,12 @@
package com.gildedrose;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import java.util.List;
+import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -8,10 +14,125 @@ class GildedRoseTest {
@Test
void foo() {
- Item[] items = new Item[] { new Item("foo", 0, 0) };
+ List
- items = List.of(new Item("foo", 0, 0));
GildedRose app = new GildedRose(items);
app.updateQuality();
- assertEquals("fixme", app.items[0].name);
+ assertEquals("foo", app.getItems().get(0).getName());
+ }
+
+ @ParameterizedTest
+ @MethodSource("agedBrieQualities")
+ void testAgedBrieQualityUpdater(String name, int sellIn, int quality) {
+ List
- items = List.of(new Item(name, sellIn, quality));
+ GildedRose app = new GildedRose(items);
+ for (int i = 0; i <= sellIn; i++) {
+ app.updateQuality();
+ }
+ for (Item item : items) {
+ assertEquals(name, item.getName());
+ assertEquals(quality + sellIn + 2, item.getQuality());
+ }
+ }
+
+ private static Stream agedBrieQualities() {
+ return Stream.of(
+ Arguments.of("Aged Brie", 2, 0),
+ Arguments.of("Aged Brie", 5, 10));
+ }
+
+ @ParameterizedTest
+ @MethodSource("backstagePassesQualities")
+ void testBackstagePassesQualityUpdater(String name, int sellIn, int quality) {
+ List
- items = List.of(new Item(name, sellIn, quality));
+ GildedRose app = new GildedRose(items);
+
+ for (int i = 0; i < sellIn; i++) {
+ app.updateQuality();
+ }
+
+ for (Item item : items) {
+ assertEquals(name, item.getName());
+ assertEquals(50 - item.getSellIn() * 5, item.getQuality());
+ }
+ }
+
+ private static Stream backstagePassesQualities() {
+ return Stream.of(
+ Arguments.of("Backstage passes to a TAFKAL80ETC concert", 15, 20),
+ Arguments.of("Backstage passes to a TAFKAL80ETC concert", 10, 49),
+ Arguments.of("Backstage passes to a TAFKAL80ETC concert", 5, 49));
+ }
+
+ @ParameterizedTest
+ @MethodSource("sulfurasQualities")
+ void testSulfurasQualityUpdater(String name, int sellIn, int quality) {
+ List
- items = List.of(new Item(name, sellIn, quality));
+ GildedRose app = new GildedRose(items);
+
+ for (int i = 0; i < sellIn; i++) {
+ app.updateQuality();
+ }
+
+ for (Item item : items) {
+ assertEquals(name, item.getName());
+ assertEquals(80, item.getQuality());
+ }
+ }
+
+ private static Stream sulfurasQualities() {
+ return Stream.of(
+ Arguments.of("Sulfuras, Hand of Ragnaros", 0, 80),
+ Arguments.of("Sulfuras, Hand of Ragnaros", -1, 80),
+ Arguments.of("Sulfuras, Hand of Ragnaros", 5, 80));
+ }
+
+ @ParameterizedTest
+ @MethodSource("conjuredQualities")
+ void testConjuredQualityUpdater(String name, int sellIn, int quality) {
+ List
- items = List.of(new Item(name, sellIn, quality));
+ GildedRose app = new GildedRose(items);
+
+ for (int i = 0; i < sellIn; i++) {
+ app.updateQuality();
+ }
+
+ for (Item item : items) {
+ assertEquals(name, item.getName());
+ assertEquals(Math.max(quality - sellIn * 2, 0), item.getQuality());
+ }
+ }
+
+ private static Stream conjuredQualities() {
+ return Stream.of(
+ Arguments.of("Conjured Mana Cake", 3, 6),
+ Arguments.of("Conjured Mana Cake", 2, 5),
+ Arguments.of("Conjured Mana Cake", 7, 10));
+ }
+
+ @ParameterizedTest
+ @MethodSource("generalQualities")
+ void testGeneralQualityUpdater(String name, int sellIn, int quality) {
+ List
- items = List.of(new Item(name, sellIn, quality));
+ GildedRose app = new GildedRose(items);
+
+ for (int i = 0; i < sellIn; i++) {
+ app.updateQuality();
+ }
+
+ for (Item item : items) {
+ assertEquals(name, item.getName());
+ if (item.getSellIn() < 0) {
+ assertEquals(quality - sellIn * 2, item.getQuality());
+ } else {
+ assertEquals(quality - sellIn, item.getQuality());
+ }
+ }
+ }
+
+ private static Stream generalQualities() {
+ return Stream.of(
+ Arguments.of("+5 Dexterity Vest", 10, 20),
+ Arguments.of("Elixir of the Mongoose", 5, 7));
}
}
diff --git a/Java/src/test/java/com/gildedrose/TexttestFixture.java b/Java/src/test/java/com/gildedrose/TextTestFixture.java
similarity index 71%
rename from Java/src/test/java/com/gildedrose/TexttestFixture.java
rename to Java/src/test/java/com/gildedrose/TextTestFixture.java
index d059c88f..5e79b2a1 100644
--- a/Java/src/test/java/com/gildedrose/TexttestFixture.java
+++ b/Java/src/test/java/com/gildedrose/TextTestFixture.java
@@ -1,10 +1,15 @@
package com.gildedrose;
-public class TexttestFixture {
- public static void main(String[] args) {
- System.out.println("OMGHAI!");
+import lombok.extern.slf4j.Slf4j;
- Item[] items = new Item[] {
+import java.util.List;
+
+@Slf4j
+public class TextTestFixture {
+ public static void main(String[] args) {
+ log.info("OMGHAI!");
+
+ List
- items = List.of(
new Item("+5 Dexterity Vest", 10, 20), //
new Item("Aged Brie", 2, 0), //
new Item("Elixir of the Mongoose", 5, 7), //
@@ -14,22 +19,21 @@ public class TexttestFixture {
new Item("Backstage passes to a TAFKAL80ETC concert", 10, 49),
new Item("Backstage passes to a TAFKAL80ETC concert", 5, 49),
// this conjured item does not work properly yet
- new Item("Conjured Mana Cake", 3, 6) };
+ new Item("Conjured Mana Cake", 3, 6));
GildedRose app = new GildedRose(items);
- int days = 2;
+ int days = 12;
if (args.length > 0) {
days = Integer.parseInt(args[0]) + 1;
}
for (int i = 0; i < days; i++) {
- System.out.println("-------- day " + i + " --------");
- System.out.println("name, sellIn, quality");
+ log.info("-------- day {} --------", i);
+ log.info("name, sellIn, quality");
for (Item item : items) {
- System.out.println(item);
+ log.info(item.toString());
}
- System.out.println();
app.updateQuality();
}
}