Skip to content

Commit

Permalink
Add test cases for stability inference (#4163)
Browse files Browse the repository at this point in the history
Should pass since 1.5.8-beta01 compose compiler plugin
  • Loading branch information
eymar authored Jan 25, 2024
1 parent ac3ca94 commit f121805
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 2 deletions.
4 changes: 2 additions & 2 deletions compose/integrations/composable-test-cases/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
org.gradle.jvmargs=-Xmx2048M -XX:MaxMetaspaceSize=512m
kotlin.code.style=official
android.useAndroidX=true
kotlin.version=1.9.21
kotlin.version=1.9.22
agp.version=7.3.0
compose.version=1.6.0-dev1357

kotlinx.coroutines.version=1.8.0-RC

#empty by default - a default version will be used
#compose.kotlinCompilerPluginVersion=23.12.18
compose.kotlinCompilerPluginVersion=1.5.4
compose.kotlinCompilerPluginVersion=1.5.8-beta01

# default|failingJs - see enum class CasesToRun
tests.casesToRun=default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ if (casesToRun.isDefault()) {

module(":testcase-expectActual-lib", "testcases/expectActual/lib")
module(":testcase-expectActual-main", "testcases/expectActual/main")

module(":testcase-stability-lib", "testcases/stability/lib")
module(":testcase-stability-main", "testcases/stability/main")
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose")
}

kotlin {
configureTargets()

sourceSets {
val commonMain by getting {
dependencies {
implementation(compose.runtime)
implementation(getCommonLib())
}
}
val commonTest by getting {
configureCommonTestDependencies()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
data class UnstableDataClassWithPrivateVar(private var i: Int) {

fun inc() { i++ }
fun getI() = i
}


data class StableDataClassWithPrivateVal(private val i: Int)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose")
}

kotlin {
configureTargets()

sourceSets {
val commonMain by getting {
dependencies {
implementation(compose.runtime)
implementation(getCommonLib())
implementation(getLibDependencyForMain())
}
}
val commonTest by getting {
configureCommonTestDependencies()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import com.example.common.TextLeafNode
import com.example.common.composeText
import kotlinx.coroutines.Job
import kotlinx.coroutines.test.runTest
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals

class Tests {

/**
* Here we use an unstable parameter, and therefore
* we expect the Composable function will NOT skip body execution.
*/
@Test
fun testUnstableParameter() = runTest {
val i = UnstableDataClassWithPrivateVar(0)
val job = Job()

val state = mutableStateOf(0)
val root = composeText(coroutineContext + job) {
UseUnstableDataClassInstance(i)
TextLeafNode("state=" + state.value.toString())
}

assertEquals("root:{UnstableDataClassWithPrivateVar(i=0), state=0}", root.dump())
assertEquals(1, i.getI())
state.value += 1

testScheduler.advanceUntilIdle()
assertEquals("root:{UnstableDataClassWithPrivateVar(i=1), state=1}", root.dump())
assertEquals(2, i.getI())
}

@Test
fun testUnstableParameterOfLocalType() = runTest {
val i = LocalUnstableDataClassWithPrivateVar(0)
val job = Job()

val state = mutableStateOf(0)
val root = composeText(coroutineContext + job) {
UseLocalUnstableDataClassWithPrivateVar(i)
TextLeafNode("state=" + state.value.toString())
}

assertEquals("root:{LocalUnstableDataClassWithPrivateVar(i=0), state=0}", root.dump())
assertEquals(1, i.getI())
state.value += 1

testScheduler.advanceUntilIdle()
assertEquals("root:{LocalUnstableDataClassWithPrivateVar(i=1), state=1}", root.dump())
assertEquals(2, i.getI())
}

@Test
fun testStableParameter() = runTest {
val i = StableDataClassWithPrivateVal(0)
val job = Job()

val state = mutableStateOf(0)
val root = composeText(coroutineContext + job) {
UseStableDataClassWithPrivateVar(i)
TextLeafNode("state=" + state.value.toString())
}

assertEquals("root:{StableDataClassWithPrivateVal(i=0), counter=0, state=0}", root.dump())
assertEquals(1, counter)

state.value += 1
testScheduler.advanceUntilIdle()
assertEquals("root:{StableDataClassWithPrivateVal(i=0), counter=0, state=1}", root.dump())
assertEquals(1, counter)
}

@BeforeTest
fun before() {
counter = 0
}
}

private var counter = 0

@Composable
fun UseUnstableDataClassInstance(i: UnstableDataClassWithPrivateVar) {
TextLeafNode(i.toString())
i.inc()
}

@Composable
fun UseStableDataClassWithPrivateVar(i: StableDataClassWithPrivateVal) {
TextLeafNode(i.toString())
TextLeafNode("counter=$counter")
counter++
}


/**
* Same as [UnstableDataClassWithPrivateVar] but defined in the same module that a function which uses it
*/
data class LocalUnstableDataClassWithPrivateVar(private var i: Int) {
fun inc() { i++ }
fun getI() = i
}

@Composable
fun UseLocalUnstableDataClassWithPrivateVar(i: LocalUnstableDataClassWithPrivateVar) {
TextLeafNode(i.toString())
i.inc()
}

0 comments on commit f121805

Please sign in to comment.