Add tests for explicit language/api version change in Gradle

Modifying language/api version should cause non-incremental build.
Implicit change (e.g. when versions are not specified, but the compiler
is updated 1.1->1.2) is handled by `AbstractKotlinCompileTool#computedCompilerClasspath`.
Explicit change is handled by `AbstractKotlinCompile#serializedCompilerArguments`.
This commit is contained in:
Alexey Tsvetkov
2017-11-22 22:15:26 +03:00
parent 913a997f24
commit 2b708f67ee
@@ -8,35 +8,51 @@ import java.io.File
class UpToDateIT : BaseGradleIT() { class UpToDateIT : BaseGradleIT() {
@Test @Test
fun testWithAllMutations() { fun testLanguageVersionChange() {
testMutations(*propertyMutationChain("compileKotlin.kotlinOptions.languageVersion",
"null", "'1.1'", "'1.0'", "null"))
}
@Test
fun testApiVersionChange() {
testMutations(*propertyMutationChain("compileKotlin.kotlinOptions.apiVersion",
"null", "'1.1'", "'1.0'", "null"))
}
@Test
fun testOther() {
testMutations(emptyMutation,
OptionMutation("compileKotlin.kotlinOptions.jvmTarget", "'1.6'", "'1.8'"),
OptionMutation("compileKotlin.kotlinOptions.freeCompilerArgs", "[]", "['-Xallow-kotlin-package']"),
OptionMutation("kotlin.experimental.coroutines", "'error'", "'enable'"),
OptionMutation("archivesBaseName", "'someName'", "'otherName'"),
externalOutputMutation,
compilerClasspathMutation)
}
private fun testMutations(vararg mutations: ProjectMutation) {
val project = Project("simpleProject", "4.1") val project = Project("simpleProject", "4.1")
project.setupWorkingDir() project.setupWorkingDir()
mutations.forEach { it.initProject(project) }
project.build("build") { assertSuccessful() }
mutations.forEach { mutations.forEach {
it.initProject(project)
project.build("build") { assertSuccessful() }
it.mutateProject(project) it.mutateProject(project)
project.build("build") { project.build("build") {
try {
assertSuccessful() assertSuccessful()
it.checkAfterRebuild(this) it.checkAfterRebuild(this)
} }
catch (e: Throwable) {
throw RuntimeException("Mutation '${it.name}' has failed", e)
}
}
} }
} }
private val mutations
get() = listOf(
emptyMutation,
optionMutation("compileKotlin.kotlinOptions.jvmTarget", "'1.6'", "'1.8'",
shouldOutdateCompileKotlin = true),
optionMutation("compileKotlin.kotlinOptions.freeCompilerArgs", "[]", "['-Xallow-kotlin-package']",
shouldOutdateCompileKotlin = true),
optionMutation("kotlin.experimental.coroutines", "'error'", "'enable'",
shouldOutdateCompileKotlin = true),
optionMutation("archivesBaseName", "'someName'", "'otherName'",
shouldOutdateCompileKotlin = true),
externalOutputMutation,
compilerClasspathMutation)
private val emptyMutation = object : ProjectMutation { private val emptyMutation = object : ProjectMutation {
override val name = "emptyMutation"
override fun initProject(project: Project) = Unit override fun initProject(project: Project) = Unit
override fun mutateProject(project: Project) = Unit override fun mutateProject(project: Project) = Unit
@@ -46,6 +62,8 @@ class UpToDateIT : BaseGradleIT() {
} }
private val compilerClasspathMutation = object : ProjectMutation { private val compilerClasspathMutation = object : ProjectMutation {
override val name = "compilerClasspathMutation"
lateinit var originalCompilerCp: List<String> lateinit var originalCompilerCp: List<String>
val originalPaths get() = originalCompilerCp.map { it.replace("\\", "/") }.joinToString(", ") { "'$it'" } val originalPaths get() = originalCompilerCp.map { it.replace("\\", "/") }.joinToString(", ") { "'$it'" }
@@ -73,6 +91,8 @@ class UpToDateIT : BaseGradleIT() {
} }
private val externalOutputMutation = object : ProjectMutation { private val externalOutputMutation = object : ProjectMutation {
override val name = "externalOutputMutation"
override fun initProject(project: Project) = Unit override fun initProject(project: Project) = Unit
lateinit var helloWorldKtClass: File lateinit var helloWorldKtClass: File
@@ -95,29 +115,37 @@ class UpToDateIT : BaseGradleIT() {
fun initProject(project: Project) fun initProject(project: Project)
fun mutateProject(project: Project) fun mutateProject(project: Project)
fun checkAfterRebuild(compiledProject: CompiledProject) fun checkAfterRebuild(compiledProject: CompiledProject)
val name: String
} }
private fun optionMutation( private fun propertyMutationChain(path: String, vararg values: String): Array<ProjectMutation> =
path: String, arrayListOf<ProjectMutation>().apply {
oldValue: String, for (i in 1..values.lastIndex) {
newValue: String, add(OptionMutation(path, values[i - 1], values[i], shouldInit = i == 1))
shouldOutdateCompileKotlin: Boolean }
) = object : ProjectMutation {
}.toTypedArray()
private inner class OptionMutation(
private val path: String,
private val oldValue: String,
private val newValue: String,
private val shouldInit: Boolean = true
) : ProjectMutation {
override val name = "OptionMutation(path='$path', oldValue='$oldValue', newValue='$newValue')"
override fun initProject(project: Project) = with(project) { override fun initProject(project: Project) = with(project) {
if (shouldInit) {
buildGradle.appendText("\n$path = $oldValue") buildGradle.appendText("\n$path = $oldValue")
} }
}
override fun mutateProject(project: Project) = with(project) { override fun mutateProject(project: Project) = with(project) {
buildGradle.modify { it.replace("$path = $oldValue", "$path = $newValue") } buildGradle.modify { it.replace("$path = $oldValue", "$path = $newValue") }
} }
override fun checkAfterRebuild(compiledProject: CompiledProject) = with(compiledProject) { override fun checkAfterRebuild(compiledProject: CompiledProject) = with(compiledProject) {
if (shouldOutdateCompileKotlin) {
assertTasksExecuted(listOf(":compileKotlin")) assertTasksExecuted(listOf(":compileKotlin"))
} }
else {
assertTasksUpToDate(listOf(":compileKotlin"))
}
}
} }
} }