mirror of
https://github.com/emilybache/GildedRose-Refactoring-Kata.git
synced 2026-02-18 07:51:29 +00:00
adding first set of tests: refactoring
This commit is contained in:
parent
1029dca6f6
commit
b728fca809
@ -36,7 +36,7 @@ abstract class GildedRoseBaseTest {
|
|||||||
testGildedRose(name, initialSellIn, initialQuality, numberDays, resultingSellIn, resultingQuality)
|
testGildedRose(name, initialSellIn, initialQuality, numberDays, resultingSellIn, resultingQuality)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testGildedRose(
|
private fun testGildedRose(
|
||||||
name: String,
|
name: String,
|
||||||
initialSellIn: Int,
|
initialSellIn: Int,
|
||||||
initialQuality: Int,
|
initialQuality: Int,
|
||||||
@ -48,7 +48,7 @@ abstract class GildedRoseBaseTest {
|
|||||||
val items = arrayOf(item)
|
val items = arrayOf(item)
|
||||||
val app = GildedRose(items)
|
val app = GildedRose(items)
|
||||||
|
|
||||||
(1..numberDays).forEach() {
|
(1..numberDays).forEach { _ ->
|
||||||
app.updateQuality()
|
app.updateQuality()
|
||||||
}
|
}
|
||||||
Assertions.assertThat(item.name).isEqualTo(name)
|
Assertions.assertThat(item.name).isEqualTo(name)
|
||||||
@ -56,7 +56,7 @@ abstract class GildedRoseBaseTest {
|
|||||||
Assertions.assertThat(item.quality).isEqualTo(resultingQuality)
|
Assertions.assertThat(item.quality).isEqualTo(resultingQuality)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun combinationsSource(): Stream<Arguments> = Stream.of(*combinationsToTest)
|
private fun combinationsSource(): Stream<Arguments> = Stream.of(*combinationsToTest)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,10 +1,7 @@
|
|||||||
package com.gildedrose
|
package com.gildedrose
|
||||||
|
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
import org.junit.jupiter.params.ParameterizedTest
|
|
||||||
import org.junit.jupiter.params.provider.Arguments
|
import org.junit.jupiter.params.provider.Arguments
|
||||||
import org.junit.jupiter.params.provider.MethodSource
|
|
||||||
import java.util.stream.Stream
|
|
||||||
|
|
||||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
internal class GildedRoseSulfurasTest : GildedRoseBaseTest(){
|
internal class GildedRoseSulfurasTest : GildedRoseBaseTest(){
|
||||||
|
|||||||
@ -1,70 +1,75 @@
|
|||||||
package com.gildedrose
|
package com.gildedrose
|
||||||
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
/*
|
private const val NR_TESTS_TO_RUN = 100_000 // 100.000 random tests should be enough to cover any untested cases by the normal unit tests
|
||||||
TODO:
|
private const val MAX_NR_ITEMS = 5
|
||||||
- const voor maxNrDays, MaxNrItems, MaxInitialQuality, MaxInitialQuality
|
private const val MAX_NR_DAYS = 100
|
||||||
- run als unit test, draai 1 minuut, of 1.000.000 keer
|
private const val MAX_INITIAL_QUALITY = 100
|
||||||
- comment: deze kan flaky zijn, maar bij 1.000.000 is die kans wel erg klein
|
private const val MIN_INITIAL_SELLIN = -10
|
||||||
|
private const val MAX_INITIAL_SELLIN = 100
|
||||||
*/
|
private val PRODUCTS_LIST = listOf(
|
||||||
|
|
||||||
val productLists = listOf(
|
|
||||||
"Aged Brie",
|
"Aged Brie",
|
||||||
"Sulfuras, Hand of Ragnaros",
|
"Sulfuras, Hand of Ragnaros",
|
||||||
"Backstage passes to a TAFKAL80ETC concert",
|
"Backstage passes to a TAFKAL80ETC concert",
|
||||||
"Foo"
|
"Foo"
|
||||||
)
|
)
|
||||||
|
private val random = Random(System.currentTimeMillis())
|
||||||
|
|
||||||
val random = Random(System.currentTimeMillis())
|
class RandomizedRegressionTest {
|
||||||
|
@Test
|
||||||
|
fun `test random combinations and compare the result from the legacy code with the refactored code`() {
|
||||||
|
(0..NR_TESTS_TO_RUN).forEach{
|
||||||
|
// create new random combination of items
|
||||||
|
val nrItemsToTest = random.nextInt(1,MAX_NR_ITEMS)
|
||||||
|
val nrDays = random.nextInt(1,MAX_NR_DAYS)
|
||||||
|
val initialItems = createRandomItemList(nrItemsToTest)
|
||||||
|
val legacyItems = initialItems.deepClone()
|
||||||
|
val refacturedItems = legacyItems.deepClone()
|
||||||
|
|
||||||
|
// clone the items for the legacy and the refactored implementation
|
||||||
|
val legacyApp = GildedRoseLegacy(legacyItems)
|
||||||
|
val refactoredApp = GildedRose(refacturedItems)
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
// update the quality for a number of days for both the legacy and the refactored implementation
|
||||||
(0..Int.MAX_VALUE).forEach(){
|
println("testing round $it, with $nrItemsToTest items and $nrDays days")
|
||||||
val nrItemsToTest = random.nextInt(1,5)
|
(1..nrDays).forEach { _ ->
|
||||||
val nrDays = random.nextInt(1,100)
|
legacyApp.updateQuality()
|
||||||
val initialItems = createRandomItemList(nrItemsToTest)
|
refactoredApp.updateQuality()
|
||||||
val legacyItems = initialItems.deepClone()
|
}
|
||||||
val refacturedItems = legacyItems.deepClone()
|
|
||||||
|
|
||||||
val legacyApp = GildedRoseLegacy(legacyItems)
|
// compare the result of the legacy and the refactored implementation
|
||||||
val refactoredApp = GildedRose(refacturedItems)
|
val testDescription : String = describeTestcase(initialItems, nrDays, refactoredApp.items, legacyApp.items)
|
||||||
|
val actialItemsAsString = describeItems(refactoredApp.items)
|
||||||
println("testing round $it, with $nrItemsToTest items and $nrDays days")
|
val expectedItemsAsString = describeItems(legacyApp.items)
|
||||||
(1..nrDays).forEach {
|
assertThat(actialItemsAsString).`as`("The following testcase failed: \n$testDescription").isEqualTo(expectedItemsAsString)
|
||||||
legacyApp.updateQuality()
|
|
||||||
refactoredApp.updateQuality()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val testDescription : String = describeTestcase(initialItems, nrDays, refactoredApp.items, legacyApp.items)
|
|
||||||
val actialItemsAsString = describeItems(refactoredApp.items)
|
|
||||||
val expectedItemsAsString = describeItems(legacyApp.items)
|
|
||||||
assertThat(actialItemsAsString).`as`("The following testcase failed: \n$testDescription").isEqualTo(expectedItemsAsString)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun describeTestcase(initialItems: Array<Item>, nrDays: Int, actualItems: Array<Item>, expectedItems: Array<Item>) =
|
||||||
|
"Initial items: \n${describeItems(initialItems)}\n\n"+
|
||||||
|
"expected items after $nrDays days:\n"+
|
||||||
|
"${describeItems(expectedItems)}\n\n"+
|
||||||
|
"actual items after $nrDays days:\n"+
|
||||||
|
describeItems(actualItems)
|
||||||
|
|
||||||
|
private fun describeItems(items: Array<Item>) = items.joinToString("\n") { " -${it.name}: sellIn:${it.sellIn} quality:${it.quality}" }
|
||||||
|
|
||||||
|
private fun createRandomItem(): Item{
|
||||||
|
val nameIndex = random.nextInt(PRODUCTS_LIST.size)
|
||||||
|
val name = PRODUCTS_LIST[nameIndex]
|
||||||
|
val sellIn =random.nextInt(MIN_INITIAL_SELLIN, MAX_INITIAL_SELLIN)
|
||||||
|
val quality = random.nextInt(MAX_INITIAL_QUALITY)
|
||||||
|
return Item(name,sellIn,quality)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Item.clone() = Item(name,sellIn,quality)
|
||||||
|
|
||||||
|
private fun Array<Item>.deepClone() = map { it.clone() } .toTypedArray()
|
||||||
|
|
||||||
|
private fun createRandomItemList(count: Int) = (0..count).map { createRandomItem() }.toTypedArray()
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun describeTestcase(initialItems: Array<Item>, nrDays: Int, actualItems: Array<Item>, expectedItems: Array<Item>) =
|
|
||||||
"Initial items: \n${describeItems(initialItems)}\n\n"+
|
|
||||||
"expected items after $nrDays days:\n"+
|
|
||||||
"${describeItems(expectedItems)}\n\n"+
|
|
||||||
"actual items after $nrDays days:\n"+
|
|
||||||
describeItems(actualItems)
|
|
||||||
|
|
||||||
fun describeItems(items: Array<Item>) = items.map { " -${it.name}: sellIn:${it.sellIn} quality:${it.quality}" }.joinToString("\n")
|
|
||||||
|
|
||||||
private fun createRandomItem(): Item{
|
|
||||||
val nameIndex = random.nextInt(productLists.size)
|
|
||||||
val name = productLists[nameIndex]
|
|
||||||
val sellIn =random.nextInt(-10, 100)
|
|
||||||
val quality = random.nextInt(100)
|
|
||||||
return Item(name,sellIn,quality)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Item.clone() = Item(name,sellIn,quality)
|
|
||||||
|
|
||||||
private fun Array<Item>.deepClone() = map { it.clone() } .toTypedArray()
|
|
||||||
|
|
||||||
|
|
||||||
private fun createRandomItemList(count: Int) = (0..count).map { createRandomItem() }.toTypedArray()
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user