Skip to content

Commit

Permalink
Merge pull request #20 from Trendyol/singular-router
Browse files Browse the repository at this point in the history
Singular Router Implementation to remove redundant TestRouter
  • Loading branch information
yigitozgumus authored Aug 5, 2024
2 parents 0963853 + cacd929 commit 787ccbd
Show file tree
Hide file tree
Showing 25 changed files with 288 additions and 213 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.trendyol.transmission.features.colorpicker.ColorPickerTransformer
import com.trendyol.transmission.features.input.InputTransformer
import com.trendyol.transmission.features.multioutput.MultiOutputTransformer
import com.trendyol.transmission.features.output.OutputTransformer
import com.trendyol.transmission.router.builder.TransmissionRouterBuilder
import com.trendyol.transmission.transformer.Transformer
import dagger.Binds
import dagger.Module
Expand Down Expand Up @@ -42,7 +43,9 @@ interface FeaturesModule {
fun provideRouter(
transformerSet: @JvmSuppressWildcards Set<Transformer>
): TransmissionRouter {
return TransmissionRouter(transformerSet)
return TransmissionRouterBuilder.build {
withTransformerSet(transformerSet)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import com.trendyol.transmission.transformer.handler.registerSignal
import com.trendyol.transmission.transformer.request.buildComputationContract
import com.trendyol.transmission.transformer.request.buildComputationContractWithArgs
import com.trendyol.transmission.transformer.request.buildDataContract
import com.trendyol.transmission.transformer.request.computation.ComputationRegistry
import com.trendyol.transmission.transformer.request.computation.computationRegistry
import com.trendyol.transmission.transformer.request.computation.registerComputation
import com.trendyol.transmission.ui.InputUiState
import kotlinx.coroutines.CoroutineDispatcher
Expand All @@ -24,14 +26,14 @@ class InputTransformer @Inject constructor(

private val holder = buildDataHolder(InputUiState(), holderContract)

init {
computationRegistry
.registerComputation(writtenInputContract) {
delay(1.seconds)
WrittenInput(holder.getValue().writtenText)
}.registerComputation(writtenInputWithArgs) {
WrittenInput(it)
}
override val computationRegistry: ComputationRegistry = computationRegistry {
registerComputation(writtenInputContract) {
delay(1.seconds)
WrittenInput(holder.getValue().writtenText)
}
registerComputation(writtenInputWithArgs) {
WrittenInput(it)
}
}

override val handlerRegistry: HandlerRegistry = handlerRegistry {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import com.trendyol.transmission.transformer.handler.handlerRegistry
import com.trendyol.transmission.transformer.handler.registerEffect
import com.trendyol.transmission.transformer.request.buildComputationContract
import com.trendyol.transmission.transformer.request.buildExecutionContract
import com.trendyol.transmission.transformer.request.computation.ComputationRegistry
import com.trendyol.transmission.transformer.request.computation.computationRegistry
import com.trendyol.transmission.transformer.request.computation.registerComputation
import com.trendyol.transmission.transformer.request.execution.ExecutionRegistry
import com.trendyol.transmission.transformer.request.execution.executionRegistry
import com.trendyol.transmission.transformer.request.execution.registerExecution
import com.trendyol.transmission.ui.ColorPickerUiState
import com.trendyol.transmission.ui.OutputUiState
Expand All @@ -34,24 +38,25 @@ class OutputTransformer @Inject constructor(

private val holder2 = buildDataHolder(ColorPickerUiState(), publishUpdates = false)

init {
computationRegistry
.registerComputation(outputCalculationContract) {
delay(2.seconds)
val data = getData(ColorPickerTransformer.holderContract)?.selectedColorIndex
val writtenOutput = compute(InputTransformer.writtenInputContract)
val result = Random.nextInt(5, 15) * Random.nextInt(5, 15)
OutputCalculationResult("result is $result with ($writtenOutput) and $data")
}
executionRegistry
.registerExecution(outputExecutionContract) {
delay(4.seconds)
communicationScope.publish(ColorPickerEffect.BackgroundColorUpdate(Pink80))
throw RuntimeException(
"This exception will be properly handled and caught " +
"inside of the onError() function"
)
}
override val computationRegistry: ComputationRegistry = computationRegistry {
registerComputation(outputCalculationContract) {
delay(2.seconds)
val data = getData(ColorPickerTransformer.holderContract)?.selectedColorIndex
val writtenOutput = compute(InputTransformer.writtenInputContract)
val result = Random.nextInt(5, 15) * Random.nextInt(5, 15)
OutputCalculationResult("result is $result with ($writtenOutput) and $data")
}
}

override val executionRegistry: ExecutionRegistry = executionRegistry {
registerExecution(outputExecutionContract) {
delay(4.seconds)
communicationScope.publish(ColorPickerEffect.BackgroundColorUpdate(Pink80))
throw RuntimeException(
"This exception will be properly handled and caught " +
"inside of the onError() function"
)
}
}

override val handlerRegistry: HandlerRegistry = handlerRegistry {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@ class ColorPickerTransformerTest {
.test(signal = ColorPickerSignal.SelectColor(3, Color.Blue)) {
assertEquals(
Color.Blue.copy(alpha = 0.1f),
(effectStream.first().effect as ColorPickerEffect.BackgroundColorUpdate).color
(effectStream.first() as ColorPickerEffect.BackgroundColorUpdate).color
)
}
}

@Test
fun `GIVEN inputTransformer, WHEN SelectColor signal is sent, THEN SelectedColorUpdate is sent to MultiOutputTransformer`() {
sut.attachToRouter().test(signal = ColorPickerSignal.SelectColor(3, Color.Blue)) {
assertTrue { effectStream.last().effect is ColorPickerEffect.SelectedColorUpdate }
assertTrue { effectStream.last() is ColorPickerEffect.SelectedColorUpdate }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class InputTransformerTest {
fun `GIVEN inputTransformer, WHEN inputUpdate signal is sent, THEN inputUpdate effect is published`() {
sut.attachToRouter()
.test(signal = InputSignal.InputUpdate("test")) {
assertEquals(InputEffect.InputUpdate("test"), effectStream.first().effect)
assertEquals(InputEffect.InputUpdate("test"), effectStream.first())
assertEquals(InputUiState("test"), dataStream.last())
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class OutputTransformerTest {
}
.test(effect = InputEffect.InputUpdate("test")) {
assertEquals(OutputUiState(outputText = "test"), dataStream[1])
assertTrue(effectStream.last().effect is RouterEffect)
assertTrue(effectStream.last() is RouterEffect)
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.trendyol.transmissiontest

import com.trendyol.transmission.Transmission
import com.trendyol.transmission.effect.EffectWrapper
import com.trendyol.transmission.TransmissionRouter
import com.trendyol.transmission.router.RegistryScope
import com.trendyol.transmission.router.builder.TransmissionTestingRouterBuilder
import com.trendyol.transmission.transformer.Transformer
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.toList
Expand All @@ -15,16 +17,16 @@ import kotlinx.coroutines.test.runTest
class TestSuite {
private var orderedInitialProcessing: List<Transmission> = emptyList()
private var transformer: Transformer? = null
private lateinit var router: TestRouter
private var registryScope: RegistryScope.() -> Unit = {}
private lateinit var router: TransmissionRouter

fun initialize(transformer: Transformer): TestSuite {
this.transformer = transformer
router = TestRouter(transformer, UnconfinedTestDispatcher())
return this
}

fun register(registry: RegistryScope.() -> Unit = {}): TestSuite {
router.registry = RegistryScopeImpl().apply(registry)
this.registryScope = registry
return this
}

Expand All @@ -39,10 +41,15 @@ class TestSuite {
transmission: Transmission,
scope: suspend TransformerTestScope.(scope: TestScope) -> Unit
) {
router = TransmissionTestingRouterBuilder.build {
withDispatcher(UnconfinedTestDispatcher())
this@TestSuite.transformer?.let { withTransformerSet(setOf(it)) }
testing(this@TestSuite.registryScope)
}

runTest {
val dataStream: MutableList<Transmission.Data> = mutableListOf()
val effectStream: MutableList<EffectWrapper> = mutableListOf()
val effectStream: MutableList<Transmission.Effect> = mutableListOf()
try {
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
router.dataStream.toList(dataStream)
Expand All @@ -52,20 +59,20 @@ class TestSuite {
}
val testScope = object : TransformerTestScope {
override val dataStream: List<Transmission.Data> = dataStream
override val effectStream: List<EffectWrapper> = effectStream
override val effectStream: List<Transmission.Effect> = effectStream
}
orderedInitialProcessing.forEach {
when (it) {
is Transmission.Data -> throw IllegalArgumentException("Transmission.Data should not be sent for processing")
is Transmission.Effect -> router.sendEffect(it)
is Transmission.Signal -> router.sendSignal(it)
is Transmission.Effect -> router.processEffect(it)
is Transmission.Signal -> router.processSignal(it)
}
transformer?.waitProcessingToFinish()
}
if (transmission is Transmission.Signal) {
router.sendSignal(transmission)
router.processSignal(transmission)
} else if (transmission is Transmission.Effect) {
router.sendEffect(transmission)
router.processEffect(transmission)
}
transformer?.waitProcessingToFinish()
testScope.scope(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import com.trendyol.transmission.effect.EffectWrapper

interface TransformerTestScope {
val dataStream: List<Transmission.Data>
val effectStream: List<EffectWrapper>
val effectStream: List<Transmission.Effect>
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.trendyol.transmission

import com.trendyol.transmission.effect.EffectWrapper
import com.trendyol.transmission.router.RegistryScopeImpl
import com.trendyol.transmission.router.RequestDelegate
import com.trendyol.transmission.router.createBroadcast
import com.trendyol.transmission.transformer.Transformer
Expand All @@ -19,9 +20,10 @@ import kotlinx.coroutines.launch
/**
* Throws [IllegalArgumentException] when supplied [Transformer] set is empty
*/
class TransmissionRouter(
class TransmissionRouter internal constructor(
internal val transformerSet: Set<Transformer>,
dispatcher: CoroutineDispatcher = Dispatchers.Default,
registryScope: RegistryScopeImpl? = null
) {

private val routerScope = CoroutineScope(SupervisorJob() + dispatcher)
Expand All @@ -36,7 +38,11 @@ class TransmissionRouter(
val effectStream: SharedFlow<Transmission.Effect> = effectBroadcast.output.map { it.effect }
.shareIn(routerScope, SharingStarted.Lazily)

private val _requestDelegate = RequestDelegate(routerScope, this@TransmissionRouter)
private val _requestDelegate = RequestDelegate(
queryScope = routerScope,
routerRef = this@TransmissionRouter,
registry = registryScope
)
val requestHelper: RequestHandler = _requestDelegate

init {
Expand All @@ -47,6 +53,10 @@ class TransmissionRouter(
signalBroadcast.producer.trySend(signal)
}

fun processEffect(effect: Transmission.Effect) {
effectBroadcast.producer.trySend(EffectWrapper(effect))
}

private fun initialize() {
require(transformerSet.isNotEmpty()) {
"transformerSet should not be empty"
Expand Down
Loading

0 comments on commit 787ccbd

Please sign in to comment.