Browse Source

[web] use common test api in benchmark-core

BENCHMARKS_USING_CORE_API
Shagen Ogandzhanian 3 years ago
parent
commit
de5f4433f8
  1. 1
      web/benchmark-core/build.gradle.kts
  2. 15
      web/benchmark-core/src/jsTest/kotlin/BenchmarkTests.kt
  3. 29
      web/benchmark-core/src/jsTest/kotlin/TestUtils.kt

1
web/benchmark-core/build.gradle.kts

@ -35,6 +35,7 @@ kotlin {
val jsTest by getting { val jsTest by getting {
dependencies { dependencies {
implementation(project(":test-utils"))
implementation(kotlin("test-js")) implementation(kotlin("test-js"))
} }
} }

15
web/benchmark-core/src/jsTest/kotlin/BenchmarkTests.kt

@ -4,6 +4,9 @@ import kotlinx.browser.window
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
import org.jetbrains.compose.web.testutils.ComposeWebExperimentalTestsApi
import org.jetbrains.compose.web.testutils.TestScope
import org.jetbrains.compose.web.testutils.runTest
import org.w3c.dom.get import org.w3c.dom.get
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -13,6 +16,7 @@ import kotlin.time.ExperimentalTime
import kotlin.time.measureTime import kotlin.time.measureTime
@OptIn(ExperimentalTime::class) @OptIn(ExperimentalTime::class)
@ComposeWebExperimentalTestsApi
class BenchmarkTests { class BenchmarkTests {
private fun flowRepeat(count: Int, calculate: suspend () -> Duration): Flow<Duration> { private fun flowRepeat(count: Int, calculate: suspend () -> Duration): Flow<Duration> {
@ -48,7 +52,7 @@ class BenchmarkTests {
suspend private fun TestScope.addNItems(n: Int): Duration { suspend private fun TestScope.addNItems(n: Int): Duration {
val addItemsCount = mutableStateOf(0) val addItemsCount = mutableStateOf(0)
val composition = composition { composition {
AddItems(addItemsCount.value) AddItems(addItemsCount.value)
} }
@ -60,7 +64,6 @@ class BenchmarkTests {
} }
assertEquals(n, root.childElementCount) assertEquals(n, root.childElementCount)
composition.dispose()
return duration return duration
} }
@ -89,7 +92,7 @@ class BenchmarkTests {
fun remove1000Items() = runBenchmark("remove1000Items") { fun remove1000Items() = runBenchmark("remove1000Items") {
val addItemsCount = mutableStateOf(1000) val addItemsCount = mutableStateOf(1000)
val composition = composition { composition {
AddItems(addItemsCount.value) AddItems(addItemsCount.value)
} }
@ -101,7 +104,6 @@ class BenchmarkTests {
} }
assertEquals(0, root.childElementCount) assertEquals(0, root.childElementCount)
composition.dispose()
duration duration
} }
@ -111,7 +113,7 @@ class BenchmarkTests {
val items = mutableStateListOf<String>() val items = mutableStateListOf<String>()
items.addAll(generateSequence(0) { it + 1 }.map { it.toString() }.take(1000)) items.addAll(generateSequence(0) { it + 1 }.map { it.toString() }.take(1000))
val composition = composition { composition {
AddItems(items) AddItems(items)
} }
@ -129,14 +131,13 @@ class BenchmarkTests {
repeat(items.size) { repeat(items.size) {
if (it % 10 == 0) items[it] = "${items[it]}-$it" if (it % 10 == 0) items[it] = "${items[it]}-$it"
} }
waitForAnimationFrame() waitForAnimationFrame()
assertEquals(1000, root.childElementCount) assertEquals(1000, root.childElementCount)
assertEquals("1", root.children[1]!!.firstChild!!.textContent) assertEquals("1", root.children[1]!!.firstChild!!.textContent)
assertEquals("10-10", root.children[10]!!.firstChild!!.textContent) assertEquals("10-10", root.children[10]!!.firstChild!!.textContent)
composition.dispose()
duration duration
} }
} }

29
web/benchmark-core/src/jsTest/kotlin/TestUtils.kt

@ -17,35 +17,6 @@ import org.w3c.dom.MutationObserverInit
import kotlin.coroutines.resume import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine import kotlin.coroutines.suspendCoroutine
private val testScope = MainScope()
class TestScope : CoroutineScope by testScope {
val root = "div".asHtmlElement()
fun composition(content: @Composable () -> Unit): Composition {
root.clear()
return renderComposable(root) {
content()
}
}
suspend fun waitChanges() {
waitForChanges(root)
}
}
internal fun runTest(block: suspend TestScope.() -> Unit): dynamic {
val scope = TestScope()
return scope.promise { block(scope) }
}
internal fun runBlockingTest(
block: suspend CoroutineScope.() -> Unit
): dynamic = testScope.promise { this.block() }
internal fun String.asHtmlElement() = document.createElement(this) as HTMLElement
/* Currently, the recompositionRunner relies on AnimationFrame to run the recomposition and /* Currently, the recompositionRunner relies on AnimationFrame to run the recomposition and
applyChanges. Therefore we can use this method after updating the state and before making applyChanges. Therefore we can use this method after updating the state and before making
assertions. assertions.

Loading…
Cancel
Save