Skip to content

Commit

Permalink
Merge branch 'android-handler-funcs'
Browse files Browse the repository at this point in the history
  • Loading branch information
janseeger committed Nov 8, 2023
2 parents 289064e + 0d09275 commit 7fe8ee9
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 1 deletion.
12 changes: 12 additions & 0 deletions dachlatten-compose/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
plugins {
id("android-library-base")
id("android-library-unit-test")
id("android-library-robolectric-test")
id("android-library-release")
}

dependencies {
implementation(libs.compose.ui)
}

android {
composeOptions {
kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get()
}

buildFeatures {
compose = true
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package de.sipgate.dachlatten.compose

import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext

// This provides a parameterless handlerFunc that can be
// passed around and invoked from anywhere. It will keep a
// reference to the Context given during its creation.
// Warning:
// Depending on the situation this can easily leak the Context!

typealias AndroidClickHandler = context (ContextProvider) () -> Unit

@Composable
inline fun withContext(crossinline target: AndroidClickHandler): ClickHandler {
return LocalContext.current.withContext(target)
}

@Composable
inline fun <reified T, R> withContext(
crossinline target: context (ContextProvider)
(T) -> R,
): (T) -> R = LocalContext.current.withContext(target)

inline fun <reified T, R> Context.withContext(
crossinline target: context (ContextProvider)
(T) -> R,
): (T) -> R = { param ->
with(ContextProviderImpl(this)) {
target.invoke(this, param)
}
}

inline fun <R> Context.withContext(
crossinline target: context (ContextProvider)
() -> R,
): () -> R = {
with(ContextProviderImpl(this)) {
target(this)
}
}
38 changes: 38 additions & 0 deletions dachlatten-compose/src/test/kotlin/AndroidHandlerFuncTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package de.sipgate.dachlatten.compose

import org.junit.Test
import org.junit.jupiter.api.Assertions
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment

@RunWith(RobolectricTestRunner::class)
class AndroidHandlerFuncTest {

@Test
fun testAndroidHandlerFuncWillReceiveAContext() {
val context = RuntimeEnvironment.getApplication().applicationContext
val handlerFunc = context.withContext(::someFunctionThatAccessesTheAndroidContext)

handlerFunc.invoke()
}

@Test
fun testAndroidHandlerFuncWillReceiveAContextAndReturnValueIsPassedBack() {
val context = RuntimeEnvironment.getApplication().applicationContext
val handlerFunc = context.withContext(::someFunctionThatAccessesTheAndroidContextAndReturnsSomething)

val result = handlerFunc.invoke()
Assertions.assertTrue(result.isNotEmpty())
}

context (ContextProvider)
private fun someFunctionThatAccessesTheAndroidContext() {
context.packageName
}

context (ContextProvider)
private fun someFunctionThatAccessesTheAndroidContextAndReturnsSomething(): String {
return context.packageName
}
}
3 changes: 2 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ turbine = "1.0.0"
annotation-jvm = "1.7.0"
androidx-lifecycle = "2.6.2"
robolectric = "4.10.3"
compose = "1.5.3"
compose = "1.5.4"
compose-compiler = "1.5.4"

[libraries]
coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutines" }
Expand Down

0 comments on commit 7fe8ee9

Please sign in to comment.