Skip to content

Commit

Permalink
feat(sandbox): Add a custom android sandbox (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
warnyul authored Mar 13, 2024
1 parent 91069a1 commit 18b9da1
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 4 deletions.
1 change: 0 additions & 1 deletion robolectric-extension/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import org.robolectric.gradle.AarDepsPlugin

plugins {
alias(libs.plugins.kotlinJvm)

}

apply plugin: AarDepsPlugin
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package tech.apter.junit.jupiter.robolectric.internal

import java.util.concurrent.Callable
import java.util.concurrent.ExecutionException
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.ThreadFactory
import org.robolectric.util.Util

internal object AndroidMainThreadExecutor {
private val executorService: ExecutorService = Executors.newSingleThreadExecutor(mainThreadFactory())

fun <T : Any?> execute(callable: Callable<T>): T {
val future = executorService.submit(callable)
try {
return future.get()
} catch (e: InterruptedException) {
future.cancel(true)
throw RuntimeException(e)
} catch (e: ExecutionException) {
throw Util.sneakyThrow<RuntimeException>(e.cause)
}
}

fun shutdown() = executorService.shutdown()

private fun mainThreadFactory(): ThreadFactory {
return ThreadFactory { r: Runnable? ->
val name = "Android SDK"
Thread(ThreadGroup(name), r, "$name Main Thread")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package tech.apter.junit.jupiter.robolectric.internal

import java.util.concurrent.Callable
import org.robolectric.ApkLoader
import org.robolectric.annotation.SQLiteMode
import org.robolectric.internal.AndroidSandbox
import org.robolectric.internal.ResourcesMode
import org.robolectric.internal.bytecode.ShadowProviders
import org.robolectric.pluginapi.Sdk

internal class JUnit5RobolectricAndroidSandbox(
runtimeSdk: Sdk,
compileSdk: Sdk,
resourcesMode: ResourcesMode,
apkLoader: ApkLoader,
testEnvironmentSpec: TestEnvironmentSpec,
sdkSandboxClassLoader: SdkSandboxClassLoader,
shadowProviders: ShadowProviders,
sqLiteMode: SQLiteMode.Mode,
) : AndroidSandbox(
runtimeSdk,
compileSdk,
resourcesMode,
apkLoader,
testEnvironmentSpec,
sdkSandboxClassLoader,
shadowProviders,
sqLiteMode,
) {
override fun <T : Any?> runOnMainThread(callable: Callable<T>): T =
AndroidMainThreadExecutor.execute(callable)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ internal class JUnit5RobolectricSandboxBuilder @Inject constructor(
resourcesMode: ResourcesMode,
sqLiteMode: SQLiteMode.Mode,
): AndroidSandbox {
logger.trace { "build" }
val sdkSandboxClassLoader = getOrCreateClassLoader(instrumentationConfig, runtimeSdk)
return AndroidSandbox(
return JUnit5RobolectricAndroidSandbox(
runtimeSdk,
compileSdk,
resourcesMode,
Expand All @@ -46,7 +47,7 @@ internal class JUnit5RobolectricSandboxBuilder @Inject constructor(
instrumentationConfig: InstrumentationConfiguration,
runtimeSdk: Sdk,
): SdkSandboxClassLoader {
val key = Key(instrumentationConfig, runtimeSdk, classInstrumentor)
val key = Key(instrumentationConfig, runtimeSdk)
return classLoaderCache.getOrPut(key) {
logger.debug { "${SdkSandboxClassLoader::class.simpleName} instance created for $key." }
SdkSandboxClassLoader(instrumentationConfig, runtimeSdk, classInstrumentor)
Expand All @@ -56,7 +57,6 @@ internal class JUnit5RobolectricSandboxBuilder @Inject constructor(
private data class Key(
private val configuration: InstrumentationConfiguration,
private val runtimeSdk: Sdk,
private val classInstrumentor: ClassInstrumentor,
)

private companion object {
Expand Down

0 comments on commit 18b9da1

Please sign in to comment.