Deliver simple, min and advanced implementations. Also test that proves each implementation works as expected

This commit is contained in:
Jacek Weremko 2024-06-16 19:54:19 +02:00
parent 87ca925990
commit e7662616ea
34 changed files with 732 additions and 67 deletions

View File

@ -64,4 +64,16 @@ During refactor I also found README file in a main directory in which algorithm
- 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.
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
![img_2.png](img_2.png)
### 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -1,5 +1,6 @@
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) {
override fun toString(): String {
return this.name + ", " + this.sellIn + ", " + this.quality

View File

@ -0,0 +1,2 @@
package com.gildedrose

View File

@ -1,8 +1,6 @@
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.*
@ -20,9 +18,9 @@ fun generateTestCasesInRanger(names: List<String>, sellInRange: IntRange, qualit
fun main(args: Array<String>) {
val names = listOf(
AGED_BRIE,
BACKSTAGE_PASSES,
LULFURAS_HAND_OF_RAGNAROK,
com.platinumrose.ItemType.AGED_BRIE.name,
com.platinumrose.ItemType.BACKSTAGE_PASSES.name,
com.platinumrose.ItemType.SULFURAS.name,
"new none-existing on code name"
)
val sellInRange = -100..100

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

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

View File

@ -0,0 +1,8 @@
package com.platinumrose
import com.gildedrose.Item
interface Solution {
fun items(): List<Item>
fun updateQuality()
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 {
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"
}
fun updateQuality() {
override fun items(): List<Item> {
return items
}
override fun updateQuality() {
for (item in items) {
when (item.name) {
AGED_BRIE -> updateQualityForAgedBrie(item)
BACKSTAGE_PASSES -> updateQualityForBackstagePasses(item)
LULFURAS_HAND_OF_RAGNAROK -> null
com.platinumrose.ItemType.AGED_BRIE.value -> updateQualityForAgedBrie(item)
com.platinumrose.ItemType.BACKSTAGE_PASSES.value -> updateQualityForBackstagePasses(item)
com.platinumrose.ItemType.SULFURAS.value -> updateQualityForSulfuras(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) {
item.quality -= 1
}
item.quality = item.quality.coerceIn(0, REGULAR_ITEM_MAX_QUALITY)
}
private fun updateQualityForAgedBrie(item: Item) {
@ -38,6 +47,7 @@ class PlatinumRose(var items: List<Item>) {
if (item.sellIn < 0) {
item.quality += 1
}
item.quality = item.quality.coerceIn(0, REGULAR_ITEM_MAX_QUALITY)
}
private fun updateQualityForBackstagePasses(item: Item) {
@ -52,5 +62,10 @@ class PlatinumRose(var items: List<Item>) {
if (item.sellIn < 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)
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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