main.tech.apter.junit.jupiter.robolectric.internal.JUnit5MavenDependencyResolver.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of robolectric-extension Show documentation
Show all versions of robolectric-extension Show documentation
This repository aims to bridge the gap between JUnit 5 and Robolectric,
enabling developers to leverage the benefits of both frameworks
for unit testing Android applications. While Robolectric currently lacks
a dedicated JUnit 5 extension, this project proposes a community-driven solution to
achieve seamless integration.
The newest version!
package tech.apter.junit.jupiter.robolectric.internal
import org.robolectric.MavenRoboSettings
import org.robolectric.internal.dependency.DependencyJar
import org.robolectric.internal.dependency.MavenArtifactFetcher
import org.robolectric.internal.dependency.MavenDependencyResolver
import org.robolectric.internal.dependency.MavenJarArtifact
import java.io.File
import java.io.IOException
import java.io.RandomAccessFile
import java.net.MalformedURLException
import java.net.URL
import java.util.concurrent.ExecutorService
internal class JUnit5MavenDependencyResolver private constructor(
repositoryUrl: String,
repositoryId: String,
repositoryUserName: String?,
repositoryPassword: String?,
proxyHost: String?,
proxyPort: Int,
) : MavenDependencyResolver(repositoryUrl, repositoryId, repositoryUserName, repositoryPassword, proxyHost, proxyPort) {
constructor() : this(
MavenRoboSettings.getMavenRepositoryUrl(),
MavenRoboSettings.getMavenRepositoryId(),
MavenRoboSettings.getMavenRepositoryUserName(),
MavenRoboSettings.getMavenRepositoryPassword(),
MavenRoboSettings.getMavenProxyHost(),
MavenRoboSettings.getMavenProxyPort(),
)
private val executorService: ExecutorService = createExecutorService()
private val mavenArtifactFetcher: MavenArtifactFetcher = createMavenFetcher(
repositoryUrl,
repositoryUserName,
repositoryPassword,
proxyHost,
proxyPort,
localRepositoryDir,
executorService,
)
override fun getLocalArtifactUrls(vararg dependencies: DependencyJar): Array {
val artifacts: List> = dependencies.map { it to MavenJarArtifact(it) }
for ((dependencyJar, artifact) in artifacts) {
if (!File(localRepositoryDir, artifact.jarPath()).exists()) {
whileLocked(dependencyJar) {
mavenArtifactFetcher.fetchArtifact(artifact)
}
}
}
val urls = arrayOfNulls(dependencies.size)
try {
for (i in artifacts.indices) {
val artifact = artifacts[i].second
urls[i] = File(localRepositoryDir, artifact.jarPath()).toURI().toURL()
}
} catch (e: MalformedURLException) {
throw AssertionError(e)
}
return urls
}
private fun createLockFile(dependencyJar: DependencyJar): File {
val lockFileName = dependencyJar.shortName.replace(SPECIAL_CHARACTERS_IN_FILE_NAME_REGEX.toRegex(), "_")
return File(System.getProperty("user.home"), "$lockFileName.lock")
}
@Suppress("NestedBlockDepth")
private fun whileLocked(dependencyJar: DependencyJar, runnable: Runnable) {
val lockFile = createLockFile(dependencyJar)
try {
RandomAccessFile(lockFile, "rw").use { raf ->
raf.channel.use { channel ->
channel.lock().use {
runnable.run()
}
}
}
} catch (e: IOException) {
throw IllegalStateException("Couldn't create lock file $lockFile", e)
} finally {
lockFile.delete()
}
}
private companion object {
private const val SPECIAL_CHARACTERS_IN_FILE_NAME_REGEX = """[<>:"\\/|\?\*]"""
}
}