[IC] Multi-module incremental compilation smoke tests for KMP
Part 2. Main multi-module KMP smoke tests for incremental compilation ^KT-56963 Fixed ^KT-63876 Fixed Merge-request: KT-MR-13193 Merged-by: Evgenii Mazhukin <evgenii.mazhukin@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
c4fe7e4453
commit
befa921fd9
+27
-27
@@ -9,15 +9,13 @@ import org.gradle.api.logging.LogLevel
|
|||||||
import org.gradle.testkit.runner.BuildResult
|
import org.gradle.testkit.runner.BuildResult
|
||||||
import org.gradle.util.GradleVersion
|
import org.gradle.util.GradleVersion
|
||||||
import org.jetbrains.kotlin.gradle.testbase.*
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
import org.jetbrains.kotlin.gradle.testbase.relativizeTo
|
import org.jetbrains.kotlin.gradle.util.replaceWithVersion
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
|
||||||
import kotlin.io.path.appendText
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KmpIncrementalITBase is used as a "limited scope" for experimental test utils.
|
* Convenience class for KMP incremental compilation tests.
|
||||||
* If some of them can be reused widely, consider moving them to KGPBaseTest
|
*
|
||||||
* or the appropriate util package. //TODO: KT-63876
|
* Consider moving all general-purpose logic to `org.jetbrains.kotlin.gradle.testbase` package.
|
||||||
*/
|
*/
|
||||||
abstract class KmpIncrementalITBase : KGPBaseTest() {
|
abstract class KmpIncrementalITBase : KGPBaseTest() {
|
||||||
|
|
||||||
@@ -27,9 +25,11 @@ abstract class KmpIncrementalITBase : KGPBaseTest() {
|
|||||||
protected open val gradleTask = "assemble"
|
protected open val gradleTask = "assemble"
|
||||||
protected open val projectName = "generic-kmp-app-plus-lib-with-tests"
|
protected open val projectName = "generic-kmp-app-plus-lib-with-tests"
|
||||||
protected open val mainCompileTasks = setOf(
|
protected open val mainCompileTasks = setOf(
|
||||||
|
":app:compileCommonMainKotlinMetadata",
|
||||||
":app:compileKotlinJvm",
|
":app:compileKotlinJvm",
|
||||||
":app:compileKotlinJs",
|
":app:compileKotlinJs",
|
||||||
":app:compileKotlinNative",
|
":app:compileKotlinNative",
|
||||||
|
":lib:compileCommonMainKotlinMetadata",
|
||||||
":lib:compileKotlinJvm",
|
":lib:compileKotlinJvm",
|
||||||
":lib:compileKotlinJs",
|
":lib:compileKotlinJs",
|
||||||
":lib:compileKotlinNative",
|
":lib:compileKotlinNative",
|
||||||
@@ -48,30 +48,30 @@ abstract class KmpIncrementalITBase : KGPBaseTest() {
|
|||||||
return subProject(subproject).kotlinSourcesDir(srcDir).resolve(name)
|
return subProject(subproject).kotlinSourcesDir(srcDir).resolve(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun Path.addPrivateVal(): Path {
|
protected open fun TestProject.checkIncrementalBuild(
|
||||||
this@addPrivateVal.appendText("private val nothingMuch${changeCounter.incrementAndGet()} = 24")
|
tasksExpectedToExecute: Set<String>,
|
||||||
return this@addPrivateVal
|
assertions: BuildResult.() -> Unit = {}
|
||||||
}
|
) {
|
||||||
|
|
||||||
protected open fun BuildResult.assertSuccessOrUTD(allTasks: Set<String>, executedTasks: Set<String>) {
|
|
||||||
assertTasksExecuted(executedTasks)
|
|
||||||
assertTasksUpToDate(allTasks - executedTasks)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun TestProject.testCase(incrementalPath: Path? = null, executedTasks: Set<String>, assertions: BuildResult.() -> Unit = {}) {
|
|
||||||
build(gradleTask, buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
build(gradleTask, buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||||
assertSuccessOrUTD(
|
assertTasksExecuted(tasksExpectedToExecute)
|
||||||
allTasks = mainCompileTasks,
|
assertTasksUpToDate(mainCompileTasks - tasksExpectedToExecute)
|
||||||
executedTasks = executedTasks
|
|
||||||
)
|
|
||||||
incrementalPath?.let {
|
|
||||||
assertIncrementalCompilation(listOf(it).relativizeTo(projectPath))
|
|
||||||
}
|
|
||||||
assertions()
|
assertions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
protected open fun TestProject.multiStepCheckIncrementalBuilds(
|
||||||
private val changeCounter = AtomicInteger(0)
|
incrementalPath: Path,
|
||||||
|
steps: List<String>,
|
||||||
|
tasksExpectedToExecuteOnEachStep: Set<String>,
|
||||||
|
afterEachStep: BuildResult.() -> Unit = {}
|
||||||
|
) {
|
||||||
|
for (step in steps) {
|
||||||
|
incrementalPath.replaceWithVersion(step)
|
||||||
|
build(gradleTask, buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||||
|
assertTasksExecuted(tasksExpectedToExecuteOnEachStep)
|
||||||
|
assertTasksUpToDate(mainCompileTasks - tasksExpectedToExecuteOnEachStep)
|
||||||
|
afterEachStep()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-32
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.mpp.smoke
|
|||||||
import org.gradle.util.GradleVersion
|
import org.gradle.util.GradleVersion
|
||||||
import org.jetbrains.kotlin.gradle.mpp.KmpIncrementalITBase
|
import org.jetbrains.kotlin.gradle.mpp.KmpIncrementalITBase
|
||||||
import org.jetbrains.kotlin.gradle.testbase.*
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata
|
||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,6 +20,7 @@ open class BasicIncrementalCompilationIT : KmpIncrementalITBase() {
|
|||||||
|
|
||||||
@DisplayName("Base test case - local change, local recompilation")
|
@DisplayName("Base test case - local change, local recompilation")
|
||||||
@GradleTest
|
@GradleTest
|
||||||
|
@TestMetadata("generic-kmp-app-plus-lib-with-tests")
|
||||||
fun testStrictlyLocalChange(gradleVersion: GradleVersion): Unit = withProject(gradleVersion) {
|
fun testStrictlyLocalChange(gradleVersion: GradleVersion): Unit = withProject(gradleVersion) {
|
||||||
build("assemble")
|
build("assemble")
|
||||||
|
|
||||||
@@ -26,84 +28,99 @@ open class BasicIncrementalCompilationIT : KmpIncrementalITBase() {
|
|||||||
* Step 1: touch app:common, no abi change
|
* Step 1: touch app:common, no abi change
|
||||||
*/
|
*/
|
||||||
|
|
||||||
testCase(
|
val sourceInAppCommon = resolvePath("app", "commonMain", "Unused.kt").addPrivateVal()
|
||||||
incrementalPath = resolvePath("app", "commonMain", "Unused.kt").addPrivateVal(),
|
checkIncrementalBuild(
|
||||||
executedTasks = setOf(
|
tasksExpectedToExecute = setOf(
|
||||||
|
":app:compileCommonMainKotlinMetadata",
|
||||||
":app:compileKotlinJvm",
|
":app:compileKotlinJvm",
|
||||||
":app:compileKotlinJs",
|
":app:compileKotlinJs",
|
||||||
":app:compileKotlinNative"
|
":app:compileKotlinNative"
|
||||||
)
|
)
|
||||||
)
|
) {
|
||||||
|
assertIncrementalCompilation(listOf(sourceInAppCommon).relativizeTo(projectPath))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Step 2: touch app:jvm, no abi change
|
* Step 2: touch app:jvm, no abi change
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val appJvmClassKt = resolvePath("app", "jvmMain", "UnusedJvm.kt").addPrivateVal()
|
val sourceInAppJvm = resolvePath("app", "jvmMain", "UnusedJvm.kt").addPrivateVal()
|
||||||
testCase(
|
checkIncrementalBuild(
|
||||||
incrementalPath = null, //TODO: it just doesn't print "Incremental compilation completed", why? (KT-63476)
|
tasksExpectedToExecute = setOf(":app:compileKotlinJvm")
|
||||||
executedTasks = setOf(":app:compileKotlinJvm")
|
|
||||||
) {
|
) {
|
||||||
assertCompiledKotlinSources(listOf(appJvmClassKt).relativizeTo(projectPath), output)
|
//TODO: it just doesn't print "Incremental compilation completed", why? (KT-63476)
|
||||||
|
assertCompiledKotlinSources(listOf(sourceInAppJvm).relativizeTo(projectPath), output)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Step 3: touch app:js, no abi change
|
* Step 3: touch app:js, no abi change
|
||||||
*/
|
*/
|
||||||
|
|
||||||
testCase(
|
val sourceInAppJs = resolvePath("app", "jsMain", "UnusedJs.kt").addPrivateVal()
|
||||||
incrementalPath = resolvePath("app", "jsMain", "UnusedJs.kt").addPrivateVal(),
|
checkIncrementalBuild(
|
||||||
executedTasks = setOf(":app:compileKotlinJs"),
|
tasksExpectedToExecute = setOf(":app:compileKotlinJs"),
|
||||||
)
|
) {
|
||||||
|
assertIncrementalCompilation(listOf(sourceInAppJs).relativizeTo(projectPath))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Step 4: touch app:native, no abi change
|
* Step 4: touch app:native, no abi change
|
||||||
*/
|
*/
|
||||||
|
|
||||||
resolvePath("app", "nativeMain", "UnusedNative.kt").addPrivateVal()
|
resolvePath("app", "nativeMain", "UnusedNative.kt").addPrivateVal()
|
||||||
testCase(
|
checkIncrementalBuild(
|
||||||
incrementalPath = null, // no native incremental compilation - see KT-62824
|
tasksExpectedToExecute = setOf(":app:compileKotlinNative"),
|
||||||
executedTasks = setOf(":app:compileKotlinNative"),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Step 5: touch lib:common, no abi change
|
* Step 5: touch lib:common, no abi change
|
||||||
*/
|
*/
|
||||||
|
|
||||||
testCase(
|
val sourceInLibCommon = resolvePath("lib", "commonMain", "UsedInLibPlatformTests.kt").addPrivateVal()
|
||||||
incrementalPath = resolvePath("lib", "commonMain", "UsedInLibPlatformTests.kt").addPrivateVal(),
|
checkIncrementalBuild(
|
||||||
executedTasks = mainCompileTasks // TODO: KT-62642 - bad compile avoidance here
|
tasksExpectedToExecute = mainCompileTasks // TODO: KT-62642 - bad compile avoidance here
|
||||||
)
|
) {
|
||||||
|
assertIncrementalCompilation(listOf(sourceInLibCommon).relativizeTo(projectPath))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Step 6: touch lib:jvm, no abi change
|
* Step 6: touch lib:jvm, no abi change
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val libJvmUtilKt = resolvePath("lib", "jvmMain", "UsedInAppJvmAndLibTests.kt").addPrivateVal()
|
val sourceInLibJvm = resolvePath("lib", "jvmMain", "UsedInAppJvmAndLibTests.kt").addPrivateVal()
|
||||||
testCase(
|
checkIncrementalBuild(
|
||||||
incrementalPath = null, //TODO: it just doesn't print "Incremental compilation completed", why? (KT-63476)
|
tasksExpectedToExecute = setOf(
|
||||||
executedTasks = setOf(":app:compileKotlinJvm", ":lib:compileKotlinJvm"),
|
":app:compileKotlinJvm",
|
||||||
|
":lib:compileKotlinJvm"
|
||||||
|
),
|
||||||
) {
|
) {
|
||||||
assertCompiledKotlinSources(listOf(libJvmUtilKt).relativizeTo(projectPath), output)
|
assertCompiledKotlinSources(listOf(sourceInLibJvm).relativizeTo(projectPath), output)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Step 7: touch lib:js, no abi change
|
* Step 7: touch lib:js, no abi change
|
||||||
*/
|
*/
|
||||||
|
|
||||||
testCase(
|
val sourceInLibJs = resolvePath("lib", "jsMain", "UsedInAppJsAndLibTests.kt").addPrivateVal()
|
||||||
incrementalPath = resolvePath("lib", "jsMain", "UsedInAppJsAndLibTests.kt").addPrivateVal(),
|
checkIncrementalBuild(
|
||||||
executedTasks = setOf(":app:compileKotlinJs", ":lib:compileKotlinJs"),
|
tasksExpectedToExecute = setOf(
|
||||||
)
|
":app:compileKotlinJs",
|
||||||
|
":lib:compileKotlinJs"
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
assertIncrementalCompilation(listOf(sourceInLibJs).relativizeTo(projectPath))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Step 8: touch lib:native, no abi change
|
* Step 8: touch lib:native, no abi change
|
||||||
*/
|
*/
|
||||||
|
|
||||||
resolvePath("lib", "nativeMain", "UsedInAppNativeAndLibTests.kt").addPrivateVal()
|
resolvePath("lib", "nativeMain", "UsedInAppNativeAndLibTests.kt").addPrivateVal()
|
||||||
testCase(
|
checkIncrementalBuild(
|
||||||
incrementalPath = null,
|
tasksExpectedToExecute = setOf(
|
||||||
executedTasks = setOf(":app:compileKotlinNative", ":lib:compileKotlinNative"),
|
":app:compileKotlinNative",
|
||||||
|
":lib:compileKotlinNative"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-18
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.mpp.smoke
|
|||||||
import org.gradle.util.GradleVersion
|
import org.gradle.util.GradleVersion
|
||||||
import org.jetbrains.kotlin.gradle.mpp.KmpIncrementalITBase
|
import org.jetbrains.kotlin.gradle.mpp.KmpIncrementalITBase
|
||||||
import org.jetbrains.kotlin.gradle.testbase.*
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata
|
||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
|
||||||
@DisplayName("Basic incremental scenarios with tests in KMP - K2")
|
@DisplayName("Basic incremental scenarios with tests in KMP - K2")
|
||||||
@@ -15,6 +16,9 @@ import org.junit.jupiter.api.DisplayName
|
|||||||
open class BasicTestIncrementalCompilationIT : KmpIncrementalITBase() {
|
open class BasicTestIncrementalCompilationIT : KmpIncrementalITBase() {
|
||||||
override val mainCompileTasks: Set<String>
|
override val mainCompileTasks: Set<String>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
|
":app:compileCommonMainKotlinMetadata",
|
||||||
|
":lib:compileCommonMainKotlinMetadata",
|
||||||
|
|
||||||
":app:compileTestKotlinJvm",
|
":app:compileTestKotlinJvm",
|
||||||
":lib:compileTestKotlinJvm",
|
":lib:compileTestKotlinJvm",
|
||||||
|
|
||||||
@@ -38,6 +42,7 @@ open class BasicTestIncrementalCompilationIT : KmpIncrementalITBase() {
|
|||||||
|
|
||||||
@DisplayName("KMP tests are rebuilt when affected")
|
@DisplayName("KMP tests are rebuilt when affected")
|
||||||
@GradleTest
|
@GradleTest
|
||||||
|
@TestMetadata("generic-kmp-app-plus-lib-with-tests")
|
||||||
fun testAffectingTestDependencies(gradleVersion: GradleVersion): Unit = withProject(gradleVersion) {
|
fun testAffectingTestDependencies(gradleVersion: GradleVersion): Unit = withProject(gradleVersion) {
|
||||||
build("build")
|
build("build")
|
||||||
|
|
||||||
@@ -45,18 +50,21 @@ open class BasicTestIncrementalCompilationIT : KmpIncrementalITBase() {
|
|||||||
* Step 1 - touch lib/common, affect all tests in app and lib
|
* Step 1 - touch lib/common, affect all tests in app and lib
|
||||||
*/
|
*/
|
||||||
|
|
||||||
testCase(
|
val changedInLibCommon = resolvePath("lib", "commonMain", "UsedInLibPlatformTests.kt").addPrivateVal()
|
||||||
incrementalPath = resolvePath("lib", "commonMain", "UsedInLibPlatformTests.kt").addPrivateVal(),
|
checkIncrementalBuild(
|
||||||
executedTasks = mainCompileTasks,
|
tasksExpectedToExecute = mainCompileTasks,
|
||||||
)
|
) {
|
||||||
|
assertIncrementalCompilation(listOf(changedInLibCommon).relativizeTo(projectPath))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Step 2 - touch app/common, affect all tests in app
|
* Step 2 - touch app/common, affect all tests in app
|
||||||
*/
|
*/
|
||||||
|
|
||||||
testCase(
|
val changedInAppCommon = resolvePath("app", "commonMain", "Unused.kt").addPrivateVal()
|
||||||
incrementalPath = resolvePath("app", "commonMain", "Unused.kt").addPrivateVal(),
|
checkIncrementalBuild(
|
||||||
executedTasks = setOf(
|
tasksExpectedToExecute = setOf(
|
||||||
|
":app:compileCommonMainKotlinMetadata",
|
||||||
":app:compileTestKotlinJvm",
|
":app:compileTestKotlinJvm",
|
||||||
":app:compileTestKotlinNative",
|
":app:compileTestKotlinNative",
|
||||||
":app:compileTestKotlinJs",
|
":app:compileTestKotlinJs",
|
||||||
@@ -64,16 +72,17 @@ open class BasicTestIncrementalCompilationIT : KmpIncrementalITBase() {
|
|||||||
":app:jvmTest",
|
":app:jvmTest",
|
||||||
":app:nativeTest",
|
":app:nativeTest",
|
||||||
),
|
),
|
||||||
)
|
) {
|
||||||
|
assertIncrementalCompilation(listOf(changedInAppCommon).relativizeTo(projectPath))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Step 3 - touch app/jvm, affect jvm tests in app
|
* Step 3 - touch app/jvm, affect jvm tests in app
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val touchedAppJvm = resolvePath("app", "jvmMain", "UnusedJvm.kt").addPrivateVal()
|
val touchedAppJvm = resolvePath("app", "jvmMain", "UnusedJvm.kt").addPrivateVal()
|
||||||
testCase(
|
checkIncrementalBuild(
|
||||||
incrementalPath = null,
|
tasksExpectedToExecute = setOf(
|
||||||
executedTasks = setOf(
|
|
||||||
":app:compileTestKotlinJvm",
|
":app:compileTestKotlinJvm",
|
||||||
":app:jvmTest",
|
":app:jvmTest",
|
||||||
),
|
),
|
||||||
@@ -85,22 +94,23 @@ open class BasicTestIncrementalCompilationIT : KmpIncrementalITBase() {
|
|||||||
* Step 4 - touch app/js, affect js tests in app
|
* Step 4 - touch app/js, affect js tests in app
|
||||||
*/
|
*/
|
||||||
|
|
||||||
testCase(
|
val changedInAppJs = resolvePath("app", "jsMain", "UnusedJs.kt").addPrivateVal()
|
||||||
incrementalPath = resolvePath("app", "jsMain", "UnusedJs.kt").addPrivateVal(),
|
checkIncrementalBuild(
|
||||||
executedTasks = setOf(
|
tasksExpectedToExecute = setOf(
|
||||||
":app:compileTestKotlinJs",
|
":app:compileTestKotlinJs",
|
||||||
":app:jsTest",
|
":app:jsTest",
|
||||||
),
|
),
|
||||||
)
|
) {
|
||||||
|
assertIncrementalCompilation(listOf(changedInAppJs).relativizeTo(projectPath))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Step 5 - touch app/native, affect native tests in app
|
* Step 5 - touch app/native, affect native tests in app
|
||||||
*/
|
*/
|
||||||
|
|
||||||
resolvePath("app", "nativeMain", "UnusedNative.kt").addPrivateVal()
|
resolvePath("app", "nativeMain", "UnusedNative.kt").addPrivateVal()
|
||||||
testCase(
|
checkIncrementalBuild(
|
||||||
incrementalPath = null,
|
tasksExpectedToExecute = setOf(
|
||||||
executedTasks = setOf(
|
|
||||||
":app:compileTestKotlinNative",
|
":app:compileTestKotlinNative",
|
||||||
":app:nativeTest",
|
":app:nativeTest",
|
||||||
),
|
),
|
||||||
|
|||||||
+14
-13
@@ -8,17 +8,15 @@ package org.jetbrains.kotlin.gradle.mpp.smoke
|
|||||||
import org.gradle.api.logging.LogLevel
|
import org.gradle.api.logging.LogLevel
|
||||||
import org.gradle.util.GradleVersion
|
import org.gradle.util.GradleVersion
|
||||||
import org.jetbrains.kotlin.gradle.testbase.*
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
import org.jetbrains.kotlin.gradle.util.replaceFirst
|
import org.jetbrains.kotlin.gradle.util.replaceWithVersion
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata
|
||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
import kotlin.io.path.appendText
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Touch file with expect fun, target IC adds actual to the build set
|
* Touch file with expect fun, target IC adds actual to the build set
|
||||||
* Variants: expect class
|
* Variants: expect class
|
||||||
* Touch file with actual fun, target IC adds expect to the build set
|
* Touch file with actual fun, target IC adds expect to the build set
|
||||||
* Variants: expect class
|
* Variants: expect class
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@DisplayName("Incremental scenarios with expect/actual - K2")
|
@DisplayName("Incremental scenarios with expect/actual - K2")
|
||||||
@MppGradlePluginTests
|
@MppGradlePluginTests
|
||||||
@@ -28,17 +26,21 @@ open class ExpectActualIncrementalCompilationIT : KGPBaseTest() {
|
|||||||
|
|
||||||
@DisplayName("File with actual declaration needs recompiling")
|
@DisplayName("File with actual declaration needs recompiling")
|
||||||
@GradleTest
|
@GradleTest
|
||||||
|
@TestMetadata("expect-actual-fun-or-class-ic")
|
||||||
fun testRecompilationOfActualFun(gradleVersion: GradleVersion) {
|
fun testRecompilationOfActualFun(gradleVersion: GradleVersion) {
|
||||||
nativeProject("expect-actual-fun-or-class-ic", gradleVersion) {
|
nativeProject("expect-actual-fun-or-class-ic", gradleVersion) {
|
||||||
build("assemble")
|
build("assemble")
|
||||||
|
|
||||||
listOf(
|
listOf(
|
||||||
kotlinSourcesDir("jvmMain").resolve("ActualFunFoo.kt"),
|
kotlinSourcesDir("jvmMain").resolve("ActualFunFoo.kt"),
|
||||||
kotlinSourcesDir("nativeMain").resolve("ActualFunFoo.kt"),
|
|
||||||
kotlinSourcesDir("jsMain").resolve("ActualFunFoo.kt")
|
kotlinSourcesDir("jsMain").resolve("ActualFunFoo.kt")
|
||||||
).forEach {
|
).forEach {
|
||||||
it.replaceFirst("\"foo", "\"bar")
|
// just touch the file. expected logic is this:
|
||||||
|
// actual declaration needs to be recompiled -> we add expect declaration to the list of compiled files
|
||||||
|
it.addPrivateVal()
|
||||||
}
|
}
|
||||||
|
//TODO: KT-63970 - native compilation fails, if val is private
|
||||||
|
kotlinSourcesDir("nativeMain").resolve("ActualFunFoo.kt").addPublicVal()
|
||||||
|
|
||||||
build("assemble", buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
build("assemble", buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||||
assertTasksExecuted(":compileKotlinJvm", ":compileKotlinJs", ":compileKotlinNative")
|
assertTasksExecuted(":compileKotlinJvm", ":compileKotlinJs", ":compileKotlinNative")
|
||||||
@@ -55,15 +57,13 @@ open class ExpectActualIncrementalCompilationIT : KGPBaseTest() {
|
|||||||
|
|
||||||
@DisplayName("File with expect declaration needs recompiling indirectly")
|
@DisplayName("File with expect declaration needs recompiling indirectly")
|
||||||
@GradleTest
|
@GradleTest
|
||||||
|
@TestMetadata("expect-actual-fun-or-class-ic")
|
||||||
fun testRecompilationOfExpectFun(gradleVersion: GradleVersion) {
|
fun testRecompilationOfExpectFun(gradleVersion: GradleVersion) {
|
||||||
nativeProject("expect-actual-fun-or-class-ic", gradleVersion) {
|
nativeProject("expect-actual-fun-or-class-ic", gradleVersion) {
|
||||||
build("assemble")
|
build("assemble")
|
||||||
|
|
||||||
val unusedKtPath = kotlinSourcesDir("commonMain").resolve("Unused.kt")
|
val commonSourceKt = kotlinSourcesDir("commonMain").resolve("UsedInFileWithExpectFun.kt")
|
||||||
unusedKtPath.replaceFirst(
|
commonSourceKt.replaceWithVersion("sourceCompatibleAbiChange")
|
||||||
"val secret = 1",
|
|
||||||
"val secret = \"k2\""
|
|
||||||
)
|
|
||||||
|
|
||||||
build("assemble", buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
build("assemble", buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||||
assertTasksExecuted(":compileKotlinJvm", ":compileKotlinJs", ":compileKotlinNative")
|
assertTasksExecuted(":compileKotlinJvm", ":compileKotlinJs", ":compileKotlinNative")
|
||||||
@@ -72,7 +72,7 @@ open class ExpectActualIncrementalCompilationIT : KGPBaseTest() {
|
|||||||
kotlinSourcesDir("jvmMain").resolve("ActualFunFoo.kt"),
|
kotlinSourcesDir("jvmMain").resolve("ActualFunFoo.kt"),
|
||||||
kotlinSourcesDir("jsMain").resolve("ActualFunFoo.kt"),
|
kotlinSourcesDir("jsMain").resolve("ActualFunFoo.kt"),
|
||||||
kotlinSourcesDir("commonMain").resolve("ExpectFunFoo.kt"),
|
kotlinSourcesDir("commonMain").resolve("ExpectFunFoo.kt"),
|
||||||
unusedKtPath
|
commonSourceKt
|
||||||
).relativizeTo(projectPath)
|
).relativizeTo(projectPath)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -81,11 +81,12 @@ open class ExpectActualIncrementalCompilationIT : KGPBaseTest() {
|
|||||||
|
|
||||||
@DisplayName("File with expect class declaration needs recompiling")
|
@DisplayName("File with expect class declaration needs recompiling")
|
||||||
@GradleTest
|
@GradleTest
|
||||||
|
@TestMetadata("expect-actual-fun-or-class-ic")
|
||||||
fun testRecompilationOfExpectClass(gradleVersion: GradleVersion) {
|
fun testRecompilationOfExpectClass(gradleVersion: GradleVersion) {
|
||||||
nativeProject("expect-actual-fun-or-class-ic", gradleVersion) {
|
nativeProject("expect-actual-fun-or-class-ic", gradleVersion) {
|
||||||
build("assemble")
|
build("assemble")
|
||||||
|
|
||||||
kotlinSourcesDir("commonMain").resolve("ExpectClassBar.kt").appendText("val irrelevant = 2")
|
kotlinSourcesDir("commonMain").resolve("ExpectClassBar.kt").addPrivateVal()
|
||||||
|
|
||||||
build("assemble", buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
build("assemble", buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||||
assertTasksExecuted(":compileKotlinJvm", ":compileKotlinJs", ":compileKotlinNative")
|
assertTasksExecuted(":compileKotlinJvm", ":compileKotlinJs", ":compileKotlinNative")
|
||||||
|
|||||||
+207
-32
@@ -5,62 +5,237 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.mpp.smoke
|
package org.jetbrains.kotlin.gradle.mpp.smoke
|
||||||
|
|
||||||
|
import org.gradle.api.logging.LogLevel
|
||||||
|
import org.gradle.testkit.runner.BuildResult
|
||||||
import org.gradle.util.GradleVersion
|
import org.gradle.util.GradleVersion
|
||||||
import org.jetbrains.kotlin.gradle.testbase.BuildOptions
|
import org.jetbrains.kotlin.gradle.mpp.KmpIncrementalITBase
|
||||||
import org.jetbrains.kotlin.gradle.testbase.GradleTest
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
import org.jetbrains.kotlin.gradle.testbase.KGPBaseTest
|
import org.jetbrains.kotlin.gradle.util.replaceWithVersion
|
||||||
import org.jetbrains.kotlin.gradle.testbase.MppGradlePluginTests
|
import org.jetbrains.kotlin.test.TestMetadata
|
||||||
import org.junit.jupiter.api.Disabled
|
|
||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
|
||||||
@Disabled("KT-56963")
|
/**
|
||||||
|
* Multi-module KMP tests assert that IC is fine, when API changes between two modules, or common/platform parts of a module.
|
||||||
|
*/
|
||||||
@DisplayName("Basic multi-module incremental scenarios with KMP - K2")
|
@DisplayName("Basic multi-module incremental scenarios with KMP - K2")
|
||||||
@MppGradlePluginTests
|
@MppGradlePluginTests
|
||||||
open class MultiModuleIncrementalCompilationIT : KGPBaseTest() {
|
open class MultiModuleIncrementalCompilationIT : KmpIncrementalITBase() {
|
||||||
override val defaultBuildOptions: BuildOptions
|
|
||||||
get() = super.defaultBuildOptions.copyEnsuringK2()
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests api change across the module + sourceSet boundary
|
||||||
|
*/
|
||||||
@DisplayName("Verify IC builds on change in lib/commonMain")
|
@DisplayName("Verify IC builds on change in lib/commonMain")
|
||||||
@GradleTest
|
@GradleTest
|
||||||
fun testTouchLibCommon(gradleVersion: GradleVersion) {
|
@TestMetadata("generic-kmp-app-plus-lib-with-tests")
|
||||||
/**
|
fun testTouchLibCommon(gradleVersion: GradleVersion) = withProject(gradleVersion) {
|
||||||
* [Cross-Module] touch libCommon, affect appCommon, appJs
|
build("assemble")
|
||||||
* Variants: 1. code-compatible ABI breakage (change deduced return type), 2. no ABI breakage, 3. error + fix
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step 1: touch util used in app common
|
||||||
|
*/
|
||||||
|
val usedInAppCommon = resolvePath("lib", "commonMain", "UsedInAppCommon.kt")
|
||||||
|
|
||||||
|
multiStepCheckIncrementalBuilds(
|
||||||
|
incrementalPath = usedInAppCommon,
|
||||||
|
steps = listOf(
|
||||||
|
"1_addUnusedParameter",
|
||||||
|
"2_changeReturnType"
|
||||||
|
),
|
||||||
|
tasksExpectedToExecuteOnEachStep = mainCompileTasks,
|
||||||
|
afterEachStep = {
|
||||||
|
assertIncrementalCompilation(
|
||||||
|
listOf(
|
||||||
|
usedInAppCommon,
|
||||||
|
resolvePath("app", "commonMain", "DependsOnLibCommon.kt")
|
||||||
|
).relativizeTo(projectPath)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step 2: touch class extended in app platform, then build each platform
|
||||||
|
*/
|
||||||
|
val usedInAppPlatform = resolvePath("lib", "commonMain", "UsedInAppPlatform.kt")
|
||||||
|
usedInAppPlatform.replaceWithVersion("1_addNewPublicApi")
|
||||||
|
|
||||||
|
fun testIndividualTarget(moduleTask: String, extraAssertions: BuildResult.() -> Unit = {}) {
|
||||||
|
build(":app:$moduleTask", buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||||
|
val targetTasks = setOf(
|
||||||
|
":app:$moduleTask",
|
||||||
|
":lib:$moduleTask"
|
||||||
|
)
|
||||||
|
assertTasksExecuted(targetTasks)
|
||||||
|
assertTasksAreNotInTaskGraph(*(mainCompileTasks - targetTasks).toTypedArray())
|
||||||
|
extraAssertions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testIndividualTarget("compileKotlinJvm") {
|
||||||
|
assertCompiledKotlinSources(
|
||||||
|
listOf(
|
||||||
|
usedInAppPlatform,
|
||||||
|
resolvePath("app", "jvmMain", "DependsOnLibCommon.kt")
|
||||||
|
).relativizeTo(projectPath),
|
||||||
|
output
|
||||||
|
)
|
||||||
|
}
|
||||||
|
testIndividualTarget("compileKotlinJs") {
|
||||||
|
assertIncrementalCompilation(
|
||||||
|
listOf(
|
||||||
|
usedInAppPlatform,
|
||||||
|
resolvePath("app", "jsMain", "DependsOnLibCommon.kt")
|
||||||
|
).relativizeTo(projectPath)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
testIndividualTarget("compileKotlinNative")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Three platforms, two steps for each. Do source-compatible changes: first add default parameter,
|
||||||
|
* then change return type.
|
||||||
|
* lib/platform utils are used in app/platform with deduced return type.
|
||||||
|
*/
|
||||||
@DisplayName("Verify IC builds on change in lib/platformMain")
|
@DisplayName("Verify IC builds on change in lib/platformMain")
|
||||||
@GradleTest
|
@GradleTest
|
||||||
fun testTouchLibPlatform(gradleVersion: GradleVersion) {
|
@TestMetadata("generic-kmp-app-plus-lib-with-tests")
|
||||||
/**
|
fun testTouchLibPlatform(gradleVersion: GradleVersion) = withProject(gradleVersion) {
|
||||||
* [C-M] touch lbJs, affect appJs
|
build("assemble")
|
||||||
* Variants: 1. code-compatible ABI breakage (change deduced return type), 2. no ABI breakage, 3. error + fix
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
val commonSteps = listOf("1_addUnusedParameter", "2_changeReturnType")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step 1 - jvm
|
||||||
|
*/
|
||||||
|
val jvmUtil = resolvePath("lib", "jvmMain", "UsedInAppJvmAndLibTests.kt")
|
||||||
|
multiStepCheckIncrementalBuilds(
|
||||||
|
incrementalPath = jvmUtil,
|
||||||
|
steps = commonSteps,
|
||||||
|
tasksExpectedToExecuteOnEachStep = setOf(
|
||||||
|
":app:compileKotlinJvm",
|
||||||
|
":lib:compileKotlinJvm"
|
||||||
|
),
|
||||||
|
afterEachStep = {
|
||||||
|
assertCompiledKotlinSources(
|
||||||
|
expectedSources = listOf(
|
||||||
|
jvmUtil,
|
||||||
|
resolvePath("app", "jvmMain", "DependsOnLibJvm.kt")
|
||||||
|
).relativizeTo(projectPath),
|
||||||
|
output = output
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step 2 - js
|
||||||
|
*/
|
||||||
|
val jsUtil = resolvePath("lib", "jsMain", "UsedInAppJsAndLibTests.kt")
|
||||||
|
multiStepCheckIncrementalBuilds(
|
||||||
|
incrementalPath = jsUtil,
|
||||||
|
steps = commonSteps,
|
||||||
|
tasksExpectedToExecuteOnEachStep = setOf(
|
||||||
|
":app:compileKotlinJs",
|
||||||
|
":lib:compileKotlinJs"
|
||||||
|
),
|
||||||
|
afterEachStep = {
|
||||||
|
assertIncrementalCompilation(
|
||||||
|
listOf(
|
||||||
|
jsUtil,
|
||||||
|
resolvePath("app", "jsMain", "DependsOnLibJs.kt")
|
||||||
|
).relativizeTo(projectPath)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step 3 - native
|
||||||
|
*/
|
||||||
|
val nativeUtil = resolvePath("lib", "nativeMain", "UsedInAppNativeAndLibTests.kt")
|
||||||
|
multiStepCheckIncrementalBuilds(
|
||||||
|
incrementalPath = nativeUtil,
|
||||||
|
steps = commonSteps,
|
||||||
|
tasksExpectedToExecuteOnEachStep = setOf(
|
||||||
|
":app:compileKotlinNative",
|
||||||
|
":lib:compileKotlinNative"
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main smoke tests for api changes on the source set boundary
|
||||||
|
*/
|
||||||
@DisplayName("Verify IC builds on change in app/commonMain")
|
@DisplayName("Verify IC builds on change in app/commonMain")
|
||||||
@GradleTest
|
@GradleTest
|
||||||
fun testTouchAppCommon(gradleVersion: GradleVersion) {
|
@TestMetadata("generic-kmp-app-plus-lib-with-tests")
|
||||||
/**
|
fun testTouchAppCommon(gradleVersion: GradleVersion) = withProject(gradleVersion) {
|
||||||
* [C-M] touch appCommon, rebuild appJs
|
build("assemble")
|
||||||
* Variants: 1. code-compatible ABI breakage (change deduced return type), 2. no ABI breakage, 3. error + fix
|
|
||||||
*/
|
|
||||||
|
|
||||||
//TODO KT-56963 : confirm and create issues for these source-compatible changes
|
val utilPath = resolvePath("app", "commonMain", "UsedInAppPlatform.kt")
|
||||||
//utilKtPath.replaceFirst("fun multiplyByTwo(n: Int): Int", "fun <T> multiplyByTwo(n: T): T") - breaks native
|
|
||||||
//utilKtPath.replaceFirst("fun multiplyByTwo(n: Int): Int", "fun multiplyByTwo(n: Int, unused: Int = 42): Int") - breaks js
|
multiStepCheckIncrementalBuilds(
|
||||||
|
incrementalPath = utilPath,
|
||||||
|
steps = listOf(
|
||||||
|
"1_changeReturnType",
|
||||||
|
"2_addUnusedParameter"
|
||||||
|
// test changes in a different order for robustness
|
||||||
|
),
|
||||||
|
tasksExpectedToExecuteOnEachStep = setOf(
|
||||||
|
":app:compileCommonMainKotlinMetadata",
|
||||||
|
":app:compileKotlinJvm",
|
||||||
|
":app:compileKotlinJs",
|
||||||
|
":app:compileKotlinNative"
|
||||||
|
),
|
||||||
|
afterEachStep = {
|
||||||
|
assertIncrementalCompilation(
|
||||||
|
listOf(
|
||||||
|
utilPath,
|
||||||
|
resolvePath("app", "jsMain", "DependsOnAppCommon.kt"),
|
||||||
|
resolvePath("app", "jvmMain", "DependsOnAppCommon.kt")
|
||||||
|
).relativizeTo(projectPath)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Platform changes in a non-dependency shouldn't affect anything else
|
||||||
|
*/
|
||||||
@DisplayName("Verify IC builds on change in app/platformMain")
|
@DisplayName("Verify IC builds on change in app/platformMain")
|
||||||
@GradleTest
|
@GradleTest
|
||||||
fun testTouchAppPlatform(gradleVersion: GradleVersion) {
|
@TestMetadata("generic-kmp-app-plus-lib-with-tests")
|
||||||
/**
|
fun testTouchAppPlatform(gradleVersion: GradleVersion) = withProject(gradleVersion) {
|
||||||
* [C-M] touch appJs, rebuild appJs
|
build("assemble")
|
||||||
* Variants: 1. code-compatible ABI breakage (change deduced return type), 2. no ABI breakage, 3. error + fix
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step 1 - jvm
|
||||||
|
*/
|
||||||
|
val changedJvmSource = resolvePath("app", "jvmMain", "UnusedJvm.kt")
|
||||||
|
.replaceWithVersion("addParent")
|
||||||
|
checkIncrementalBuild(
|
||||||
|
tasksExpectedToExecute = setOf(":app:compileKotlinJvm")
|
||||||
|
) {
|
||||||
|
assertCompiledKotlinSources(listOf(changedJvmSource).relativizeTo(projectPath), output)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step 2 - js
|
||||||
|
*/
|
||||||
|
val changedJsSource = resolvePath("app", "jsMain", "UnusedJs.kt")
|
||||||
|
.replaceWithVersion("addParent")
|
||||||
|
checkIncrementalBuild(
|
||||||
|
tasksExpectedToExecute = setOf(":app:compileKotlinJs")
|
||||||
|
) {
|
||||||
|
assertIncrementalCompilation(listOf(changedJsSource).relativizeTo(projectPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step 3 - native
|
||||||
|
*/
|
||||||
|
resolvePath("app", "nativeMain", "UnusedNative.kt")
|
||||||
|
.replaceWithVersion("addParent")
|
||||||
|
checkIncrementalBuild(
|
||||||
|
tasksExpectedToExecute = setOf(":app:compileKotlinNative")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.testbase
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.testbase.TransformationsGeneratorState.changeCounter
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
import kotlin.io.path.appendText
|
||||||
|
|
||||||
|
|
||||||
|
fun Path.addPrivateVal(): Path {
|
||||||
|
appendText("\nprivate val integerValue${changeCounter.incrementAndGet()} = 24\n")
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Path.addPublicVal(): Path {
|
||||||
|
appendText("\nval integerValue${changeCounter.incrementAndGet()} = 25\n")
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that generated names are unique.
|
||||||
|
*/
|
||||||
|
private object TransformationsGeneratorState {
|
||||||
|
val changeCounter = AtomicInteger(0)
|
||||||
|
}
|
||||||
+19
-2
@@ -35,7 +35,12 @@ fun BuildResult.assertTasksExecuted(vararg tasks: String) {
|
|||||||
tasks.forEach { task ->
|
tasks.forEach { task ->
|
||||||
assert(task(task)?.outcome == TaskOutcome.SUCCESS) {
|
assert(task(task)?.outcome == TaskOutcome.SUCCESS) {
|
||||||
printBuildOutput()
|
printBuildOutput()
|
||||||
"Task $task didn't have 'SUCCESS' state: ${task(task)?.outcome}"
|
"""
|
||||||
|
Task $task didn't have 'SUCCESS' state: ${task(task)?.outcome}
|
||||||
|
|
||||||
|
Actual task states:
|
||||||
|
${getActualTasksAsString()}
|
||||||
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,7 +97,12 @@ fun BuildResult.assertTasksUpToDate(vararg tasks: String) {
|
|||||||
tasks.forEach { task ->
|
tasks.forEach { task ->
|
||||||
assert(task(task)?.outcome == TaskOutcome.UP_TO_DATE) {
|
assert(task(task)?.outcome == TaskOutcome.UP_TO_DATE) {
|
||||||
printBuildOutput()
|
printBuildOutput()
|
||||||
"Task $task didn't have 'UP-TO-DATE' state: ${task(task)?.outcome}"
|
"""
|
||||||
|
Task $task didn't have 'UP-TO-DATE' state: ${task(task)?.outcome}
|
||||||
|
|
||||||
|
Actual task states:
|
||||||
|
${getActualTasksAsString()}
|
||||||
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,6 +214,13 @@ fun BuildResult.assertTasksInBuildOutput(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns printable list of tasks that actually executed.
|
||||||
|
*/
|
||||||
|
private fun BuildResult.getActualTasksAsString(): String {
|
||||||
|
return tasks.joinToString("\n") { "${it.path} - ${it.outcome}" }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method parses the output of a 'tasks --all' build
|
* Method parses the output of a 'tasks --all' build
|
||||||
* and returns a list of all the tasks mentioned in it.
|
* and returns a list of all the tasks mentioned in it.
|
||||||
|
|||||||
+7
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.util
|
|||||||
import org.jetbrains.kotlin.gradle.testbase.createTempDirDeleteOnExit
|
import org.jetbrains.kotlin.gradle.testbase.createTempDirDeleteOnExit
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.copyTo
|
||||||
import kotlin.io.path.readText
|
import kotlin.io.path.readText
|
||||||
import kotlin.io.path.writeText
|
import kotlin.io.path.writeText
|
||||||
|
|
||||||
@@ -116,3 +117,9 @@ fun File.replaceText(regex: Regex, replacement: String) {
|
|||||||
fun Path.replaceFirst(oldValue: String, newValue: String) {
|
fun Path.replaceFirst(oldValue: String, newValue: String) {
|
||||||
writeText(readText().replaceFirst(oldValue, newValue))
|
writeText(readText().replaceFirst(oldValue, newValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Path.replaceWithVersion(versionSuffix: String): Path {
|
||||||
|
val otherVersion = resolveSibling("$fileName.$versionSuffix")
|
||||||
|
otherVersion.copyTo(this, overwrite = true)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
expect fun foo(): Any
|
expect fun foo(): Any
|
||||||
|
|
||||||
fun fooImpl() = secret
|
fun fooImpl() = commonMainValue
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
val secret = 1
|
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
val commonMainValue = 1
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
val commonMainValue = "it's a string now"
|
||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
class AppCommonUnusedClass {
|
open class AppCommonUnusedClass {
|
||||||
fun bar() = 234
|
fun bar() = 234
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun appCommonFunForAppPlatform() = "Yes"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun appCommonFunForAppPlatform() = 90
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun appCommonFunForAppPlatform(delta: Double = 1.0) = 90
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
import kotlin.test.Test
|
|
||||||
import kotlin.test.assertEquals
|
|
||||||
|
|
||||||
class AppCommonTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun sayYesSaysYes() {
|
|
||||||
assertEquals("Yes", appCommonFunForAppPlatformAndAppCommonTest())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class AppCommonTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun threeIsThree() {
|
||||||
|
assertEquals(3, 3)
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
class AppJsUnusedClassWithDependencies {
|
class AppJsUnusedClassWithDependencies {
|
||||||
val line = appCommonFunForAppPlatformAndAppCommonTest()
|
val line = appCommonFunForAppPlatform()
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class AppJsUnusedClass : AppCommonUnusedClass() {
|
||||||
|
fun foo() = 234
|
||||||
|
}
|
||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
class AppJvmUnusedClassWithDependencies {
|
class AppJvmUnusedClassWithDependencies {
|
||||||
val line = appCommonFunForAppPlatformAndAppCommonTest()
|
val line = appCommonFunForAppPlatform()
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class AppJvmUnusedClass : AppCommonUnusedClass() {
|
||||||
|
fun doBar() = 2
|
||||||
|
}
|
||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
class AppNativeUnusedClassWithDependencies {
|
class AppNativeUnusedClassWithDependencies {
|
||||||
val line = appCommonFunForAppPlatformAndAppCommonTest()
|
val line = appCommonFunForAppPlatform()
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class AppNativeUnusedClass : AppCommonUnusedClass() {
|
||||||
|
fun queueSomething() = Unit
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun libCommonFunForAppCommon(unused: Any? = null) = Double.NaN
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun libCommonFunForAppCommon(unused: Any? = null): String? = null
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
open class LibCommonClassForAppPlatform(
|
||||||
|
val length: Int,
|
||||||
|
val builder: String,
|
||||||
|
) {
|
||||||
|
val introduceNewPublicApi = "Yes, please"
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun libJsPlatformUtil(unused: Boolean = true): Int = 0
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun libJsPlatformUtil(unused: Boolean = true): Double = 20.0
|
||||||
+1
-1
@@ -5,7 +5,7 @@ class LibJsTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun jsUtilReturns0() {
|
fun jsUtilReturns0() {
|
||||||
assertEquals(0, libJsPlatformUtil())
|
assertEquals(0, libJsPlatformUtil().toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun libJvmPlatformUtil(unused: Boolean = true): Int = 400
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun libJvmPlatformUtil(unused: Boolean = true): Double = 20.0
|
||||||
+1
-1
@@ -5,7 +5,7 @@ class LibJvmTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun jvmUtilReturns400() {
|
fun jvmUtilReturns400() {
|
||||||
assertEquals(400, libJvmPlatformUtil())
|
assertEquals(400, libJvmPlatformUtil().toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun libNativePlatformUtil(unused: Boolean = true): Int = 800
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fun libNativePlatformUtil(unused: Boolean = true): Double = 20.0
|
||||||
+1
-1
@@ -5,7 +5,7 @@ class LibNativeTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun nativeUtilReturns800() {
|
fun nativeUtilReturns800() {
|
||||||
assertEquals(800, libNativePlatformUtil())
|
assertEquals(800, libNativePlatformUtil().toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user