Skip to content

Commit

Permalink
Create mosaic-testing module (#528)
Browse files Browse the repository at this point in the history
  • Loading branch information
EpicDima authored Jan 3, 2025
1 parent 313db47 commit 321290f
Show file tree
Hide file tree
Showing 27 changed files with 142 additions and 40 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
New:
- Create `mosaic-animation` library, that provides various possibilities for animating Mosaic. An analog of [androidx.compose.animation-core](https://developer.android.com/reference/kotlin/androidx/compose/animation/core/package-summary).
- Add `IntrinsicSize` and related `Modifier.width/height/requiredWidth/requiredHeight`.
- New `mosaic-testing` artifact for testing Mosaic.

Changed:
- Rendering now occurs as fast as possible, although still only when necessary. Previously the maximum FPS was capped to 20 which could cause minor visual delays when processing events.
Expand Down
1 change: 1 addition & 0 deletions mosaic-runtime/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ kotlin {
}
commonTest {
dependencies {
implementation projects.mosaicTesting
implementation libs.kotlin.test
implementation libs.kotlinx.coroutines.test
implementation libs.assertk
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.jakewharton.mosaic

import assertk.assertThat
import assertk.assertions.isEqualTo
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.Column
import com.jakewharton.mosaic.ui.Row
import com.jakewharton.mosaic.ui.Static
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import assertk.assertThat
import assertk.assertions.isEqualTo
import com.jakewharton.mosaic.layout.width
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.testing.TestMosaic
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.Alignment
import com.jakewharton.mosaic.ui.Box
import com.jakewharton.mosaic.ui.Column
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import assertk.assertions.isNotNull
import assertk.assertions.message
import com.jakewharton.mosaic.layout.drawBehind
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.Layout
import com.jakewharton.mosaic.ui.Row
import com.jakewharton.mosaic.ui.Static
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import assertk.assertThat
import assertk.assertions.isEqualTo
import com.jakewharton.mosaic.layout.drawBehind
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.Column
import com.jakewharton.mosaic.ui.Layout
import com.jakewharton.mosaic.ui.Row
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.jakewharton.mosaic.layout.offset
import com.jakewharton.mosaic.layout.size
import com.jakewharton.mosaic.layout.width
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.Box
import com.jakewharton.mosaic.ui.Column
import com.jakewharton.mosaic.ui.Filler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import com.jakewharton.mosaic.NodeSnapshots
import com.jakewharton.mosaic.TestFiller
import com.jakewharton.mosaic.assertFailure
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.runMosaicTest
import com.jakewharton.mosaic.size
import com.jakewharton.mosaic.testIntrinsics
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.Layout
import com.jakewharton.mosaic.ui.unit.Constraints
import com.jakewharton.mosaic.ui.unit.IntSize
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import com.jakewharton.mosaic.ConstrainedBox
import com.jakewharton.mosaic.NodeSnapshots
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.position
import com.jakewharton.mosaic.runMosaicTest
import com.jakewharton.mosaic.size
import com.jakewharton.mosaic.testIntrinsics
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.Box
import com.jakewharton.mosaic.ui.Column
import com.jakewharton.mosaic.ui.Layout
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import com.jakewharton.mosaic.TestChar
import com.jakewharton.mosaic.TestFiller
import com.jakewharton.mosaic.assertFailure
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.runMosaicTest
import com.jakewharton.mosaic.s
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.Box
import com.jakewharton.mosaic.ui.unit.IntOffset
import kotlin.test.Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import com.jakewharton.mosaic.TestChar
import com.jakewharton.mosaic.TestFiller
import com.jakewharton.mosaic.assertFailure
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.runMosaicTest
import com.jakewharton.mosaic.s
import com.jakewharton.mosaic.testIntrinsics
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.Layout
import com.jakewharton.mosaic.ui.unit.Constraints
import kotlin.test.Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import com.jakewharton.mosaic.Container
import com.jakewharton.mosaic.NodeSnapshots
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.position
import com.jakewharton.mosaic.runMosaicTest
import com.jakewharton.mosaic.size
import com.jakewharton.mosaic.testIntrinsics
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.Alignment
import com.jakewharton.mosaic.ui.Box
import com.jakewharton.mosaic.ui.Column
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.jakewharton.mosaic

import com.jakewharton.mosaic.layout.MosaicNode
import com.jakewharton.mosaic.testing.SnapshotStrategy

internal object DumpSnapshots : SnapshotStrategy<String> {
override fun create(mosaic: Mosaic): String {
return mosaic.dump()
}
}

internal object NodeSnapshots : SnapshotStrategy<MosaicNode> {
override fun create(mosaic: Mosaic): MosaicNode {
return (mosaic as MosaicComposition).rootNode
}
}

internal class RenderingSnapshots(
private val rendering: Rendering,
) : SnapshotStrategy<String> {
override fun create(mosaic: Mosaic): String {
return rendering.render(mosaic).toString()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.jakewharton.mosaic.layout.MeasureScope
import com.jakewharton.mosaic.layout.MosaicNode
import com.jakewharton.mosaic.layout.Placeable
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.Alignment
import com.jakewharton.mosaic.ui.Filler
import com.jakewharton.mosaic.ui.Layout
Expand Down Expand Up @@ -53,7 +54,7 @@ inline fun TestFiller(modifier: Modifier = Modifier) {
}

@Composable
fun Container(
internal fun Container(
modifier: Modifier = Modifier,
alignment: Alignment = Alignment.Center,
expanded: Boolean = false,
Expand Down Expand Up @@ -158,7 +159,7 @@ suspend fun testIntrinsics(
}

@Composable
internal fun ConstrainedBox(
fun ConstrainedBox(
constraints: Constraints,
modifier: Modifier = Modifier,
content: @Composable () -> Unit = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ import com.jakewharton.mosaic.layout.size
import com.jakewharton.mosaic.layout.width
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.position
import com.jakewharton.mosaic.runMosaicTest
import com.jakewharton.mosaic.s
import com.jakewharton.mosaic.size
import com.jakewharton.mosaic.testIntrinsics
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.unit.Constraints
import com.jakewharton.mosaic.ui.unit.IntOffset
import com.jakewharton.mosaic.ui.unit.IntSize
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import com.jakewharton.mosaic.layout.padding
import com.jakewharton.mosaic.layout.size
import com.jakewharton.mosaic.layout.width
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.runMosaicTest
import com.jakewharton.mosaic.s
import com.jakewharton.mosaic.size
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.unit.Constraints
import com.jakewharton.mosaic.ui.unit.IntSize
import kotlin.test.Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import com.jakewharton.mosaic.layout.width
import com.jakewharton.mosaic.layout.wrapContentHeight
import com.jakewharton.mosaic.layout.wrapContentWidth
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.runMosaicTest
import com.jakewharton.mosaic.testing.runMosaicTest
import kotlin.test.Test
import kotlinx.coroutines.test.runTest

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import com.jakewharton.mosaic.layout.widthIn
import com.jakewharton.mosaic.layout.wrapContentSize
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.position
import com.jakewharton.mosaic.runMosaicTest
import com.jakewharton.mosaic.size
import com.jakewharton.mosaic.testIntrinsics
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.unit.Constraints
import com.jakewharton.mosaic.ui.unit.IntOffset
import com.jakewharton.mosaic.ui.unit.IntSize
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import com.jakewharton.mosaic.layout.height
import com.jakewharton.mosaic.layout.size
import com.jakewharton.mosaic.layout.width
import com.jakewharton.mosaic.modifier.Modifier
import com.jakewharton.mosaic.runMosaicTest
import com.jakewharton.mosaic.s
import com.jakewharton.mosaic.size
import com.jakewharton.mosaic.testing.runMosaicTest
import com.jakewharton.mosaic.ui.unit.Constraints
import com.jakewharton.mosaic.ui.unit.IntSize
import kotlin.test.Test
Expand Down
14 changes: 14 additions & 0 deletions mosaic-testing/api/mosaic-testing.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
public abstract interface class com/jakewharton/mosaic/testing/SnapshotStrategy {
public abstract fun create (Lcom/jakewharton/mosaic/Mosaic;)Ljava/lang/Object;
}

public abstract interface class com/jakewharton/mosaic/testing/TestMosaic : com/jakewharton/mosaic/Mosaic {
public abstract fun awaitSnapshot-VtjQ1oo (JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun awaitSnapshot-VtjQ1oo$default (Lcom/jakewharton/mosaic/testing/TestMosaic;JLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
}

public final class com/jakewharton/mosaic/testing/TestMosaicKt {
public static final fun runMosaicTest (Lcom/jakewharton/mosaic/testing/SnapshotStrategy;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final fun runMosaicTest (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

21 changes: 21 additions & 0 deletions mosaic-testing/api/mosaic-testing.klib.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Klib ABI Dump
// Targets: [linuxArm64, linuxX64, macosArm64, macosX64, mingwX64]
// Rendering settings:
// - Signature version: 2
// - Show manifest properties: true
// - Show declarations: true

// Library unique name: <com.jakewharton.mosaic:mosaic-testing>
abstract fun interface <#A: kotlin/Any?> com.jakewharton.mosaic.testing/SnapshotStrategy { // com.jakewharton.mosaic.testing/SnapshotStrategy|null[0]
abstract fun create(com.jakewharton.mosaic/Mosaic): #A // com.jakewharton.mosaic.testing/SnapshotStrategy.create|create(com.jakewharton.mosaic.Mosaic){}[0]
}

abstract interface <#A: kotlin/Any?> com.jakewharton.mosaic.testing/TestMosaic : com.jakewharton.mosaic/Mosaic { // com.jakewharton.mosaic.testing/TestMosaic|null[0]
abstract suspend fun awaitSnapshot(kotlin.time/Duration = ...): #A // com.jakewharton.mosaic.testing/TestMosaic.awaitSnapshot|awaitSnapshot(kotlin.time.Duration){}[0]
}

final val com.jakewharton.mosaic.testing/com_jakewharton_mosaic_testing_PlainTextSnapshots$stableprop // com.jakewharton.mosaic.testing/com_jakewharton_mosaic_testing_PlainTextSnapshots$stableprop|#static{}com_jakewharton_mosaic_testing_PlainTextSnapshots$stableprop[0]

final fun com.jakewharton.mosaic.testing/com_jakewharton_mosaic_testing_PlainTextSnapshots$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.testing/com_jakewharton_mosaic_testing_PlainTextSnapshots$stableprop_getter|com_jakewharton_mosaic_testing_PlainTextSnapshots$stableprop_getter(){}[0]
final suspend fun <#A: kotlin/Any?, #B: kotlin/Any?> com.jakewharton.mosaic.testing/runMosaicTest(com.jakewharton.mosaic.testing/SnapshotStrategy<#A>, kotlin.coroutines/SuspendFunction1<com.jakewharton.mosaic.testing/TestMosaic<#A>, #B>): #B // com.jakewharton.mosaic.testing/runMosaicTest|runMosaicTest(com.jakewharton.mosaic.testing.SnapshotStrategy<0:0>;kotlin.coroutines.SuspendFunction1<com.jakewharton.mosaic.testing.TestMosaic<0:0>,0:1>){0§<kotlin.Any?>;1§<kotlin.Any?>}[0]
final suspend fun com.jakewharton.mosaic.testing/runMosaicTest(kotlin.coroutines/SuspendFunction1<com.jakewharton.mosaic.testing/TestMosaic<kotlin/String>, kotlin/Unit>) // com.jakewharton.mosaic.testing/runMosaicTest|runMosaicTest(kotlin.coroutines.SuspendFunction1<com.jakewharton.mosaic.testing.TestMosaic<kotlin.String>,kotlin.Unit>){}[0]
21 changes: 21 additions & 0 deletions mosaic-testing/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apply plugin: 'org.jetbrains.kotlin.multiplatform'
apply plugin: 'org.jetbrains.kotlin.plugin.compose'
apply from: "$rootDir/addAllTargets.gradle"
apply from: "$rootDir/publish.gradle"
apply plugin: 'dev.drewhamilton.poko'

kotlin {
explicitApi()

sourceSets {
commonMain {
dependencies {
api projects.mosaicRuntime
api libs.kotlinx.coroutines.core
implementation libs.compose.collection
}
}
}

compilerOptions.freeCompilerArgs.add('-Xexpect-actual-classes')
}
2 changes: 2 additions & 0 deletions mosaic-testing/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
POM_ARTIFACT_ID=mosaic-testing
POM_NAME=Mosaic testing
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package com.jakewharton.mosaic
package com.jakewharton.mosaic.testing

import androidx.collection.MutableObjectList
import androidx.compose.runtime.BroadcastFrameClock
import androidx.compose.runtime.Composable
import com.jakewharton.mosaic.Mosaic
import com.jakewharton.mosaic.TextCanvas
import com.jakewharton.mosaic.layout.KeyEvent
import com.jakewharton.mosaic.layout.MosaicNode
import com.jakewharton.mosaic.ui.AnsiLevel
import kotlin.coroutines.CoroutineContext
import kotlin.time.Duration
Expand All @@ -13,15 +14,15 @@ import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.withTimeout

internal fun interface SnapshotStrategy<T> {
fun create(mosaic: Mosaic): T
public fun interface SnapshotStrategy<T> {
public fun create(mosaic: Mosaic): T
}

internal suspend fun runMosaicTest(block: suspend TestMosaic<String>.() -> Unit) {
public suspend fun runMosaicTest(block: suspend TestMosaic<String>.() -> Unit) {
runMosaicTest(PlainTextSnapshots, block)
}

internal suspend fun <T, R> runMosaicTest(
public suspend fun <T, R> runMosaicTest(
snapshotStrategy: SnapshotStrategy<T>,
block: suspend TestMosaic<T>.() -> R,
): R {
Expand All @@ -36,8 +37,8 @@ internal suspend fun <T, R> runMosaicTest(
}
}

internal interface TestMosaic<T> : Mosaic {
suspend fun awaitSnapshot(duration: Duration = 1.seconds): T
public interface TestMosaic<T> : Mosaic {
public suspend fun awaitSnapshot(duration: Duration = 1.seconds): T
}

private class RealTestMosaic<T>(
Expand Down Expand Up @@ -107,23 +108,3 @@ internal object PlainTextSnapshots : SnapshotStrategy<String> {
return mosaic.paint().render(AnsiLevel.NONE)
}
}

internal object DumpSnapshots : SnapshotStrategy<String> {
override fun create(mosaic: Mosaic): String {
return mosaic.dump()
}
}

internal object NodeSnapshots : SnapshotStrategy<MosaicNode> {
override fun create(mosaic: Mosaic): MosaicNode {
return (mosaic as MosaicComposition).rootNode
}
}

internal class RenderingSnapshots(
private val rendering: Rendering,
) : SnapshotStrategy<String> {
override fun create(mosaic: Mosaic): String {
return rendering.render(mosaic).toString()
}
}
8 changes: 8 additions & 0 deletions samples/counter/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ kotlin {
implementation projects.mosaicRuntime
}
}
commonTest {
dependencies {
implementation projects.mosaicTesting
implementation libs.kotlin.test
implementation libs.kotlinx.coroutines.test
implementation libs.assertk
}
}
}

targets.withType(KotlinNativeTarget).configureEach { target ->
Expand Down
21 changes: 21 additions & 0 deletions samples/counter/src/commonTest/kotlin/example/CounterTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package example

import assertk.assertThat
import assertk.assertions.isEqualTo
import com.jakewharton.mosaic.testing.runMosaicTest
import kotlin.test.Test
import kotlinx.coroutines.test.runTest

class CounterTest {
@Test
fun counter() = runTest {
runMosaicTest {
setContent {
Counter()
}
for (count in 0..20) {
assertThat(awaitSnapshot()).isEqualTo("The count is: $count")
}
}
}
}
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ rootProject.name = 'mosaic'
include ':mosaic-animation'
include ':mosaic-runtime'
include ':mosaic-terminal'
include ':mosaic-testing'

include ':samples:counter'
include ':samples:demo'
Expand Down

0 comments on commit 321290f

Please sign in to comment.