Set friend modules for android gradle test tasks
This fixes the following issues:
1. When product flavors were used, android unit tests could not refer
to internal symbols from main source set.
2. Android instrumentation tests could not refer
to internal symbols from main source set
#KT-11166 fixed
This commit is contained in:
+4
-12
@@ -73,6 +73,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractCo
|
||||
var compilerCalled: Boolean = false
|
||||
// TODO: consider more reliable approach (see usage)
|
||||
var anyClassesCompiled: Boolean = false
|
||||
var friendTaskName: String? = null
|
||||
|
||||
private val loggerInstance = Logging.getLogger(this.javaClass)
|
||||
override fun getLogger() = loggerInstance
|
||||
@@ -145,7 +146,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractCo
|
||||
|
||||
}
|
||||
|
||||
|
||||
open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
|
||||
override val compiler = K2JVMCompiler()
|
||||
override fun createBlankArgs(): K2JVMCompilerArguments = K2JVMCompilerArguments()
|
||||
@@ -154,12 +154,6 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
|
||||
// Should be SourceDirectorySet or File
|
||||
val srcDirsSources = HashSet<Any>()
|
||||
|
||||
private val testsMap = mapOf(
|
||||
"compileTestKotlin" to "compileKotlin",
|
||||
"compileDebugUnitTestKotlin" to "compileDebugKotlin",
|
||||
"compileReleaseUnitTestKotlin" to "compileReleaseKotlin"
|
||||
)
|
||||
|
||||
// TODO: find out whether we really need to be able to override destination dir here, and how it should work with destinationDir property
|
||||
private val compilerDestinationDir: String get() = if (StringUtils.isEmpty(kotlinOptions.destination)) { kotlinDestinationDir?.path.orEmpty() } else { kotlinOptions.destination }
|
||||
|
||||
@@ -209,7 +203,7 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
|
||||
args.moduleName = kotlinOptions.moduleName ?: extraProperties.getOrNull<String>("defaultModuleName")
|
||||
args.languageVersion = kotlinOptions.languageVersion
|
||||
|
||||
fun addFriendPathForTestTask(taskName: String) {
|
||||
fun addFriendPathForTestTask(taskName: String) {
|
||||
logger.kotlinDebug("try to determine the output directory of corresponding $taskName task")
|
||||
val tasks = project.getTasksByName("$taskName", false)
|
||||
logger.kotlinDebug("tasks for $taskName: ${tasks}")
|
||||
@@ -223,10 +217,8 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
|
||||
}
|
||||
}
|
||||
|
||||
testsMap.get(this.name)?.let {
|
||||
addFriendPathForTestTask(it)
|
||||
}
|
||||
|
||||
logger.kotlinDebug { "friendTaskName = $friendTaskName" }
|
||||
friendTaskName?.let { addFriendPathForTestTask(it) }
|
||||
logger.kotlinDebug("args.moduleName = ${args.moduleName}")
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
|
||||
|
||||
+10
-7
@@ -48,7 +48,8 @@ abstract class KotlinSourceSetProcessor<T : AbstractCompile>(
|
||||
val pluginName: String,
|
||||
val compileTaskNameSuffix: String,
|
||||
val taskDescription: String,
|
||||
val compilerClass: Class<T>
|
||||
val compilerClass: Class<T>,
|
||||
val tasksProvider: KotlinTasksProvider
|
||||
) {
|
||||
abstract protected fun doTargetSpecificProcessing()
|
||||
val logger = Logging.getLogger(this.javaClass)
|
||||
@@ -98,9 +99,9 @@ abstract class KotlinSourceSetProcessor<T : AbstractCompile>(
|
||||
open protected fun createKotlinCompileTask(suffix: String = ""): T {
|
||||
val name = sourceSet.getCompileTaskName(compileTaskNameSuffix) + suffix
|
||||
logger.kotlinDebug("Creating kotlin compile task $name with class $compilerClass")
|
||||
val compile = project.tasks.create(name, compilerClass)
|
||||
val compile = tasksProvider.createKotlinJVMTask(project, name)
|
||||
compile.extensions.extraProperties.set("defaultModuleName", "${project.name}-$name")
|
||||
return compile
|
||||
return compilerClass.cast(compile)
|
||||
}
|
||||
|
||||
open protected fun commonTaskConfiguration() {
|
||||
@@ -116,13 +117,14 @@ class Kotlin2JvmSourceSetProcessor(
|
||||
javaBasePlugin: JavaBasePlugin,
|
||||
sourceSet: SourceSet,
|
||||
val scriptHandler: ScriptHandler,
|
||||
val tasksProvider: KotlinTasksProvider
|
||||
tasksProvider: KotlinTasksProvider
|
||||
) : KotlinSourceSetProcessor<AbstractCompile>(
|
||||
project, javaBasePlugin, sourceSet,
|
||||
pluginName = "kotlin",
|
||||
compileTaskNameSuffix = "kotlin",
|
||||
taskDescription = "Compiles the $sourceSet.kotlin.",
|
||||
compilerClass = tasksProvider.kotlinJVMCompileTaskClass
|
||||
compilerClass = tasksProvider.kotlinJVMCompileTaskClass,
|
||||
tasksProvider = tasksProvider
|
||||
) {
|
||||
|
||||
private companion object {
|
||||
@@ -186,13 +188,14 @@ class Kotlin2JsSourceSetProcessor(
|
||||
javaBasePlugin: JavaBasePlugin,
|
||||
sourceSet: SourceSet,
|
||||
val scriptHandler: ScriptHandler,
|
||||
val tasksProvider: KotlinTasksProvider
|
||||
tasksProvider: KotlinTasksProvider
|
||||
) : KotlinSourceSetProcessor<AbstractCompile>(
|
||||
project, javaBasePlugin, sourceSet,
|
||||
pluginName = "kotlin2js",
|
||||
taskDescription = "Compiles the kotlin sources in $sourceSet to JavaScript.",
|
||||
compileTaskNameSuffix = "kotlin2Js",
|
||||
compilerClass = tasksProvider.kotlinJSCompileTaskClass
|
||||
compilerClass = tasksProvider.kotlinJSCompileTaskClass,
|
||||
tasksProvider = tasksProvider
|
||||
) {
|
||||
|
||||
val copyKotlinJsTaskName = sourceSet.getTaskName("copy", "kotlinJs")
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.initialization.dsl.ScriptHandler
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.api.logging.Logging
|
||||
import org.jetbrains.kotlin.gradle.tasks.AndroidTasksProvider
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||
|
||||
// TODO: simplify: the complicated structure is a leftover from dynamic loading of plugin core, could be significantly simplified now
|
||||
@@ -59,7 +60,7 @@ open class KotlinPluginWrapper: KotlinBasePluginWrapper() {
|
||||
}
|
||||
|
||||
open class KotlinAndroidPluginWrapper : KotlinBasePluginWrapper() {
|
||||
override fun getPlugin(pluginClassLoader: ClassLoader, scriptHandler: ScriptHandler) = KotlinAndroidPlugin(scriptHandler, KotlinTasksProvider(pluginClassLoader))
|
||||
override fun getPlugin(pluginClassLoader: ClassLoader, scriptHandler: ScriptHandler) = KotlinAndroidPlugin(scriptHandler, AndroidTasksProvider(pluginClassLoader))
|
||||
}
|
||||
|
||||
open class Kotlin2JsPluginWrapper : KotlinBasePluginWrapper() {
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin
|
||||
|
||||
import org.gradle.api.Task
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
|
||||
abstract class TaskToFriendTaskMapper {
|
||||
operator fun get(task: Task): String? =
|
||||
getFriendByName(task.name)
|
||||
|
||||
@TestOnly
|
||||
operator fun get(name: String): String? =
|
||||
getFriendByName(name)
|
||||
|
||||
protected abstract fun getFriendByName(name: String): String?
|
||||
}
|
||||
|
||||
sealed class RegexTaskToFriendTaskMapper(
|
||||
private val prefix: String,
|
||||
private val suffix: String
|
||||
) : TaskToFriendTaskMapper() {
|
||||
class Default : RegexTaskToFriendTaskMapper("compile", "TestKotlin")
|
||||
class Android : RegexTaskToFriendTaskMapper("compile", "(Unit|Android)TestKotlin")
|
||||
|
||||
private val regex = "$prefix(.*)$suffix".toRegex()
|
||||
|
||||
override fun getFriendByName(name: String): String? {
|
||||
val match = regex.matchEntire(name) ?: return null
|
||||
val variant = match.groups[1]?.value ?: ""
|
||||
return prefix + variant + "Kotlin"
|
||||
}
|
||||
}
|
||||
+1
@@ -53,6 +53,7 @@ internal fun AbstractCompile.appendClasspathDynamically(file: File) {
|
||||
|
||||
internal var AbstractTask.anyClassesCompiled: Boolean? by TaskPropertyDelegate("anyClassesCompiled")
|
||||
internal var AbstractTask.kotlinDestinationDir: File? by TaskPropertyDelegate("kotlinDestinationDir")
|
||||
internal var AbstractTask.friendTaskName: String? by TaskPropertyDelegate("friendTaskName")
|
||||
|
||||
inline
|
||||
internal fun <reified T : Any> TaskPropertyDelegate(propertyName: String) =
|
||||
|
||||
+17
-5
@@ -4,6 +4,9 @@ import org.gradle.api.tasks.compile.AbstractCompile
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.SourceTask
|
||||
import org.jetbrains.kotlin.gradle.plugin.RegexTaskToFriendTaskMapper
|
||||
import org.jetbrains.kotlin.gradle.plugin.TaskToFriendTaskMapper
|
||||
import org.jetbrains.kotlin.gradle.plugin.friendTaskName
|
||||
import java.net.URLClassLoader
|
||||
|
||||
/**
|
||||
@@ -12,7 +15,7 @@ import java.net.URLClassLoader
|
||||
* date: 17.12.2014.
|
||||
*/
|
||||
|
||||
public open class KotlinTasksProvider(val tasksLoader: ClassLoader) {
|
||||
open class KotlinTasksProvider(val tasksLoader: ClassLoader) {
|
||||
val kotlinJVMCompileTaskClass: Class<AbstractCompile> =
|
||||
tasksLoader.loadClass("org.jetbrains.kotlin.gradle.tasks.KotlinCompile") as Class<AbstractCompile>
|
||||
|
||||
@@ -22,12 +25,21 @@ public open class KotlinTasksProvider(val tasksLoader: ClassLoader) {
|
||||
val kotlinJVMOptionsClass: Class<Any> =
|
||||
tasksLoader.loadClass("org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments") as Class<Any>
|
||||
|
||||
|
||||
public fun createKotlinJVMTask(project: Project, name: String): AbstractCompile {
|
||||
return project.tasks.create(name, kotlinJVMCompileTaskClass)
|
||||
fun createKotlinJVMTask(project: Project, name: String): AbstractCompile {
|
||||
return project.tasks.create(name, kotlinJVMCompileTaskClass).apply {
|
||||
friendTaskName = taskToFriendTaskMapper[this]
|
||||
}
|
||||
}
|
||||
|
||||
public fun createKotlinJSTask(project: Project, name: String): AbstractCompile {
|
||||
fun createKotlinJSTask(project: Project, name: String): AbstractCompile {
|
||||
return project.tasks.create(name, kotlinJSCompileTaskClass)
|
||||
}
|
||||
|
||||
protected open val taskToFriendTaskMapper: TaskToFriendTaskMapper =
|
||||
RegexTaskToFriendTaskMapper.Default()
|
||||
}
|
||||
|
||||
class AndroidTasksProvider(tasksLoader: ClassLoader) : KotlinTasksProvider(tasksLoader) {
|
||||
override val taskToFriendTaskMapper: TaskToFriendTaskMapper =
|
||||
RegexTaskToFriendTaskMapper.Android()
|
||||
}
|
||||
+7
-2
@@ -18,11 +18,13 @@ abstract class AbstractKotlinAndroidGradleTests(
|
||||
androidHome = File("../../../dependencies/android-sdk-for-tests"),
|
||||
androidGradlePluginVersion = androidGradlePluginVersion)
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
fun testSimpleCompile() {
|
||||
val project = Project("AndroidProject", gradleVersion)
|
||||
|
||||
project.build("build") {
|
||||
project.build("build", "assembleAndroidTest") {
|
||||
assertSuccessful()
|
||||
assertContains(":Lib:compileReleaseKotlin",
|
||||
":Test:compileDebugKotlin",
|
||||
@@ -37,7 +39,10 @@ abstract class AbstractKotlinAndroidGradleTests(
|
||||
":compileFlavor1Jnidebug",
|
||||
":compileFlavor2Jnidebug",
|
||||
":compileFlavor1Release",
|
||||
":compileFlavor2Release")
|
||||
":compileFlavor2Release",
|
||||
":compileFlavor1DebugUnitTestKotlin",
|
||||
"InternalDummyTest PASSED",
|
||||
":compileFlavor1DebugAndroidTestKotlin")
|
||||
}
|
||||
|
||||
// Run the build second time, assert everything is up-to-date
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin
|
||||
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class RegexTaskToFriendTaskMapperTest {
|
||||
@Test
|
||||
fun getFriendTaskNameDefault() {
|
||||
val mapper = RegexTaskToFriendTaskMapper.Default()
|
||||
Assert.assertEquals("compileKotlin", mapper["compileTestKotlin"])
|
||||
Assert.assertEquals(null, mapper["compileKotlin"])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getFriendTaskNameAndroid() {
|
||||
val mapper = RegexTaskToFriendTaskMapper.Android()
|
||||
// Unit test examples
|
||||
Assert.assertEquals("compileDebugKotlin", mapper["compileDebugUnitTestKotlin"])
|
||||
Assert.assertEquals("compileReleaseKotlin", mapper["compileReleaseUnitTestKotlin"])
|
||||
Assert.assertEquals("compileProdDebugKotlin", mapper["compileProdDebugUnitTestKotlin"])
|
||||
// Android test examples
|
||||
Assert.assertEquals("compileDebugKotlin", mapper["compileDebugAndroidTestKotlin"])
|
||||
Assert.assertEquals("compileReleaseKotlin", mapper["compileReleaseAndroidTestKotlin"])
|
||||
Assert.assertEquals("compileProdDebugKotlin", mapper["compileProdDebugAndroidTestKotlin"])
|
||||
|
||||
Assert.assertEquals(null, mapper["compileDebugKotlin"])
|
||||
}
|
||||
}
|
||||
+3
@@ -4,6 +4,8 @@ apply plugin: 'kotlin-android'
|
||||
|
||||
dependencies {
|
||||
compile project(':Lib')
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:1.1-SNAPSHOT"
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -12,6 +14,7 @@ android {
|
||||
|
||||
sourceSets {
|
||||
main.kotlin.srcDirs += 'root/kotlin'
|
||||
test.kotlin.srcDirs += 'src/test/kotlin'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import android.app.Application
|
||||
import android.test.ApplicationTestCase
|
||||
|
||||
class InternalDummyApplicationTest : ApplicationTestCase<Application>(Application::class.java) {
|
||||
init {
|
||||
val dummy = InternalDummy("World")
|
||||
assert("Hello World!" == dummy.greeting) { "Expected: 'Hello World!'. Actual value: ${dummy.greeting}" }
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
internal class InternalDummy(private val name: String) {
|
||||
internal val greeting: String
|
||||
get() = "Hello $name!"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class InternalDummyTest {
|
||||
@Test
|
||||
fun testInternalDummy() {
|
||||
val dummy = InternalDummy("World")
|
||||
Assert.assertEquals("Hello World!", dummy.greeting)
|
||||
}
|
||||
}
|
||||
-4
@@ -2,10 +2,6 @@ apply plugin: 'android-sdk-manager'
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile files('libs/android-support-v4.jar')
|
||||
}
|
||||
|
||||
+8
-3
@@ -1,8 +1,6 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
maven {
|
||||
url 'file://' + pathToKotlinPlugin
|
||||
}
|
||||
maven { url 'file://' + pathToKotlinPlugin }
|
||||
maven {
|
||||
url 'http://jcenter.bintray.com'
|
||||
}
|
||||
@@ -14,4 +12,11 @@ buildscript {
|
||||
classpath ('com.android.tools.build:gradle:' + androidToolsVersion)
|
||||
classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.+'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
maven { url 'file://' + pathToKotlinPlugin }
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user