mirror of
https://github.com/emilybache/GildedRose-Refactoring-Kata.git
synced 2026-02-10 20:21:26 +00:00
Deliver simple, min and advanced implementations. Also test that proves each implementation works as expected
This commit is contained in:
parent
87ca925990
commit
e7662616ea
@ -64,4 +64,16 @@ During refactor I also found README file in a main directory in which algorithm
|
|||||||
- quality cannot be negative
|
- quality cannot be negative
|
||||||
|
|
||||||
At this point code is readable but not so extensible because all algos are in a single class which might grow to infinity.
|
At this point code is readable but not so extensible because all algos are in a single class which might grow to infinity.
|
||||||
The usual way to handle this situation is to go with OO approach - I cannot modify Item class so I will implement new one and its specifications.
|
The usual way to handle this situation is to go with OO approach - I cannot modify Item class so I will implement new one and its specifications.
|
||||||
|
|
||||||
|
### End result
|
||||||
|
I didn't modify gliderose in order to be able to execute regression tests that compare my new implementation results with original.
|
||||||
|
I created a package platinumrose with few subpackages
|
||||||
|
- simple: is the simpleness, cleaned up implementation, no OO concepts or design-patterns
|
||||||
|
- mid: is the mid-level implementation with a separate strategies for each type of item
|
||||||
|
- advanced - is one of possible implementation of production grade code, it involves item extension methods, qualityCalculator factory, and separation of concepts. This is the only impl fuully covered by tests
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
### TODO
|
||||||
|
- I didn't cover extra case described in the main README because of other responsibilities and lack of time
|
||||||
BIN
Kotlin/img_2.png
Normal file
BIN
Kotlin/img_2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
@ -1,5 +1,6 @@
|
|||||||
package com.gildedrose
|
package com.gildedrose
|
||||||
|
|
||||||
|
// NOTE: changes to data class to make comparison (asserts) easier. If rough goblin is against it, I'm ready to die
|
||||||
data class Item(var name: String, var sellIn: Int, var quality: Int) {
|
data class Item(var name: String, var sellIn: Int, var quality: Int) {
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return this.name + ", " + this.sellIn + ", " + this.quality
|
return this.name + ", " + this.sellIn + ", " + this.quality
|
||||||
|
|||||||
2
Kotlin/src/main/kotlin/com/gildedrose/ItemExtention.kt
Normal file
2
Kotlin/src/main/kotlin/com/gildedrose/ItemExtention.kt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
package com.gildedrose
|
||||||
|
|
||||||
@ -1,8 +1,6 @@
|
|||||||
package com.gildedrose
|
package com.gildedrose
|
||||||
|
|
||||||
import com.gildedrose.PlatinumRose.Companion.AGED_BRIE
|
|
||||||
import com.gildedrose.PlatinumRose.Companion.BACKSTAGE_PASSES
|
|
||||||
import com.gildedrose.PlatinumRose.Companion.LULFURAS_HAND_OF_RAGNAROK
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
@ -20,9 +18,9 @@ fun generateTestCasesInRanger(names: List<String>, sellInRange: IntRange, qualit
|
|||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val names = listOf(
|
val names = listOf(
|
||||||
AGED_BRIE,
|
com.platinumrose.ItemType.AGED_BRIE.name,
|
||||||
BACKSTAGE_PASSES,
|
com.platinumrose.ItemType.BACKSTAGE_PASSES.name,
|
||||||
LULFURAS_HAND_OF_RAGNAROK,
|
com.platinumrose.ItemType.SULFURAS.name,
|
||||||
"new none-existing on code name"
|
"new none-existing on code name"
|
||||||
)
|
)
|
||||||
val sellInRange = -100..100
|
val sellInRange = -100..100
|
||||||
|
|||||||
9
Kotlin/src/main/kotlin/com/platinumrose/ItemConstant.kt
Normal file
9
Kotlin/src/main/kotlin/com/platinumrose/ItemConstant.kt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package com.platinumrose
|
||||||
|
|
||||||
|
class ItemConstant {
|
||||||
|
companion object {
|
||||||
|
const val MIN_QUALITY = 0
|
||||||
|
const val REGULAR_ITEM_MAX_QUALITY = 50
|
||||||
|
const val LEGENDARY_ITEM_MAX_QUALITY = 80
|
||||||
|
}
|
||||||
|
}
|
||||||
14
Kotlin/src/main/kotlin/com/platinumrose/ItemType.kt
Normal file
14
Kotlin/src/main/kotlin/com/platinumrose/ItemType.kt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package com.platinumrose
|
||||||
|
|
||||||
|
enum class ItemType(val value: String? = null) {
|
||||||
|
AGED_BRIE("Aged Brie"),
|
||||||
|
BACKSTAGE_PASSES("Backstage passes to a TAFKAL80ETC concert"),
|
||||||
|
SULFURAS("Sulfuras, Hand of Ragnaros"),
|
||||||
|
REGULAR;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun fromValue(value: String): com.platinumrose.ItemType {
|
||||||
|
return entries.find { it.value == value } ?: com.platinumrose.ItemType.REGULAR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
Kotlin/src/main/kotlin/com/platinumrose/Solution.kt
Normal file
8
Kotlin/src/main/kotlin/com/platinumrose/Solution.kt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package com.platinumrose
|
||||||
|
|
||||||
|
import com.gildedrose.Item
|
||||||
|
|
||||||
|
interface Solution {
|
||||||
|
fun items(): List<Item>
|
||||||
|
fun updateQuality()
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package com.platinumrose.advance
|
||||||
|
|
||||||
|
import com.gildedrose.Item
|
||||||
|
import com.platinumrose.ItemType.Companion.fromValue
|
||||||
|
import com.platinumrose.Solution
|
||||||
|
import com.platinumrose.advance.extention.updateQuality
|
||||||
|
import com.platinumrose.advance.factory.QualityCalculatorFactory
|
||||||
|
import com.platinumrose.advance.factory.QualityCalculatorFactoryImpl
|
||||||
|
|
||||||
|
class AdvancePlatinumRose(private val items: List<Item>) : Solution {
|
||||||
|
|
||||||
|
private val qualityCalculatorFactory: QualityCalculatorFactory = QualityCalculatorFactoryImpl()
|
||||||
|
|
||||||
|
override fun items(): List<Item> {
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateQuality() {
|
||||||
|
items.forEach {
|
||||||
|
it.updateQuality(qualityCalculatorFactory.qualityCalculator(fromValue(it.name)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.platinumrose.advance.extention
|
||||||
|
|
||||||
|
import com.gildedrose.Item
|
||||||
|
import com.platinumrose.advance.quality.QualityCalculator
|
||||||
|
|
||||||
|
|
||||||
|
fun Item.updateQuality(qualityCalculator: QualityCalculator) {
|
||||||
|
updateQualityBeforeSellInDate(qualityCalculator)
|
||||||
|
updateQualityAfterSellInDate(qualityCalculator)
|
||||||
|
coerceQuality(qualityCalculator)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Item.updateQualityBeforeSellInDate(qualityCalculator: QualityCalculator) {
|
||||||
|
val qualityIncrease =
|
||||||
|
qualityCalculator.computeQualityIncreaseBeforeSellIn(sellIn, quality)
|
||||||
|
sellIn += qualityCalculator.computeSellInDecrease(sellIn)
|
||||||
|
quality += qualityIncrease
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Item.updateQualityAfterSellInDate(qualityCalculator: QualityCalculator) {
|
||||||
|
val qualityIncrease =
|
||||||
|
if (sellIn >= 0) 0 else qualityCalculator.computeQualityIncreaseAfterSellIn(sellIn, quality)
|
||||||
|
quality += qualityIncrease
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Item.coerceQuality(qualityCalculator: QualityCalculator) {
|
||||||
|
quality = quality.coerceIn(com.platinumrose.ItemConstant.MIN_QUALITY, qualityCalculator.maxQuality())
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.platinumrose.advance.factory
|
||||||
|
|
||||||
|
import com.platinumrose.ItemType
|
||||||
|
import com.platinumrose.advance.quality.QualityCalculator
|
||||||
|
|
||||||
|
|
||||||
|
interface QualityCalculatorFactory {
|
||||||
|
fun qualityCalculator(itemType: ItemType): QualityCalculator
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package com.platinumrose.advance.factory
|
||||||
|
|
||||||
|
import com.platinumrose.ItemType
|
||||||
|
import com.platinumrose.advance.quality.*
|
||||||
|
|
||||||
|
|
||||||
|
class QualityCalculatorFactoryImpl : QualityCalculatorFactory {
|
||||||
|
private val strategies: Map<ItemType, QualityCalculator>
|
||||||
|
private val regularItem = RegularItem()
|
||||||
|
|
||||||
|
init {
|
||||||
|
val agedBrieUpdated = AgedBrie()
|
||||||
|
val backstagePasses = BackstagePasses()
|
||||||
|
val sulfuras = Sulfuras()
|
||||||
|
val strategiesList = listOf(agedBrieUpdated, backstagePasses, sulfuras)
|
||||||
|
strategies = strategiesList.associateBy { it.type() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun qualityCalculator(itemType: ItemType): QualityCalculator {
|
||||||
|
return strategies.getOrDefault(itemType, regularItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.platinumrose.advance.quality
|
||||||
|
|
||||||
|
import com.platinumrose.ItemConstant.Companion.REGULAR_ITEM_MAX_QUALITY
|
||||||
|
import com.platinumrose.ItemType.AGED_BRIE
|
||||||
|
|
||||||
|
|
||||||
|
internal class AgedBrie : QualityCalculator {
|
||||||
|
|
||||||
|
override fun type(): com.platinumrose.ItemType {
|
||||||
|
return AGED_BRIE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun maxQuality(): Int {
|
||||||
|
return REGULAR_ITEM_MAX_QUALITY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeSellInDecrease(sellIn: Int): Int {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeQualityIncreaseBeforeSellIn(sellIn: Int, quality: Int): Int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeQualityIncreaseAfterSellIn(sellIn: Int, quality: Int): Int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.platinumrose.advance.quality
|
||||||
|
|
||||||
|
import com.platinumrose.ItemConstant.Companion.REGULAR_ITEM_MAX_QUALITY
|
||||||
|
import com.platinumrose.ItemType.BACKSTAGE_PASSES
|
||||||
|
|
||||||
|
|
||||||
|
internal class BackstagePasses : QualityCalculator {
|
||||||
|
|
||||||
|
override fun type(): com.platinumrose.ItemType {
|
||||||
|
return BACKSTAGE_PASSES
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun maxQuality(): Int {
|
||||||
|
return REGULAR_ITEM_MAX_QUALITY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeSellInDecrease(sellIn: Int): Int {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeQualityIncreaseBeforeSellIn(sellIn: Int, quality: Int): Int {
|
||||||
|
return when (sellIn) {
|
||||||
|
in 0..5 -> 3
|
||||||
|
in 6..10 -> 2
|
||||||
|
else -> 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeQualityIncreaseAfterSellIn(sellIn: Int, quality: Int): Int {
|
||||||
|
return -quality
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package com.platinumrose.advance.quality
|
||||||
|
|
||||||
|
interface QualityCalculator {
|
||||||
|
|
||||||
|
fun type(): com.platinumrose.ItemType
|
||||||
|
fun maxQuality(): Int
|
||||||
|
|
||||||
|
fun computeQualityIncreaseBeforeSellIn(sellIn: Int, quality: Int): Int;
|
||||||
|
fun computeSellInDecrease(sellIn: Int): Int
|
||||||
|
fun computeQualityIncreaseAfterSellIn(sellIn: Int, quality: Int): Int;
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.platinumrose.advance.quality
|
||||||
|
|
||||||
|
import com.platinumrose.ItemConstant.Companion.REGULAR_ITEM_MAX_QUALITY
|
||||||
|
import com.platinumrose.ItemType.REGULAR
|
||||||
|
|
||||||
|
|
||||||
|
internal class RegularItem : QualityCalculator {
|
||||||
|
|
||||||
|
override fun type(): com.platinumrose.ItemType {
|
||||||
|
return REGULAR
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun maxQuality(): Int {
|
||||||
|
return REGULAR_ITEM_MAX_QUALITY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeSellInDecrease(sellIn: Int): Int {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeQualityIncreaseBeforeSellIn(sellIn: Int, quality: Int): Int {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeQualityIncreaseAfterSellIn(sellIn: Int, quality: Int): Int {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.platinumrose.advance.quality
|
||||||
|
|
||||||
|
import com.platinumrose.ItemConstant.Companion.LEGENDARY_ITEM_MAX_QUALITY
|
||||||
|
import com.platinumrose.ItemType.SULFURAS
|
||||||
|
|
||||||
|
|
||||||
|
internal class Sulfuras : QualityCalculator {
|
||||||
|
|
||||||
|
override fun type(): com.platinumrose.ItemType {
|
||||||
|
return SULFURAS
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun maxQuality(): Int {
|
||||||
|
return LEGENDARY_ITEM_MAX_QUALITY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeSellInDecrease(sellIn: Int): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeQualityIncreaseBeforeSellIn(sellIn: Int, quality: Int): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeQualityIncreaseAfterSellIn(sellIn: Int, quality: Int): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package com.platinumrose.mid
|
||||||
|
|
||||||
|
import com.gildedrose.Item
|
||||||
|
import com.platinumrose.ItemConstant.Companion.MIN_QUALITY
|
||||||
|
import com.platinumrose.Solution
|
||||||
|
import com.platinumrose.mid.strategy.*
|
||||||
|
|
||||||
|
|
||||||
|
class MidPlatinumRose(var items: List<Item>) : Solution {
|
||||||
|
private val strategies: Map<com.platinumrose.ItemType, UpdateQualityStrategy>
|
||||||
|
private val defaultStrategy = DefaultStrategy()
|
||||||
|
|
||||||
|
init {
|
||||||
|
val agedBrieStrategy = AgedBrieStrategy()
|
||||||
|
val backstagePassesStrategy = BackstagePassesStrategy()
|
||||||
|
val sulfurasStrategy = SulfurasStrategy()
|
||||||
|
val strategiesList = listOf(agedBrieStrategy, backstagePassesStrategy, sulfurasStrategy)
|
||||||
|
strategies = strategiesList.associateBy { it.type() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun items(): List<Item> {
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateQuality() {
|
||||||
|
for (item in items) {
|
||||||
|
val strategy = findUpdateQualityStrategy(item)
|
||||||
|
strategy.updateQuality(item)
|
||||||
|
item.quality = item.quality.coerceIn(MIN_QUALITY, strategy.maxQuality())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findUpdateQualityStrategy(item: Item): UpdateQualityStrategy {
|
||||||
|
return strategies.getOrDefault(com.platinumrose.ItemType.fromValue(item.name), defaultStrategy)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.platinumrose.mid.strategy
|
||||||
|
|
||||||
|
import com.gildedrose.Item
|
||||||
|
import com.platinumrose.ItemConstant.Companion.REGULAR_ITEM_MAX_QUALITY
|
||||||
|
import com.platinumrose.ItemType.AGED_BRIE
|
||||||
|
|
||||||
|
|
||||||
|
internal class AgedBrieStrategy : UpdateQualityStrategy {
|
||||||
|
|
||||||
|
override fun type(): com.platinumrose.ItemType {
|
||||||
|
return AGED_BRIE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateQuality(item: Item) {
|
||||||
|
item.quality += 1
|
||||||
|
item.sellIn -= 1
|
||||||
|
if (item.sellIn < 0) {
|
||||||
|
item.quality += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun maxQuality(): Int {
|
||||||
|
return REGULAR_ITEM_MAX_QUALITY
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package com.platinumrose.mid.strategy
|
||||||
|
|
||||||
|
import com.gildedrose.Item
|
||||||
|
import com.platinumrose.ItemConstant.Companion.REGULAR_ITEM_MAX_QUALITY
|
||||||
|
import com.platinumrose.ItemType.BACKSTAGE_PASSES
|
||||||
|
|
||||||
|
|
||||||
|
internal class BackstagePassesStrategy : UpdateQualityStrategy {
|
||||||
|
|
||||||
|
override fun type(): com.platinumrose.ItemType {
|
||||||
|
return BACKSTAGE_PASSES
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateQuality(item: Item) {
|
||||||
|
item.quality += 1
|
||||||
|
if (item.sellIn < 11) {
|
||||||
|
item.quality += 1
|
||||||
|
}
|
||||||
|
if (item.sellIn < 6) {
|
||||||
|
item.quality += 1
|
||||||
|
}
|
||||||
|
item.sellIn -= 1
|
||||||
|
if (item.sellIn < 0) {
|
||||||
|
item.quality = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun maxQuality(): Int {
|
||||||
|
return REGULAR_ITEM_MAX_QUALITY
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.platinumrose.mid.strategy
|
||||||
|
|
||||||
|
import com.gildedrose.Item
|
||||||
|
import com.platinumrose.ItemConstant.Companion.REGULAR_ITEM_MAX_QUALITY
|
||||||
|
import com.platinumrose.ItemType.REGULAR
|
||||||
|
|
||||||
|
|
||||||
|
internal class DefaultStrategy : UpdateQualityStrategy {
|
||||||
|
|
||||||
|
override fun type(): com.platinumrose.ItemType {
|
||||||
|
return REGULAR
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateQuality(item: Item) {
|
||||||
|
item.quality -= 1
|
||||||
|
item.sellIn -= 1
|
||||||
|
if (item.sellIn < 0) {
|
||||||
|
item.quality -= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun maxQuality(): Int {
|
||||||
|
return REGULAR_ITEM_MAX_QUALITY
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package com.platinumrose.mid.strategy
|
||||||
|
|
||||||
|
import com.gildedrose.Item
|
||||||
|
import com.platinumrose.ItemConstant.Companion.LEGENDARY_ITEM_MAX_QUALITY
|
||||||
|
import com.platinumrose.ItemType.SULFURAS
|
||||||
|
|
||||||
|
|
||||||
|
internal class SulfurasStrategy : UpdateQualityStrategy {
|
||||||
|
|
||||||
|
override fun type(): com.platinumrose.ItemType {
|
||||||
|
return SULFURAS
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateQuality(item: Item) {
|
||||||
|
// nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun maxQuality(): Int {
|
||||||
|
return LEGENDARY_ITEM_MAX_QUALITY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.platinumrose.mid.strategy
|
||||||
|
|
||||||
|
import com.gildedrose.Item
|
||||||
|
|
||||||
|
interface UpdateQualityStrategy {
|
||||||
|
fun type(): com.platinumrose.ItemType
|
||||||
|
fun updateQuality(item: Item)
|
||||||
|
fun maxQuality(): Int
|
||||||
|
}
|
||||||
@ -1,6 +1,9 @@
|
|||||||
package com.gildedrose
|
package com.platinumrose.simple
|
||||||
|
|
||||||
class PlatinumRose(var items: List<Item>) {
|
import com.gildedrose.Item
|
||||||
|
import com.platinumrose.Solution
|
||||||
|
|
||||||
|
class SimplePlatinumRose(var items: List<Item>) : Solution {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val MIN_QUALITY = 0
|
const val MIN_QUALITY = 0
|
||||||
@ -12,15 +15,20 @@ class PlatinumRose(var items: List<Item>) {
|
|||||||
const val LULFURAS_HAND_OF_RAGNAROK = "Sulfuras, Hand of Ragnaros"
|
const val LULFURAS_HAND_OF_RAGNAROK = "Sulfuras, Hand of Ragnaros"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateQuality() {
|
|
||||||
|
override fun items(): List<Item> {
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun updateQuality() {
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
when (item.name) {
|
when (item.name) {
|
||||||
AGED_BRIE -> updateQualityForAgedBrie(item)
|
com.platinumrose.ItemType.AGED_BRIE.value -> updateQualityForAgedBrie(item)
|
||||||
BACKSTAGE_PASSES -> updateQualityForBackstagePasses(item)
|
com.platinumrose.ItemType.BACKSTAGE_PASSES.value -> updateQualityForBackstagePasses(item)
|
||||||
LULFURAS_HAND_OF_RAGNAROK -> null
|
com.platinumrose.ItemType.SULFURAS.value -> updateQualityForSulfuras(item)
|
||||||
else -> updateQuality(item)
|
else -> updateQuality(item)
|
||||||
}
|
}
|
||||||
item.quality = item.quality.coerceIn(0, REGULAR_ITEM_MAX_QUALITY)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,6 +38,7 @@ class PlatinumRose(var items: List<Item>) {
|
|||||||
if (item.sellIn < 0) {
|
if (item.sellIn < 0) {
|
||||||
item.quality -= 1
|
item.quality -= 1
|
||||||
}
|
}
|
||||||
|
item.quality = item.quality.coerceIn(0, REGULAR_ITEM_MAX_QUALITY)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateQualityForAgedBrie(item: Item) {
|
private fun updateQualityForAgedBrie(item: Item) {
|
||||||
@ -38,6 +47,7 @@ class PlatinumRose(var items: List<Item>) {
|
|||||||
if (item.sellIn < 0) {
|
if (item.sellIn < 0) {
|
||||||
item.quality += 1
|
item.quality += 1
|
||||||
}
|
}
|
||||||
|
item.quality = item.quality.coerceIn(0, REGULAR_ITEM_MAX_QUALITY)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateQualityForBackstagePasses(item: Item) {
|
private fun updateQualityForBackstagePasses(item: Item) {
|
||||||
@ -52,5 +62,10 @@ class PlatinumRose(var items: List<Item>) {
|
|||||||
if (item.sellIn < 0) {
|
if (item.sellIn < 0) {
|
||||||
item.quality = 0
|
item.quality = 0
|
||||||
}
|
}
|
||||||
|
item.quality = item.quality.coerceIn(0, REGULAR_ITEM_MAX_QUALITY)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateQualityForSulfuras(item: Item) {
|
||||||
|
item.quality = item.quality.coerceIn(0, LEGENDARY_ITEM_MAX_QUALITY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,53 +0,0 @@
|
|||||||
package com.gildedrose
|
|
||||||
|
|
||||||
import com.gildedrose.PlatinumRose.Companion.AGED_BRIE
|
|
||||||
import com.gildedrose.PlatinumRose.Companion.BACKSTAGE_PASSES
|
|
||||||
import com.gildedrose.PlatinumRose.Companion.LULFURAS_HAND_OF_RAGNAROK
|
|
||||||
import com.gildedrose.PlatinumRose.Companion.MIN_QUALITY
|
|
||||||
import com.gildedrose.PlatinumRose.Companion.REGULAR_ITEM_MAX_QUALITY
|
|
||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class PlatinumRoseTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `should update quality for generated test cases and compare with GlidedRose`() {
|
|
||||||
val names = listOf(
|
|
||||||
AGED_BRIE,
|
|
||||||
BACKSTAGE_PASSES,
|
|
||||||
LULFURAS_HAND_OF_RAGNAROK,
|
|
||||||
"new none-existing on code name"
|
|
||||||
)
|
|
||||||
val sellInRange = -100..100
|
|
||||||
val qualityRange = MIN_QUALITY..REGULAR_ITEM_MAX_QUALITY
|
|
||||||
val allTestCases = generateTestCasesInRanger(names, sellInRange, qualityRange)
|
|
||||||
|
|
||||||
|
|
||||||
for (testCase in allTestCases) {
|
|
||||||
val platinumRose = PlatinumRose(listOf(Item(testCase.name, testCase.sellIn, testCase.quality)))
|
|
||||||
val gildedRose = GildedRose(listOf(Item(testCase.name, testCase.sellIn, testCase.quality)))
|
|
||||||
|
|
||||||
platinumRose.updateQuality()
|
|
||||||
gildedRose.updateQuality()
|
|
||||||
|
|
||||||
assertEquals(gildedRose.items, platinumRose.items)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateTestCasesInRanger(
|
|
||||||
names: List<String>,
|
|
||||||
sellInRange: IntRange,
|
|
||||||
qualityRange: IntRange
|
|
||||||
): List<Item> {
|
|
||||||
val items = LinkedList<Item>()
|
|
||||||
for (name in names) {
|
|
||||||
for (sellIn in sellInRange) {
|
|
||||||
for (quality in qualityRange) {
|
|
||||||
items.add(Item(name, sellIn, quality))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return items
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
package com.platinumrose
|
||||||
|
|
||||||
|
import com.gildedrose.GildedRose
|
||||||
|
import com.gildedrose.Item
|
||||||
|
import com.platinumrose.ItemConstant.Companion.MIN_QUALITY
|
||||||
|
import com.platinumrose.ItemConstant.Companion.REGULAR_ITEM_MAX_QUALITY
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
abstract class PlatinumRoseTestTemplate {
|
||||||
|
private val ITEMS_NAMES = listOf(
|
||||||
|
com.platinumrose.ItemType.AGED_BRIE.value!!,
|
||||||
|
com.platinumrose.ItemType.BACKSTAGE_PASSES.value!!,
|
||||||
|
com.platinumrose.ItemType.SULFURAS.value!!,
|
||||||
|
"new none-existing on code name"
|
||||||
|
)
|
||||||
|
private val SELLIN_RANGE = -100..100
|
||||||
|
private val QUALITY_RANGE = MIN_QUALITY..REGULAR_ITEM_MAX_QUALITY
|
||||||
|
|
||||||
|
|
||||||
|
fun generateTestCases(): List<Item> {
|
||||||
|
return generateTestCasesInRanger(ITEMS_NAMES, SELLIN_RANGE, QUALITY_RANGE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateQualityAndCheckResult(gildedRose: GildedRose, simplePlatinumRose: Solution) {
|
||||||
|
simplePlatinumRose.updateQuality()
|
||||||
|
gildedRose.updateQuality()
|
||||||
|
assertEquals(gildedRose.items, simplePlatinumRose.items())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateTestCasesInRanger(
|
||||||
|
names: List<String>,
|
||||||
|
sellInRange: IntRange,
|
||||||
|
qualityRange: IntRange
|
||||||
|
): List<Item> {
|
||||||
|
val items = LinkedList<Item>()
|
||||||
|
for (name in names) {
|
||||||
|
for (sellIn in sellInRange) {
|
||||||
|
for (quality in qualityRange) {
|
||||||
|
items.add(Item(name, sellIn, quality))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.platinumrose.advance
|
||||||
|
|
||||||
|
import com.gildedrose.GildedRose
|
||||||
|
import com.gildedrose.Item
|
||||||
|
import com.platinumrose.PlatinumRoseTestTemplate
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
class AdvancePlatinumRoseTest : PlatinumRoseTestTemplate() {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should update quality for generated test cases and compare with GlidedRose`() {
|
||||||
|
val allTestCases = generateTestCases()
|
||||||
|
val gildedRose = GildedRose(allTestCases.map { Item(it.name, it.sellIn, it.quality) })
|
||||||
|
val simplePlatinumRose = AdvancePlatinumRose(allTestCases.map { Item(it.name, it.sellIn, it.quality) })
|
||||||
|
updateQualityAndCheckResult(gildedRose, simplePlatinumRose)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
package com.platinumrose.advance.factory
|
||||||
|
|
||||||
|
import com.platinumrose.ItemType
|
||||||
|
import com.platinumrose.advance.quality.AgedBrie
|
||||||
|
import com.platinumrose.advance.quality.BackstagePasses
|
||||||
|
import com.platinumrose.advance.quality.RegularItem
|
||||||
|
import com.platinumrose.advance.quality.Sulfuras
|
||||||
|
import org.junit.jupiter.api.Assertions.assertInstanceOf
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
class QualityCalculatorFactoryImplTest {
|
||||||
|
|
||||||
|
private val qualityCalculatorFactory = QualityCalculatorFactoryImpl()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return expected calculator for AGED_BRIE`() {
|
||||||
|
val qualityCalculator = qualityCalculatorFactory.qualityCalculator(ItemType.AGED_BRIE)
|
||||||
|
assertInstanceOf(AgedBrie::class.java, qualityCalculator)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return expected calculator for BACKSTAGE_PASSES`() {
|
||||||
|
val qualityCalculator = qualityCalculatorFactory.qualityCalculator(ItemType.BACKSTAGE_PASSES)
|
||||||
|
assertInstanceOf(BackstagePasses::class.java, qualityCalculator)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return expected calculator for SULFURAS`() {
|
||||||
|
val qualityCalculator = qualityCalculatorFactory.qualityCalculator(ItemType.SULFURAS)
|
||||||
|
assertInstanceOf(Sulfuras::class.java, qualityCalculator)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return expected calculator for any other`() {
|
||||||
|
val qualityCalculator = qualityCalculatorFactory.qualityCalculator(ItemType.REGULAR)
|
||||||
|
assertInstanceOf(RegularItem::class.java, qualityCalculator)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
package com.platinumrose.advance.quality
|
||||||
|
|
||||||
|
import com.platinumrose.ItemConstant.Companion.REGULAR_ITEM_MAX_QUALITY
|
||||||
|
import com.platinumrose.ItemType
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
class AgedBrieTest {
|
||||||
|
|
||||||
|
private val Random = Random(Int.MAX_VALUE)
|
||||||
|
private val item = AgedBrie()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return expected type`() {
|
||||||
|
assertEquals(item.type(), ItemType.AGED_BRIE)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return expected max quality`() {
|
||||||
|
assertEquals(item.maxQuality(), REGULAR_ITEM_MAX_QUALITY)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return -1 when calculate sell in decrease`() {
|
||||||
|
assertEquals(item.computeSellInDecrease(Random.nextInt()), -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return 1 when calculate quality increase before sell in`() {
|
||||||
|
assertEquals(item.computeQualityIncreaseBeforeSellIn(Random.nextInt(), Random.nextInt()), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return 1 when calculate quality increase after sell in`() {
|
||||||
|
assertEquals(item.computeQualityIncreaseAfterSellIn(Random.nextInt(), Random.nextInt()), 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
package com.platinumrose.advance.quality
|
||||||
|
|
||||||
|
import com.platinumrose.ItemConstant.Companion.REGULAR_ITEM_MAX_QUALITY
|
||||||
|
import com.platinumrose.ItemType.BACKSTAGE_PASSES
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
class BackstagePassesTest {
|
||||||
|
|
||||||
|
private val Random = Random(0)
|
||||||
|
private val item = BackstagePasses()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return expected type`() {
|
||||||
|
assertEquals(item.type(), BACKSTAGE_PASSES)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return expected max quality`() {
|
||||||
|
assertEquals(item.maxQuality(), REGULAR_ITEM_MAX_QUALITY)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return -1 when calculate sell in decrease`() {
|
||||||
|
assertEquals(item.computeSellInDecrease(Random.nextInt()), -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return 1 when calculate quality increase before sell in and quality greater than 10`() {
|
||||||
|
assertEquals(item.computeQualityIncreaseBeforeSellIn(Random.nextInt(12, Int.MAX_VALUE), Random.nextInt()), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return 2 when calculate quality increase before sell in and quality between 6 and 10`() {
|
||||||
|
assertEquals(item.computeQualityIncreaseBeforeSellIn(6, Random.nextInt()), 2)
|
||||||
|
assertEquals(item.computeQualityIncreaseBeforeSellIn(10, Random.nextInt()), 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return 3 when calculate quality increase before sell in and quality between 0 and 5`() {
|
||||||
|
assertEquals(item.computeQualityIncreaseBeforeSellIn(0, Random.nextInt()), 3)
|
||||||
|
assertEquals(item.computeQualityIncreaseBeforeSellIn(5, Random.nextInt()), 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return negative quality when calculate quality increase after sell in`() {
|
||||||
|
val quality = Random.nextInt()
|
||||||
|
assertEquals(item.computeQualityIncreaseAfterSellIn(Random.nextInt(), quality), -quality)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
package com.platinumrose.advance.quality
|
||||||
|
|
||||||
|
import com.platinumrose.ItemConstant
|
||||||
|
import com.platinumrose.ItemType
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
class RegularItemTest {
|
||||||
|
|
||||||
|
private val Random = Random(Int.MAX_VALUE)
|
||||||
|
private val item = RegularItem()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return expected type`() {
|
||||||
|
assertEquals(item.type(), ItemType.REGULAR)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return expected max quality`() {
|
||||||
|
assertEquals(item.maxQuality(), ItemConstant.REGULAR_ITEM_MAX_QUALITY)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return -1 when calculate sell in decrease`() {
|
||||||
|
assertEquals(item.computeSellInDecrease(Random.nextInt()), -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return -1 when calculate quality increase before sell in`() {
|
||||||
|
assertEquals(item.computeQualityIncreaseBeforeSellIn(Random.nextInt(), Random.nextInt()), -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return -1 when calculate quality increase after sell in`() {
|
||||||
|
assertEquals(item.computeQualityIncreaseAfterSellIn(Random.nextInt(), Random.nextInt()), -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
package com.platinumrose.advance.quality
|
||||||
|
|
||||||
|
import com.platinumrose.ItemConstant
|
||||||
|
import com.platinumrose.ItemType
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
class SulfurasTest {
|
||||||
|
|
||||||
|
private val Random = Random(Int.MAX_VALUE)
|
||||||
|
private val item = Sulfuras()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return expected type`() {
|
||||||
|
assertEquals(item.type(), ItemType.SULFURAS)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return expected max quality`() {
|
||||||
|
assertEquals(item.maxQuality(), ItemConstant.LEGENDARY_ITEM_MAX_QUALITY)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return 0 when calculate sell in decrease`() {
|
||||||
|
assertEquals(item.computeSellInDecrease(Random.nextInt()), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return 0 when calculate quality increase before sell in`() {
|
||||||
|
assertEquals(item.computeQualityIncreaseBeforeSellIn(Random.nextInt(), Random.nextInt()), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should return 0 when calculate quality increase after sell in`() {
|
||||||
|
assertEquals(item.computeQualityIncreaseAfterSellIn(Random.nextInt(), Random.nextInt()), 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package com.platinumrose.mid
|
||||||
|
|
||||||
|
import com.gildedrose.GildedRose
|
||||||
|
import com.gildedrose.Item
|
||||||
|
import com.platinumrose.PlatinumRoseTestTemplate
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
|
||||||
|
class MidPlatinumRoseTest : PlatinumRoseTestTemplate() {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should update quality for generated test cases and compare with GlidedRose`() {
|
||||||
|
val allTestCases = generateTestCases()
|
||||||
|
val gildedRose = GildedRose(allTestCases.map { Item(it.name, it.sellIn, it.quality) })
|
||||||
|
val solution = MidPlatinumRose(allTestCases.map { Item(it.name, it.sellIn, it.quality) })
|
||||||
|
updateQualityAndCheckResult(gildedRose, solution)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.platinumrose.simple
|
||||||
|
|
||||||
|
import com.gildedrose.GildedRose
|
||||||
|
import com.gildedrose.Item
|
||||||
|
import com.platinumrose.PlatinumRoseTestTemplate
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
class SimplePlatinumRoseTest : PlatinumRoseTestTemplate() {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should update quality for generated test cases and compare with GlidedRose`() {
|
||||||
|
val allTestCases = generateTestCases()
|
||||||
|
val gildedRose = GildedRose(allTestCases.map { Item(it.name, it.sellIn, it.quality) })
|
||||||
|
val solution = SimplePlatinumRose(allTestCases.map { Item(it.name, it.sellIn, it.quality) })
|
||||||
|
updateQualityAndCheckResult(gildedRose, solution)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user