raniejade
08/13/2019, 4:42 AMsuspend operator fun getValue/setValue
)gildor
08/13/2019, 4:56 AMMarko Mitic
08/13/2019, 5:06 AMgildor
08/13/2019, 5:08 AMgildor
08/13/2019, 5:08 AMraniejade
08/13/2019, 5:30 AMCoroutineContext.Element
to implement memoized
values.gildor
08/13/2019, 5:33 AMgildor
08/13/2019, 5:33 AMgildor
08/13/2019, 5:33 AMraniejade
08/13/2019, 5:40 AMmemoized
values are unique per test so it's not only calculated once, hence why I'm using delegates here.gildor
08/13/2019, 5:41 AMraniejade
08/13/2019, 5:48 AMclass Memoized<T>(private val name: String,
private val constructor: () -> T,
private val destructor: (T) -> Unit) {
private var value: T? = null
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
return checkNotNull(value)
}
// called before a test is executed
fun init() {
value = constructor()
}
// called after a test is executed
fun destroy() {
destructor(checkNotNull(value))
value = null
}
}
gildor
08/13/2019, 5:50 AMraniejade
08/13/2019, 5:50 AMthis is just getter property, so it can be replaced with functionNot sure what you mean by this
gildor
08/13/2019, 5:54 AMraniejade
08/13/2019, 5:56 AMval a by memoized { ... }
test("test #1") {
// a is a different instance
}
test("test #2") {
// a is a different instance
}
raniejade
08/13/2019, 5:59 AMcoroutineContext
and the property delegate will just look it up or set/remove it.
class Memoized<T>(private val name: String,
private val constructor: () -> T,
private val destructor: (T) -> Unit) {
suspend operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
return valueFrom(name, coroutineContext)
}
// called before a test is executed
suspend fun init() {
setValue(name, coroutineContext, constructor())
}
// called after a test is executed
suspend fun destroy() {
destructor(removeValue(name, coroutineContext))
}
}
Then each test will be executed with a different coroutineContext
.gildor
08/13/2019, 6:01 AMsuspend operator fun getValue()
? why not just suspend fun getValue()
. Because it’s property delegate, right? If it will be just an object it will be possible, again, you just cannot have suspend property, as result suspend operator getValue
has no senseraniejade
08/13/2019, 6:03 AMval a by memoized { ... }
test("some test") { print(a) }
vs
val a = memoized()
test("some test") { print(a.get()) }
raniejade
08/13/2019, 6:03 AMprint(a())
gildor
08/13/2019, 6:03 AMgildor
08/13/2019, 6:03 AMraniejade
08/13/2019, 6:05 AMThreadLocal
but unique per coroutineContext instead of per thread.gildor
08/13/2019, 6:06 AMgildor
08/13/2019, 6:08 AMraniejade
08/13/2019, 6:13 AMval cachedPerGroup by memoized (CachingMode.EACH_GROUP) { ... }
group("group #1") { // launch(newCoroutineContext()) { ... }
// cachedPerGroup instance #1
group("group #2") { // launch(newCoroutineContext()) { ... }
// cachedPerGroup instance #2
test("test in group #2") { print(cachedPerGroup) }
}
test("test in group #1") { print(cachedPerGroup) }
}