[IC] Smoke tests for KMP IC, part 1
Assert reasonable compile avoidance when basic changes are made in a multiplatform project ^Relates to KT-56963 Merge-request: KT-MR-13032 Merged-by: Evgenii Mazhukin <evgenii.mazhukin@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
3ff16f7798
commit
5973951f71
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.mpp
|
||||
|
||||
import org.gradle.api.logging.LogLevel
|
||||
import org.gradle.testkit.runner.BuildResult
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.jetbrains.kotlin.gradle.testbase.relativizeTo
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.appendText
|
||||
|
||||
abstract class KmpIncrementalITBase : KGPBaseTest() {
|
||||
|
||||
override val defaultBuildOptions: BuildOptions
|
||||
get() = super.defaultBuildOptions.copyEnsuringK2()
|
||||
|
||||
protected open val gradleTask = "assemble"
|
||||
protected open val projectName = "generic-kmp-app-plus-lib-with-tests"
|
||||
protected open val mainCompileTasks = setOf(
|
||||
":app:compileKotlinJvm",
|
||||
":app:compileKotlinJs",
|
||||
":app:compileKotlinNative",
|
||||
":lib:compileKotlinJvm",
|
||||
":lib:compileKotlinJs",
|
||||
":lib:compileKotlinNative",
|
||||
)
|
||||
|
||||
protected open fun withProject(gradleVersion: GradleVersion, test: TestProject.() -> Unit): Unit {
|
||||
nativeProject(
|
||||
projectName,
|
||||
gradleVersion,
|
||||
configureSubProjects = true,
|
||||
test = test
|
||||
)
|
||||
}
|
||||
|
||||
protected open fun TestProject.touchAndGet(subproject: String, srcDir: String, name: String): Path {
|
||||
val path = subProject(subproject).kotlinSourcesDir(srcDir).resolve(name)
|
||||
path.appendText("private val nothingMuch = 24")
|
||||
return path
|
||||
}
|
||||
|
||||
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)) {
|
||||
assertSuccessOrUTD(
|
||||
allTasks = mainCompileTasks,
|
||||
executedTasks = executedTasks
|
||||
)
|
||||
incrementalPath?.let {
|
||||
assertIncrementalCompilation(listOf(it).relativizeTo(projectPath))
|
||||
}
|
||||
assertions()
|
||||
}
|
||||
}
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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.mpp.smoke
|
||||
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.mpp.KmpIncrementalITBase
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
|
||||
@DisplayName("Basic incremental scenarios with KMP - K2")
|
||||
@MppGradlePluginTests
|
||||
open class BasicIncrementalCompilationIT : KmpIncrementalITBase() {
|
||||
|
||||
@DisplayName("Base test case - local change, local recompilation")
|
||||
@GradleTest
|
||||
fun testStrictlyLocalChange(gradleVersion: GradleVersion): Unit = withProject(gradleVersion) {
|
||||
build("assemble")
|
||||
|
||||
/**
|
||||
* Step 1: touch app:common, no abi change
|
||||
*/
|
||||
|
||||
testCase(
|
||||
incrementalPath = touchAndGet("app", "commonMain", "PlainPublicClass.kt"),
|
||||
executedTasks = setOf(
|
||||
":app:compileKotlinJvm",
|
||||
":app:compileKotlinJs",
|
||||
":app:compileKotlinNative"
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* Step 2: touch app:jvm, no abi change
|
||||
*/
|
||||
|
||||
val appJvmClassKt = touchAndGet("app", "jvmMain", "PlainPublicClassJvm.kt")
|
||||
testCase(
|
||||
incrementalPath = null, //TODO: it just doesn't print "Incremental compilation completed", why? (KT-63476)
|
||||
executedTasks = setOf(":app:compileKotlinJvm")
|
||||
) {
|
||||
assertCompiledKotlinSources(listOf(appJvmClassKt).relativizeTo(projectPath), output)
|
||||
}
|
||||
|
||||
/**
|
||||
* Step 3: touch app:js, no abi change
|
||||
*/
|
||||
|
||||
testCase(
|
||||
incrementalPath = touchAndGet("app", "jsMain", "PlainPublicClassJs.kt"),
|
||||
executedTasks = setOf(":app:compileKotlinJs"),
|
||||
)
|
||||
|
||||
/**
|
||||
* Step 4: touch app:native, no abi change
|
||||
*/
|
||||
|
||||
touchAndGet("app", "nativeMain", "PlainPublicClassNative.kt")
|
||||
testCase(
|
||||
incrementalPath = null, // no native incremental compilation - see KT-62824
|
||||
executedTasks = setOf(":app:compileKotlinNative"),
|
||||
)
|
||||
|
||||
/**
|
||||
* Step 5: touch lib:common, no abi change
|
||||
*/
|
||||
|
||||
testCase(
|
||||
incrementalPath = touchAndGet("lib", "commonMain", "CommonUtil.kt"),
|
||||
executedTasks = mainCompileTasks // TODO: KT-62642 - bad compile avoidance here
|
||||
)
|
||||
|
||||
/**
|
||||
* Step 6: touch lib:jvm, no abi change
|
||||
*/
|
||||
|
||||
val libJvmUtilKt = touchAndGet("lib", "jvmMain", "libJvmPlatformUtil.kt")
|
||||
testCase(
|
||||
incrementalPath = null, //TODO: it just doesn't print "Incremental compilation completed", why? (KT-63476)
|
||||
executedTasks = setOf(":app:compileKotlinJvm", ":lib:compileKotlinJvm"),
|
||||
) {
|
||||
assertCompiledKotlinSources(listOf(libJvmUtilKt).relativizeTo(projectPath), output)
|
||||
}
|
||||
|
||||
/**
|
||||
* Step 7: touch lib:js, no abi change
|
||||
*/
|
||||
|
||||
testCase(
|
||||
incrementalPath = touchAndGet("lib", "jsMain", "libJsPlatformUtil.kt"),
|
||||
executedTasks = setOf(":app:compileKotlinJs", ":lib:compileKotlinJs"),
|
||||
)
|
||||
|
||||
/**
|
||||
* Step 8: touch lib:native, no abi change
|
||||
*/
|
||||
|
||||
touchAndGet("lib", "nativeMain", "libNativePlatformUtil.kt")
|
||||
testCase(
|
||||
incrementalPath = null,
|
||||
executedTasks = setOf(":app:compileKotlinNative", ":lib:compileKotlinNative"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Basic incremental scenarios with Kotlin Multiplatform - K1")
|
||||
class BasicIncrementalCompilationK1IT : BasicIncrementalCompilationIT() {
|
||||
override val defaultBuildOptions: BuildOptions
|
||||
get() = super.defaultBuildOptions.copyEnsuringK1()
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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.mpp.smoke
|
||||
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.mpp.KmpIncrementalITBase
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
|
||||
@DisplayName("Basic incremental scenarios with tests in KMP - K2")
|
||||
@MppGradlePluginTests
|
||||
open class BasicTestIncrementalCompilationIT : KmpIncrementalITBase() {
|
||||
override val mainCompileTasks: Set<String>
|
||||
get() = setOf(
|
||||
":app:compileTestKotlinJvm",
|
||||
":lib:compileTestKotlinJvm",
|
||||
|
||||
":app:compileTestKotlinNative",
|
||||
":lib:compileTestKotlinNative",
|
||||
|
||||
":app:compileTestKotlinJs",
|
||||
":lib:compileTestKotlinJs",
|
||||
|
||||
":app:jsTest",
|
||||
":lib:jsTest",
|
||||
|
||||
":app:jvmTest",
|
||||
":lib:jvmTest",
|
||||
|
||||
":app:nativeTest",
|
||||
":lib:nativeTest",
|
||||
)
|
||||
override val gradleTask: String
|
||||
get() = "build"
|
||||
|
||||
@DisplayName("KMP tests are rebuilt when affected")
|
||||
@GradleTest
|
||||
fun testAffectingTestDependencies(gradleVersion: GradleVersion): Unit = withProject(gradleVersion) {
|
||||
build("build")
|
||||
|
||||
/**
|
||||
* Step 1 - touch lib/common, affect all tests in app and lib
|
||||
*/
|
||||
|
||||
testCase(
|
||||
incrementalPath = touchAndGet("lib", "commonMain", "CommonUtil.kt"),
|
||||
executedTasks = mainCompileTasks,
|
||||
)
|
||||
|
||||
/**
|
||||
* Step 2 - touch app/common, affect all tests in app
|
||||
*/
|
||||
|
||||
testCase(
|
||||
incrementalPath = touchAndGet("app", "commonMain", "PlainPublicClass.kt"),
|
||||
executedTasks = setOf(
|
||||
":app:compileTestKotlinJvm",
|
||||
":app:compileTestKotlinNative",
|
||||
":app:compileTestKotlinJs",
|
||||
":app:jsTest",
|
||||
":app:jvmTest",
|
||||
":app:nativeTest",
|
||||
),
|
||||
)
|
||||
|
||||
/**
|
||||
* Step 3 - touch app/jvm, affect jvm tests in app
|
||||
*/
|
||||
|
||||
val touchedAppJvm = touchAndGet("app", "jvmMain", "PlainPublicClassJvm.kt")
|
||||
testCase(
|
||||
incrementalPath = null,
|
||||
executedTasks = setOf(
|
||||
":app:compileTestKotlinJvm",
|
||||
":app:jvmTest",
|
||||
),
|
||||
) {
|
||||
assertCompiledKotlinSources(listOf(touchedAppJvm).relativizeTo(projectPath), output) //KT-63476
|
||||
}
|
||||
|
||||
/**
|
||||
* Step 4 - touch app/js, affect js tests in app
|
||||
*/
|
||||
|
||||
testCase(
|
||||
incrementalPath = touchAndGet("app", "jsMain", "PlainPublicClassJs.kt"),
|
||||
executedTasks = setOf(
|
||||
":app:compileTestKotlinJs",
|
||||
":app:jsTest",
|
||||
),
|
||||
)
|
||||
|
||||
/**
|
||||
* Step 5 - touch app/native, affect native tests in app
|
||||
*/
|
||||
|
||||
touchAndGet("app", "nativeMain", "PlainPublicClassNative.kt")
|
||||
testCase(
|
||||
incrementalPath = null,
|
||||
executedTasks = setOf(
|
||||
":app:compileTestKotlinNative",
|
||||
":app:nativeTest",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Basic incremental scenarios with tests in KMP - K1")
|
||||
class BasicTestIncrementalCompilationK1IT : BasicTestIncrementalCompilationIT() {
|
||||
override val defaultBuildOptions: BuildOptions
|
||||
get() = super.defaultBuildOptions.copyEnsuringK1()
|
||||
}
|
||||
+9
-17
@@ -3,7 +3,7 @@
|
||||
* 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.mpp
|
||||
package org.jetbrains.kotlin.gradle.mpp.smoke
|
||||
|
||||
import org.gradle.api.logging.LogLevel
|
||||
import org.gradle.util.GradleVersion
|
||||
@@ -12,28 +12,20 @@ import org.jetbrains.kotlin.gradle.util.replaceFirst
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import kotlin.io.path.appendText
|
||||
|
||||
/**
|
||||
*
|
||||
* Touch file with expect fun, target IC adds actual to the build set
|
||||
* Variants: expect class
|
||||
* Touch file with actual fun, target IC adds expect to the build set
|
||||
* Variants: expect class
|
||||
*
|
||||
*/
|
||||
@DisplayName("Incremental scenarios with expect/actual - K2")
|
||||
@MppGradlePluginTests
|
||||
open class ExpectActualIncrementalCompilationIT : KGPBaseTest() {
|
||||
override val defaultBuildOptions: BuildOptions
|
||||
get() = super.defaultBuildOptions.copyEnsuringK2()
|
||||
|
||||
@DisplayName("Base test case - local change, local recompilation")
|
||||
@GradleTest
|
||||
fun testStrictlyLocalChange(gradleVersion: GradleVersion) {
|
||||
nativeProject("expect-actual-fun-or-class-ic", gradleVersion) {
|
||||
build("assemble")
|
||||
|
||||
val valueKtPath = kotlinSourcesDir("commonMain").resolve("Value.kt")
|
||||
valueKtPath.appendText("val irrelevant = 2")
|
||||
|
||||
build("assemble", buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||
assertTasksExecuted(":compileKotlinJvm", ":compileKotlinJs", ":compileKotlinNative")
|
||||
assertIncrementalCompilation(listOf(valueKtPath).relativizeTo(projectPath))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("File with actual declaration needs recompiling")
|
||||
@GradleTest
|
||||
fun testRecompilationOfActualFun(gradleVersion: GradleVersion) {
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.mpp.smoke
|
||||
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.BuildOptions
|
||||
import org.jetbrains.kotlin.gradle.testbase.GradleTest
|
||||
import org.jetbrains.kotlin.gradle.testbase.KGPBaseTest
|
||||
import org.jetbrains.kotlin.gradle.testbase.MppGradlePluginTests
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
|
||||
@Disabled("KT-56963")
|
||||
@DisplayName("Basic multi-module incremental scenarios with KMP - K2")
|
||||
@MppGradlePluginTests
|
||||
open class MultiModuleIncrementalCompilationIT : KGPBaseTest() {
|
||||
override val defaultBuildOptions: BuildOptions
|
||||
get() = super.defaultBuildOptions.copyEnsuringK2()
|
||||
|
||||
@DisplayName("Verify IC builds on change in lib/commonMain")
|
||||
@GradleTest
|
||||
fun testTouchLibCommon(gradleVersion: GradleVersion) {
|
||||
/**
|
||||
* [Cross-Module] touch libCommon, affect appCommon, appJs
|
||||
* Variants: 1. code-compatible ABI breakage (change deduced return type), 2. no ABI breakage, 3. error + fix
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@DisplayName("Verify IC builds on change in lib/platformMain")
|
||||
@GradleTest
|
||||
fun testTouchLibPlatform(gradleVersion: GradleVersion) {
|
||||
/**
|
||||
* [C-M] touch lbJs, affect appJs
|
||||
* Variants: 1. code-compatible ABI breakage (change deduced return type), 2. no ABI breakage, 3. error + fix
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@DisplayName("Verify IC builds on change in app/commonMain")
|
||||
@GradleTest
|
||||
fun testTouchAppCommon(gradleVersion: GradleVersion) {
|
||||
/**
|
||||
* [C-M] touch appCommon, rebuild appJs
|
||||
* 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
|
||||
//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
|
||||
}
|
||||
|
||||
@DisplayName("Verify IC builds on change in app/platformMain")
|
||||
@GradleTest
|
||||
fun testTouchAppPlatform(gradleVersion: GradleVersion) {
|
||||
/**
|
||||
* [C-M] touch appJs, rebuild appJs
|
||||
* Variants: 1. code-compatible ABI breakage (change deduced return type), 2. no ABI breakage, 3. error + fix
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Incremental scenarios with expect/actual - K1")
|
||||
class MultiModuleIncrementalCompilationK1IT : MultiModuleIncrementalCompilationIT() {
|
||||
override val defaultBuildOptions: BuildOptions
|
||||
get() = super.defaultBuildOptions.copyEnsuringK1()
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
js()
|
||||
<SingleNativeTarget>("native")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
js {
|
||||
nodejs()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation(project(":lib"))
|
||||
}
|
||||
}
|
||||
val commonTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun sayYes() = "Yes"
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
expect class Detail {
|
||||
val key: String
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class PlainPublicClass {
|
||||
fun bar() = 234
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class TrivialTest {
|
||||
|
||||
@Test
|
||||
fun sayYesSaysYes() {
|
||||
assertEquals("Yes", sayYes())
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
actual class Detail {
|
||||
actual val key: String = "42"
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class PlainPublicClassJs {
|
||||
fun foo() = 234
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun useLibJsPlatformUtil() = libJsPlatformUtil()
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
actual class Detail {
|
||||
actual val key: String = "422"
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class PlainPublicClassJvm {
|
||||
fun doBar() = 2
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun useLibJvmPlatformUtil() = libJvmPlatformUtil()
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
actual class Detail {
|
||||
actual val key: String = "definitely not ios"
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class PlainPublicClassNative {
|
||||
fun queueSomething() = Unit
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun useLibNativePlatformUtil() = libNativePlatformUtil()
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
js()
|
||||
<SingleNativeTarget>("native")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
js {
|
||||
nodejs()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
val commonTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun multiplyByTwo(n: Int): Int {
|
||||
return n * 2
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
expect fun calc(expression: String): Double
|
||||
+1
@@ -0,0 +1 @@
|
||||
private val bar = 12
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
actual fun calc(expression: String): Double {
|
||||
return Double.NaN
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun libJsPlatformUtil(): Int = 0
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class AdvancedTest {
|
||||
|
||||
@Test
|
||||
fun jsUtilReturns0() {
|
||||
assertEquals(0, libJsPlatformUtil())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun commonUtilTest() {
|
||||
assertEquals(2, multiplyByTwo(1))
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
actual fun calc(expression: String): Double {
|
||||
return expression.toDoubleOrNull()?.let { it * 2 } ?: 0.0
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun libJvmPlatformUtil(): Int = 400
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class AdvancedTest {
|
||||
|
||||
@Test
|
||||
fun jvmUtilReturns400() {
|
||||
assertEquals(400, libJvmPlatformUtil())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun commonUtilTest() {
|
||||
assertEquals(2, multiplyByTwo(1))
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
actual fun calc(expression: String): Double {
|
||||
return 15.0
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun libNativePlatformUtil(): Int = 800
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class AdvancedTest {
|
||||
|
||||
@Test
|
||||
fun nativeUtilReturns800() {
|
||||
assertEquals(800, libNativePlatformUtil())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun commonUtilTest() {
|
||||
assertEquals(2, multiplyByTwo(1))
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
include(":app")
|
||||
include(":lib")
|
||||
Reference in New Issue
Block a user