Created
May 24, 2025 08:22
-
-
Save krishofmans/10d86bb46444e7bae92872bc3d7e3ba8 to your computer and use it in GitHub Desktop.
My solution so far for the inventory kata
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package io.tripled.backtothefuture | |
| import io.kotest.core.spec.style.FunSpec | |
| import io.kotest.matchers.shouldBe | |
| import java.time.LocalDateTime | |
| import java.time.temporal.ChronoUnit | |
| class InventoryKata : FunSpec( { | |
| val today = LocalDateTime.now() | |
| val yesterday = today.minus(1, ChronoUnit.DAYS) | |
| val tomorrow = today.plus(1, ChronoUnit.DAYS) | |
| test("adding things to the inventory through time") { | |
| val inventory = Inventory() | |
| inventory.add(today, "π") | |
| inventory.add(today, "π₯") | |
| inventory.add(tomorrow, "π") | |
| inventory.project(yesterday) shouldBe "" | |
| inventory.project(today) shouldBe "ππ₯" | |
| inventory.project(tomorrow) shouldBe "ππ₯π" | |
| } | |
| test("removing things impacts the inventory"){ | |
| val inventory = Inventory() | |
| inventory.add(today, "π"); | |
| inventory.add(today, "π₯"); | |
| inventory.remove(tomorrow, "π"); | |
| inventory.project(yesterday) shouldBe "" | |
| inventory.project(today) shouldBe "ππ₯" | |
| inventory.project(tomorrow) shouldBe "π₯" | |
| } | |
| test("grouping items"){ | |
| val inventory = Inventory() | |
| val future = tomorrow | |
| inventory.add(today, "π"); | |
| inventory.add(today, "π₯"); | |
| inventory.add(today, "π"); | |
| inventory.add(today, "π"); | |
| inventory.project(future) shouldBe "ππ₯ππ" | |
| inventory.group(tomorrow, listOf("π₯", "π")); | |
| inventory.project(future) shouldBe "π|π₯π|π" | |
| } | |
| }) | |
| class Inventory { | |
| private val inventory = mutableListOf<InventoryEvent>() | |
| fun add(momentInTime: LocalDateTime, product: String) { | |
| inventory.add(InventoryEventAdded(momentInTime, SingleItem(product))) | |
| } | |
| fun project(momentInTime: LocalDateTime): String { | |
| val finalState = mutableListOf<Item>() | |
| inventory.sortBy { it.momentInTime } | |
| val eventsSoFar = | |
| inventory.filter { beforeOrAtTheSameTime(it, momentInTime) }.toList() | |
| for (event in eventsSoFar) { | |
| when (event) { | |
| is InventoryEventAdded -> { | |
| finalState.add(event.item) | |
| } | |
| is InventoryEventRemoved -> { | |
| finalState.remove(event.item) | |
| } | |
| is InventoryGroupAdded -> { | |
| finalState.add(event.item) | |
| //finalState.removeAll(event.item.presentation.split("")) | |
| } | |
| } | |
| } | |
| return finalState.joinToString("") { it.presentation } | |
| } | |
| private fun beforeOrAtTheSameTime( | |
| event: InventoryEvent, | |
| momentInTime: LocalDateTime, | |
| ): Boolean = event.momentInTime.isBefore(momentInTime) || momentInTime == event.momentInTime | |
| fun remove(momentInTime: LocalDateTime, product: String) { | |
| inventory.add(InventoryEventRemoved(momentInTime, SingleItem(product))) | |
| } | |
| fun group(momentInTime: LocalDateTime, groupOfProducts: List<String>) { | |
| inventory.add(InventoryGroupAdded(momentInTime, GroupedItem(groupOfProducts))) | |
| } | |
| sealed interface InventoryEvent { | |
| val momentInTime: LocalDateTime | |
| val item: Item | |
| } | |
| class InventoryEventAdded(override val momentInTime: LocalDateTime, override val item: Item) : InventoryEvent | |
| class InventoryEventRemoved(override val momentInTime: LocalDateTime, override val item: Item) : InventoryEvent | |
| class InventoryGroupAdded( | |
| override val momentInTime: LocalDateTime, | |
| override val item: Item, | |
| ) : InventoryEvent | |
| sealed interface Item { | |
| val presentation: String | |
| } | |
| data class SingleItem(val product: String) : Item { | |
| override val presentation: String | |
| get() = product | |
| } | |
| data class GroupedItem(val groupOfProducts: List<String>) : Item { | |
| override val presentation: String | |
| get() = "|${groupOfProducts.joinToString("" ) { it }}|" | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment