Adjusted test classes

This commit is contained in:
Brage Skjønborg 2026-01-31 17:35:49 +01:00
parent 9ba7b9ed26
commit dd40f7f726
10 changed files with 37 additions and 42 deletions

View File

@ -8,7 +8,6 @@ import no.iktdev.eventi.events.EventListenerRegistry
import no.iktdev.eventi.events.EventTypeRegistry import no.iktdev.eventi.events.EventTypeRegistry
import no.iktdev.eventi.models.DeleteEvent import no.iktdev.eventi.models.DeleteEvent
import no.iktdev.eventi.models.Event import no.iktdev.eventi.models.Event
import no.iktdev.eventi.models.Metadata
import no.iktdev.eventi.testUtil.wipe import no.iktdev.eventi.testUtil.wipe
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertEquals
@ -34,9 +33,6 @@ class EventDispatcherTest : TestBase() {
class TriggerEvent : Event() class TriggerEvent : Event()
class OtherEvent : Event() class OtherEvent : Event()
class DummyEvent : Event() { class DummyEvent : Event() {
fun putMetadata(metadata: Metadata) {
this.metadata = metadata
}
} }
@BeforeEach @BeforeEach
@ -61,7 +57,7 @@ class EventDispatcherTest : TestBase() {
skal kun én ny event produseres og prosessen stoppe skal kun én ny event produseres og prosessen stoppe
""") """)
fun shouldProduceOneEventAndStop() { fun shouldProduceOneEventAndStop() {
val listener = ProducingListener() ProducingListener()
val trigger = TriggerEvent() val trigger = TriggerEvent()
dispatcher.dispatch(trigger.referenceId, listOf(trigger)) dispatcher.dispatch(trigger.referenceId, listOf(trigger))
@ -71,7 +67,7 @@ class EventDispatcherTest : TestBase() {
val event = produced!!.toEvent() val event = produced!!.toEvent()
assertThat(event!!.metadata.derivedFromId).hasSize(1) assertThat(event!!.metadata.derivedFromId).hasSize(1)
assertThat(event!!.metadata.derivedFromId).contains(trigger.eventId) assertThat(event.metadata.derivedFromId).contains(trigger.eventId)
assertTrue(event is DerivedEvent) assertTrue(event is DerivedEvent)
} }
@ -82,14 +78,14 @@ class EventDispatcherTest : TestBase() {
skal ikke DerivedEvent produseres nytt skal ikke DerivedEvent produseres nytt
""") """)
fun shouldSkipAlreadyDerivedEvents() { fun shouldSkipAlreadyDerivedEvents() {
val listener = ProducingListener() ProducingListener()
val trigger = TriggerEvent() val trigger = TriggerEvent()
val derived = DerivedEvent().derivedOf(trigger).toPersisted(1L, MyTime.utcNow()) val derived = DerivedEvent().derivedOf(trigger).toPersisted(1L, MyTime.utcNow())
eventStore.persist(derived!!.toEvent()!!) // simulate prior production eventStore.persist(derived!!.toEvent()!!) // simulate prior production
dispatcher.dispatch(trigger.referenceId, listOf(trigger, derived!!.toEvent()!!)) dispatcher.dispatch(trigger.referenceId, listOf(trigger, derived.toEvent()!!))
assertEquals(1, eventStore.all().size) assertEquals(1, eventStore.all().size)
} }
@ -117,7 +113,7 @@ class EventDispatcherTest : TestBase() {
skal ikke DerivedEvent produseres nytt skal ikke DerivedEvent produseres nytt
""") """)
fun shouldBehaveDeterministicallyAcrossReplays() { fun shouldBehaveDeterministicallyAcrossReplays() {
val listener = ProducingListener() ProducingListener()
val trigger = TriggerEvent() val trigger = TriggerEvent()
dispatcher.dispatch(trigger.referenceId, listOf(trigger)) dispatcher.dispatch(trigger.referenceId, listOf(trigger))
@ -173,8 +169,8 @@ class EventDispatcherTest : TestBase() {
""") """)
fun shouldDeliverDeleteEventToListenersThatReactToIt() { fun shouldDeliverDeleteEventToListenersThatReactToIt() {
val received = mutableListOf<Event>() val received = mutableListOf<Event>()
val listener = object : EventListener() { object : EventListener() {
override fun onEvent(event: Event, context: List<Event>): Event? { override fun onEvent(event: Event, history: List<Event>): Event? {
if (event is DeleteEvent) received += event if (event is DeleteEvent) received += event
return null return null
} }
@ -193,7 +189,7 @@ class EventDispatcherTest : TestBase() {
skal ikke original-eventen leveres som kandidat igjen skal ikke original-eventen leveres som kandidat igjen
""") """)
fun shouldNotRedeliverEventsThatHaveProducedDerivedEvents() { fun shouldNotRedeliverEventsThatHaveProducedDerivedEvents() {
val listener = ProducingListener() ProducingListener()
val trigger = TriggerEvent() val trigger = TriggerEvent()
// Første dispatch: trigger produserer en DerivedEvent // Første dispatch: trigger produserer en DerivedEvent
@ -228,7 +224,7 @@ class EventDispatcherTest : TestBase() {
var receivedHistory: List<Event> = emptyList() var receivedHistory: List<Event> = emptyList()
val listener = object : EventListener() { object : EventListener() {
override fun onEvent(event: Event, history: List<Event>): Event? { override fun onEvent(event: Event, history: List<Event>): Event? {
receivedHistory = history receivedHistory = history
return null return null
@ -256,7 +252,7 @@ class EventDispatcherTest : TestBase() {
var receivedHistory: List<Event> = emptyList() var receivedHistory: List<Event> = emptyList()
val listener = object : EventListener() { object : EventListener() {
override fun onEvent(event: Event, history: List<Event>): Event? { override fun onEvent(event: Event, history: List<Event>): Event? {
receivedHistory = history receivedHistory = history
return null return null
@ -285,7 +281,7 @@ class EventDispatcherTest : TestBase() {
var receivedEvent: Event? = null var receivedEvent: Event? = null
var receivedHistory: List<Event> = emptyList() var receivedHistory: List<Event> = emptyList()
val listener = object : EventListener() { object : EventListener() {
override fun onEvent(event: Event, history: List<Event>): Event? { override fun onEvent(event: Event, history: List<Event>): Event? {
receivedEvent = event receivedEvent = event
receivedHistory = history receivedHistory = history
@ -302,15 +298,15 @@ class EventDispatcherTest : TestBase() {
// --- Test helpers --- // --- Test helpers ---
class ProducingListener : EventListener() { class ProducingListener : EventListener() {
override fun onEvent(event: Event, context: List<Event>): Event? { override fun onEvent(event: Event, history: List<Event>): Event? {
return if (event is TriggerEvent) DerivedEvent().derivedOf(event) else null return if (event is TriggerEvent) DerivedEvent().derivedOf(event) else null
} }
} }
class ContextCapturingListener : EventListener() { class ContextCapturingListener : EventListener() {
var context: List<Event> = emptyList() var context: List<Event> = emptyList()
override fun onEvent(event: Event, context: List<Event>): Event? { override fun onEvent(event: Event, history: List<Event>): Event? {
this.context = context this.context = history
return null return null
} }
} }

View File

@ -8,7 +8,6 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout import kotlinx.coroutines.withTimeout
import no.iktdev.eventi.EventDispatcherTest
import no.iktdev.eventi.EventDispatcherTest.DerivedEvent import no.iktdev.eventi.EventDispatcherTest.DerivedEvent
import no.iktdev.eventi.EventDispatcherTest.OtherEvent import no.iktdev.eventi.EventDispatcherTest.OtherEvent
import no.iktdev.eventi.EventDispatcherTest.TriggerEvent import no.iktdev.eventi.EventDispatcherTest.TriggerEvent
@ -65,7 +64,7 @@ class EventPollerImplementationTest : TestBase() {
EventListenerRegistry.registerListener( EventListenerRegistry.registerListener(
object : EventListener() { object : EventListener() {
override fun onEvent(event: Event, context: List<Event>): Event? { override fun onEvent(event: Event, history: List<Event>): Event? {
dispatched += event.referenceId dispatched += event.referenceId
completionMap[event.referenceId]?.complete(Unit) completionMap[event.referenceId]?.complete(Unit)
return null return null
@ -133,7 +132,7 @@ class EventPollerImplementationTest : TestBase() {
EventTypeRegistry.register(listOf(TriggerEvent::class.java)) EventTypeRegistry.register(listOf(TriggerEvent::class.java))
object : EventListener() { object : EventListener() {
override fun onEvent(event: Event, context: List<Event>): Event? { override fun onEvent(event: Event, history: List<Event>): Event? {
received += event received += event
if (received.size == 3) done.complete(Unit) if (received.size == 3) done.complete(Unit)
return null return null
@ -186,7 +185,7 @@ class EventPollerImplementationTest : TestBase() {
val handled = mutableListOf<Event>() val handled = mutableListOf<Event>()
object : EventListener() { object : EventListener() {
override fun onEvent(event: Event, context: List<Event>): Event? { override fun onEvent(event: Event, history: List<Event>): Event? {
if (event !is EchoEvent) return null if (event !is EchoEvent) return null
handled += event handled += event
channel.trySend(event) channel.trySend(event)

View File

@ -1,7 +1,7 @@
@file:OptIn(ExperimentalCoroutinesApi::class)
package no.iktdev.eventi.events package no.iktdev.eventi.events
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.test.* import kotlinx.coroutines.test.*
import no.iktdev.eventi.InMemoryEventStore import no.iktdev.eventi.InMemoryEventStore
@ -9,9 +9,6 @@ import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import java.util.UUID import java.util.UUID
import kotlinx.coroutines.*
import no.iktdev.eventi.MyTime
import no.iktdev.eventi.ZDS.toPersisted
import no.iktdev.eventi.models.Event import no.iktdev.eventi.models.Event
import no.iktdev.eventi.models.Metadata import no.iktdev.eventi.models.Metadata
import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.DisplayName
@ -89,7 +86,7 @@ class RunSimulationTestTest {
} }
} }
private fun persistEvent(ref: UUID, time: Instant) { private fun persistEvent(ref: UUID) {
val e = TestEvent().withReference(ref) val e = TestEvent().withReference(ref)
store.persist(e.setMetadata(Metadata())) store.persist(e.setMetadata(Metadata()))
} }
@ -102,9 +99,8 @@ class RunSimulationTestTest {
""") """)
fun pollerUpdatesLastSeenTimeWhenDispatchHappens() = runTest(testDispatcher) { fun pollerUpdatesLastSeenTimeWhenDispatchHappens() = runTest(testDispatcher) {
val ref = UUID.randomUUID() val ref = UUID.randomUUID()
val t = Instant.parse("2026-01-22T12:00:00Z")
persistEvent(ref, t) persistEvent(ref)
poller.pollOnce() poller.pollOnce()
advanceUntilIdle() advanceUntilIdle()
@ -149,9 +145,8 @@ class RunSimulationTestTest {
""") """)
fun pollerDoesNotDoubleDispatch() = runTest(testDispatcher) { fun pollerDoesNotDoubleDispatch() = runTest(testDispatcher) {
val ref = UUID.randomUUID() val ref = UUID.randomUUID()
val t = Instant.parse("2026-01-22T12:00:00Z")
persistEvent(ref, t) persistEvent(ref)
poller.pollOnce() poller.pollOnce()
advanceUntilIdle() advanceUntilIdle()
@ -171,10 +166,9 @@ class RunSimulationTestTest {
fun pollerHandlesMultipleReferenceIds() = runTest(testDispatcher) { fun pollerHandlesMultipleReferenceIds() = runTest(testDispatcher) {
val refA = UUID.randomUUID() val refA = UUID.randomUUID()
val refB = UUID.randomUUID() val refB = UUID.randomUUID()
val t = Instant.parse("2026-01-22T12:00:00Z")
persistEvent(refA, t) persistEvent(refA)
persistEvent(refB, t.plusSeconds(1)) persistEvent(refB)
poller.pollOnce() poller.pollOnce()
advanceUntilIdle() advanceUntilIdle()
@ -191,10 +185,9 @@ class RunSimulationTestTest {
fun pollerHandlesIdenticalTimestamps() = runTest(testDispatcher) { fun pollerHandlesIdenticalTimestamps() = runTest(testDispatcher) {
val refA = UUID.randomUUID() val refA = UUID.randomUUID()
val refB = UUID.randomUUID() val refB = UUID.randomUUID()
val t = Instant.parse("2026-01-22T12:00:00Z")
persistEvent(refA, t) persistEvent(refA)
persistEvent(refB, t) persistEvent(refB)
poller.pollOnce() poller.pollOnce()
advanceUntilIdle() advanceUntilIdle()
@ -242,9 +235,8 @@ class RunSimulationTestTest {
fun pollerProcessesEventsArrivingWhileQueueBusy() = runTest(testDispatcher) { fun pollerProcessesEventsArrivingWhileQueueBusy() = runTest(testDispatcher) {
val ref = UUID.randomUUID() val ref = UUID.randomUUID()
val t1 = Instant.parse("2026-01-22T12:00:00Z") val t1 = Instant.parse("2026-01-22T12:00:00Z")
val t2 = t1.plusSeconds(5)
persistEvent(ref, t1) persistEvent(ref)
val controlledQueue = ControlledDispatchQueue(scope) val controlledQueue = ControlledDispatchQueue(scope)
controlledQueue.busyRefs += ref controlledQueue.busyRefs += ref
@ -261,7 +253,7 @@ class RunSimulationTestTest {
controlledQueue.busyRefs.clear() controlledQueue.busyRefs.clear()
// Add new event // Add new event
persistEvent(ref, t2) persistEvent(ref)
// Poll #2: should dispatch both events // Poll #2: should dispatch both events
poller.pollOnce() poller.pollOnce()

View File

@ -51,7 +51,7 @@ class SequenceDispatchQueueTest : TestBase() {
EventListenerRegistry.registerListener( EventListenerRegistry.registerListener(
object : EventListener() { object : EventListener() {
override fun onEvent(event: Event, context: List<Event>): Event? { override fun onEvent(event: Event, history: List<Event>): Event? {
dispatched += event.referenceId dispatched += event.referenceId
Thread.sleep(50) // simuler tung prosessering Thread.sleep(50) // simuler tung prosessering
return null return null

View File

@ -1,5 +1,6 @@
package no.iktdev.eventi.events.poller package no.iktdev.eventi.events.poller
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.* import kotlinx.coroutines.test.*
import no.iktdev.eventi.InMemoryEventStore import no.iktdev.eventi.InMemoryEventStore
import no.iktdev.eventi.MyTime import no.iktdev.eventi.MyTime
@ -23,6 +24,7 @@ import org.assertj.core.api.Assertions.assertThat
import java.time.Duration import java.time.Duration
@ExperimentalCoroutinesApi
@DisplayName(""" @DisplayName("""
EventPollerImplementation start-loop EventPollerImplementation start-loop
Når polleren kjører i en kontrollert test-loop Når polleren kjører i en kontrollert test-loop

View File

@ -1,5 +1,6 @@
package no.iktdev.eventi.events.poller package no.iktdev.eventi.events.poller
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.advanceTimeBy
import no.iktdev.eventi.events.EventDispatcher import no.iktdev.eventi.events.EventDispatcher
@ -9,6 +10,7 @@ import no.iktdev.eventi.stores.EventStore
import java.time.Instant import java.time.Instant
import java.util.UUID import java.util.UUID
@ExperimentalCoroutinesApi
class TestablePoller( class TestablePoller(
eventStore: EventStore, eventStore: EventStore,
dispatchQueue: SequenceDispatchQueue, dispatchQueue: SequenceDispatchQueue,

View File

@ -13,6 +13,7 @@ fun EventListenerRegistry.wipe() {
// Tøm mapen // Tøm mapen
val mutableList = field.get(EventListenerRegistry) as MutableList<*> val mutableList = field.get(EventListenerRegistry) as MutableList<*>
@Suppress("UNCHECKED_CAST")
(mutableList as MutableList<Class<out EventListener>>).clear() (mutableList as MutableList<Class<out EventListener>>).clear()
// Verifiser at det er tomt // Verifiser at det er tomt

View File

@ -13,6 +13,7 @@ fun EventTypeRegistry.wipe() {
// Tøm mapen // Tøm mapen
val typesMap = field.get(EventTypeRegistry) as MutableMap<*, *> val typesMap = field.get(EventTypeRegistry) as MutableMap<*, *>
@Suppress("UNCHECKED_CAST")
(typesMap as MutableMap<String, Class<out Event>>).clear() (typesMap as MutableMap<String, Class<out Event>>).clear()
// Verifiser at det er tomt // Verifiser at det er tomt

View File

@ -15,6 +15,7 @@ fun TaskListenerRegistry.wipe() {
// Tøm mapen // Tøm mapen
val mutableList = field.get(TaskListenerRegistry) as MutableList<*> val mutableList = field.get(TaskListenerRegistry) as MutableList<*>
@Suppress("UNCHECKED_CAST")
(mutableList as MutableList<Class<out TaskListener>>).clear() (mutableList as MutableList<Class<out TaskListener>>).clear()
// Verifiser at det er tomt // Verifiser at det er tomt

View File

@ -15,6 +15,7 @@ fun TaskTypeRegistry.wipe() {
// Tøm mapen // Tøm mapen
val typesMap = field.get(TaskTypeRegistry) as MutableMap<*, *> val typesMap = field.get(TaskTypeRegistry) as MutableMap<*, *>
@Suppress("UNCHECKED_CAST")
(typesMap as MutableMap<String, Class<out Task>>).clear() (typesMap as MutableMap<String, Class<out Task>>).clear()
// Verifiser at det er tomt // Verifiser at det er tomt