Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added tracking for operations #147

Merged
merged 5 commits into from
Aug 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions core/src/jsMain/kotlin/dev/fritz2/tracking/tracking.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package dev.fritz2.tracking

import dev.fritz2.binding.Store
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.debounce

/**
* convenience method for creating a [Tracker]
*/
fun tracker(defaultTransaction: String = "...", debounceTimeout: Long = 100): Tracker =
Tracker(defaultTransaction, debounceTimeout)

/**
* tracks running transactions (e.g. inside a [Store])
*
* @param defaultTransaction default transactions text (used if not specified when [track] is called)
* @param debounceTimeout denounces values in the [Flow] of running transaction by this value
* @param state stores the actual running transaction or null
*/
class Tracker(
private val defaultTransaction: String,
debounceTimeout: Long,
private val state: MutableStateFlow<String?> = MutableStateFlow(null)
) : Flow<String?> by state.debounce(debounceTimeout) {

/**
* tracks a given operation
*
* @param transaction text describing the transaction
* @param operation function to track
*/
suspend fun <T> track(transaction: String = defaultTransaction, operation: suspend () -> T): T {
state.value = transaction
return operation().also { state.value = null }
}

}
73 changes: 73 additions & 0 deletions core/src/jsTest/kotlin/dev/fritz2/tracking/tracking.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package dev.fritz2.tracking

import dev.fritz2.binding.RootStore
import dev.fritz2.binding.action
import dev.fritz2.binding.handledBy
import dev.fritz2.dom.html.render
import dev.fritz2.dom.mount
import dev.fritz2.identification.uniqueId
import dev.fritz2.test.initDocument
import dev.fritz2.test.runTest
import dev.fritz2.test.targetId
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.map
import kotlin.browser.document
import kotlin.test.Test
import kotlin.test.assertEquals

class TrackingTests {


@Test
fun testTracking() = runTest {
initDocument()

val transactionText = "long running"
val transactionId = "transaction-${uniqueId()}"

val startValue = "start"
val endValue = "end"
val valueId = "value-${uniqueId()}"

val store = object : RootStore<String>(startValue) {
val running = tracker()

val longRunningHandler = handle {
running.track(transactionText) {
delay(600)
endValue
}
}
}

render {
div {
span(id = transactionId) { store.running.map { it.orEmpty() }.bind() }
span(id = valueId) { store.data.bind() }
}
}.mount(targetId)
delay(200)

action() handledBy store.longRunningHandler

val valueBeforeTransaction = document.getElementById(valueId)?.textContent
assertEquals(startValue, valueBeforeTransaction)

delay(300)

val transactionDuringHandler = document.getElementById(transactionId)?.textContent
assertEquals(transactionText, transactionDuringHandler)

val valueDuringTransaction = document.getElementById(valueId)?.textContent
assertEquals(startValue, valueDuringTransaction)

delay(450)

val transactionAfterHandler = document.getElementById(transactionId)?.textContent
assertEquals("", transactionAfterHandler)

val valueAfterTransaction = document.getElementById(valueId)?.textContent
assertEquals(endValue, valueAfterTransaction)

}
}