Add a few integration tests for the new MPP plugin
This commit is contained in:
+211
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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
|
||||
|
||||
import org.jetbrains.kotlin.gradle.util.modify
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
class NewMultiplatformIT : BaseGradleIT() {
|
||||
val gradleVersion = GradleVersionRequired.AtLeast("4.8")
|
||||
|
||||
private fun Project.targetClassesDir(targetName: String, sourceSetName: String = "main") =
|
||||
classesDir(sourceSet = "$targetName/$sourceSetName")
|
||||
|
||||
@Test
|
||||
fun testLibAndApp() {
|
||||
val libProject = Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")
|
||||
val appProject = Project("sample-app", gradleVersion, "new-mpp-lib-and-app")
|
||||
|
||||
with(libProject) {
|
||||
build("publish") {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(":compileKotlinJvm6", ":compileKotlinNodeJs", ":jvm6Jar", ":nodeJsJar")
|
||||
val repoDir = projectDir.resolve("repo")
|
||||
val moduleDir = repoDir.resolve("com/example/sample-lib/1.0")
|
||||
val jvmJarName = "sample-lib-1.0-jvm6.jar"
|
||||
val jsJarName = "sample-lib-1.0-nodeJs.jar"
|
||||
listOf(jvmJarName, jsJarName, "sample-lib-1.0.module").forEach {
|
||||
Assert.assertTrue(moduleDir.resolve(it).exists())
|
||||
}
|
||||
|
||||
val jvmJarEntries = ZipFile(moduleDir.resolve(jvmJarName)).entries().asSequence().map { it.name }.toSet()
|
||||
Assert.assertTrue("com/example/lib/CommonKt.class" in jvmJarEntries)
|
||||
Assert.assertTrue("com/example/lib/MainKt.class" in jvmJarEntries)
|
||||
|
||||
val jsJar = ZipFile(moduleDir.resolve(jsJarName))
|
||||
val compiledJs = jsJar.getInputStream(jsJar.getEntry("sample-lib.js")).reader().readText()
|
||||
Assert.assertTrue("function id(" in compiledJs)
|
||||
Assert.assertTrue("function idUsage(" in compiledJs)
|
||||
Assert.assertTrue("function expectedFun(" in compiledJs)
|
||||
Assert.assertTrue("function main(" in compiledJs)
|
||||
}
|
||||
}
|
||||
|
||||
val libLocalRepoUri = libProject.projectDir.resolve("repo").toURI()
|
||||
|
||||
with(appProject) {
|
||||
setupWorkingDir()
|
||||
gradleBuildScript().appendText("\nrepositories { maven { url '$libLocalRepoUri' } }")
|
||||
|
||||
fun CompiledProject.checkAppBuild() {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(":compileKotlinJvm6", ":compileKotlinJvm8", ":compileKotlinNodeJs")
|
||||
|
||||
projectDir.resolve(targetClassesDir("jvm6")).run {
|
||||
Assert.assertTrue(resolve("com/example/app/AKt.class").exists())
|
||||
Assert.assertTrue(this.resolve("com/example/app/UseBothIdsKt.class").exists())
|
||||
}
|
||||
|
||||
projectDir.resolve(targetClassesDir("jvm8")).run {
|
||||
Assert.assertTrue(resolve("com/example/app/AKt.class").exists())
|
||||
Assert.assertTrue(resolve("com/example/app/UseBothIdsKt.class").exists())
|
||||
Assert.assertTrue(resolve("com/example/app/Jdk8ApiUsageKt.class").exists())
|
||||
}
|
||||
|
||||
projectDir.resolve(targetClassesDir("nodeJs")).resolve("sample-app.js").readText().run {
|
||||
Assert.assertTrue(contains("console.info"))
|
||||
Assert.assertTrue(contains("function nodeJsMain("))
|
||||
}
|
||||
}
|
||||
|
||||
build("assemble") {
|
||||
checkAppBuild()
|
||||
}
|
||||
|
||||
// Now run again with a project dependency instead of a module one:
|
||||
libProject.projectDir.copyRecursively(projectDir.resolve(libProject.projectDir.name))
|
||||
projectDir.resolve("settings.gradle").appendText("\ninclude '${libProject.projectDir.name}'")
|
||||
gradleBuildScript().modify { it.replace("'com.example:sample-lib:1.0'", "project(':${libProject.projectDir.name}')") }
|
||||
|
||||
build("assemble", "--rerun-tasks") {
|
||||
checkAppBuild()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSourceSetCyclicDependencyDetection() = with(Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")) {
|
||||
setupWorkingDir()
|
||||
gradleBuildScript().appendText("\n" + """
|
||||
kotlin.sourceSets {
|
||||
a
|
||||
b { dependsOn a }
|
||||
c { dependsOn b }
|
||||
a.dependsOn(c)
|
||||
}
|
||||
""".trimIndent())
|
||||
|
||||
build("assemble") {
|
||||
assertFailed()
|
||||
assertContains("a -> c -> b -> a")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testJvmWithJavaEquivalence() = with(Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")) {
|
||||
lateinit var classesWithoutJava: Set<String>
|
||||
|
||||
fun getFilePathsSet(inDirectory: String): Set<String> {
|
||||
val dir = projectDir.resolve(inDirectory)
|
||||
return dir.walk().filter { it.isFile }.map { it.relativeTo(dir).path.replace('\\', '/') }.toSet()
|
||||
}
|
||||
|
||||
build("assemble") {
|
||||
assertSuccessful()
|
||||
classesWithoutJava = getFilePathsSet("build/classes")
|
||||
}
|
||||
|
||||
gradleBuildScript().modify { it.replace("presets.jvm", "presets.jvmWithJava") }
|
||||
|
||||
projectDir.resolve("src/main/java").apply {
|
||||
mkdirs()
|
||||
mkdir()
|
||||
// Check that Java can access the dependencies (kotlin-stdlib):
|
||||
resolve("JavaClassInJava.java").writeText("""
|
||||
package com.example.lib;
|
||||
import kotlin.sequences.Sequence;
|
||||
class JavaClassInJava {
|
||||
Sequence<String> makeSequence() { throw new UnsupportedOperationException(); }
|
||||
}
|
||||
""".trimIndent())
|
||||
|
||||
// Add a Kotlin source file in the Java source root and check that it is compiled:
|
||||
resolve("KotlinClassInJava.kt").writeText("""
|
||||
package com.example.lib
|
||||
class KotlinClassInJava
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
build("clean", "assemble") {
|
||||
assertSuccessful()
|
||||
val expectedClasses =
|
||||
classesWithoutJava +
|
||||
"kotlin/jvm6/main/com/example/lib/KotlinClassInJava.class" +
|
||||
"java/main/com/example/lib/JavaClassInJava.class"
|
||||
val actualClasses = getFilePathsSet("build/classes")
|
||||
Assert.assertEquals(expectedClasses, actualClasses)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLibWithTests() = with(Project("new-mpp-lib-with-tests", gradleVersion)) {
|
||||
build("check") {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(
|
||||
// compilation tasks:
|
||||
":compileKotlinJs",
|
||||
":compileTestKotlinJs",
|
||||
":compileKotlinJvmWithoutJava",
|
||||
":compileTestKotlinJvmWithoutJava",
|
||||
":compileKotlinJvmWithJava",
|
||||
":compileJava",
|
||||
":compileTestKotlinJvmWithJava",
|
||||
":compileTestJava",
|
||||
// test tasks:
|
||||
":jsTest", // does not run any actual tests for now
|
||||
":jvmWithoutJavaTest",
|
||||
":test"
|
||||
)
|
||||
|
||||
val expectedKotlinOutputFiles = listOf(
|
||||
kotlinClassesDir(sourceSet = "js/main") + "new-mpp-lib-with-tests.js",
|
||||
kotlinClassesDir(sourceSet = "js/test") + "new-mpp-lib-with-tests_test.js",
|
||||
*kotlinClassesDir(sourceSet = "jvmWithJava/main").let {
|
||||
arrayOf(
|
||||
it + "com/example/lib/JavaClassUsageKt.class",
|
||||
it + "com/example/lib/CommonKt.class",
|
||||
it + "META-INF/new-mpp-lib-with-tests.kotlin_module"
|
||||
)
|
||||
},
|
||||
*kotlinClassesDir(sourceSet = "jvmWithJava/test").let {
|
||||
arrayOf(
|
||||
it + "com/example/lib/TestCommonCode.class",
|
||||
it + "com/example/lib/TestWithJava.class",
|
||||
it + "META-INF/new-mpp-lib-with-tests.kotlin_module" // Note: same name as in main
|
||||
)
|
||||
},
|
||||
*kotlinClassesDir(sourceSet = "jvmWithoutJava/main").let {
|
||||
arrayOf(
|
||||
it + "com/example/lib/CommonKt.class",
|
||||
it + "com/example/lib/MainKt.class",
|
||||
it + "META-INF/new-mpp-lib-with-tests.kotlin_module"
|
||||
)
|
||||
},
|
||||
*kotlinClassesDir(sourceSet = "jvmWithoutJava/test").let {
|
||||
arrayOf(
|
||||
it + "com/example/lib/TestCommonCode.class",
|
||||
it + "com/example/lib/TestWithoutJava.class",
|
||||
it + "META-INF/new-mpp-lib-with-tests.kotlin_module" // Note: same name as in main
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
expectedKotlinOutputFiles.forEach { assertFileExists(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'kotlin-multiplatform'
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
// NB: Build of this module depends on 'sample-lib' publication. You need to add the local
|
||||
// repository where 'sample-lib' artifacts are published.
|
||||
}
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
implementation 'com.example:sample-lib:1.0'
|
||||
}
|
||||
}
|
||||
allJvm {
|
||||
dependsOn commonMain
|
||||
dependencies {
|
||||
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
|
||||
}
|
||||
}
|
||||
jvm6Main {
|
||||
dependsOn allJvm
|
||||
}
|
||||
jvm8Main {
|
||||
dependsOn allJvm
|
||||
dependencies {
|
||||
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
|
||||
}
|
||||
}
|
||||
nodeJsMain {
|
||||
dependencies {
|
||||
implementation 'org.jetbrains.kotlin:kotlin-stdlib-js'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
targets {
|
||||
fromPreset(presets.jvm, 'jvm6')
|
||||
fromPreset(presets.jvm, 'jvm8') {
|
||||
compilations.main {
|
||||
tasks.getByName(compileKotlinTaskName) {
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fromPreset(presets.js, 'nodeJs')
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
enableFeaturePreview('GRADLE_METADATA')
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.example.app
|
||||
|
||||
import com.example.lib.*
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println(id(123))
|
||||
println(idUsage(456))
|
||||
println(x())
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.example.app
|
||||
|
||||
import com.example.lib.id
|
||||
import com.example.lib.expectedFun
|
||||
|
||||
fun idUsage(x: Int): Int = id(x)
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
expectedFun()
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.example.app
|
||||
|
||||
import kotlin.streams.asStream
|
||||
|
||||
fun useJdk8Api() = listOf(1, 2, 3).asSequence().asStream()
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import kotlin.js.Console
|
||||
|
||||
import com.example.lib.*
|
||||
|
||||
external val console: Console
|
||||
|
||||
fun nodeJsMain(args: Array<String>) {
|
||||
console.info(id(123), idUsage(), expectedFun())
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
group 'com.example'
|
||||
version '1.0'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'kotlin-multiplatform'
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven { url "http://dl.bintray.com/kotlin/kotlinx.html/" }
|
||||
}
|
||||
|
||||
kotlin {
|
||||
targets {
|
||||
fromPreset(presets.jvm, 'jvm6')
|
||||
fromPreset(presets.js, 'nodeJs')
|
||||
}
|
||||
sourceSets {
|
||||
jvm6Main {
|
||||
dependencies {
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4'
|
||||
}
|
||||
}
|
||||
nodeJsMain {
|
||||
dependencies {
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-html-js:0.6.11'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kotlin.sourceSets.each { println it.kotlin.srcDirs }
|
||||
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven { url "file://${projectDir.absolutePath.replace('\\', '/')}/repo" }
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
enableFeaturePreview('GRADLE_METADATA')
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.example.lib
|
||||
|
||||
fun <T> id(t: T): T = t
|
||||
|
||||
expect fun expectedFun(): Unit
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.example.lib
|
||||
|
||||
fun x(): String = "x"
|
||||
|
||||
actual fun expectedFun() {
|
||||
println(id(x()))
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.example.lib
|
||||
|
||||
import com.example.lib.id
|
||||
import com.example.lib.expectedFun
|
||||
|
||||
fun idUsage() = id("123")
|
||||
|
||||
actual fun expectedFun() = Unit
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
expectedFun()
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
group 'com.example'
|
||||
version '1.0'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'kotlin-multiplatform'
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven { url "http://dl.bintray.com/kotlin/kotlinx.html/" }
|
||||
}
|
||||
|
||||
kotlin {
|
||||
targets {
|
||||
fromPreset(presets.jvm, 'jvmWithoutJava')
|
||||
fromPreset(presets.jvmWithJava, 'jvmWithJava')
|
||||
fromPreset(presets.js, 'js')
|
||||
}
|
||||
sourceSets {
|
||||
commonTest {
|
||||
dependencies {
|
||||
implementation 'org.jetbrains.kotlin:kotlin-test-common'
|
||||
implementation 'org.jetbrains.kotlin:kotlin-test-annotations-common'
|
||||
}
|
||||
}
|
||||
configure([main, jvmWithoutJavaMain]) {
|
||||
dependencies {
|
||||
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
|
||||
}
|
||||
}
|
||||
configure([test, jvmWithoutJavaTest]) {
|
||||
dependencies {
|
||||
implementation 'org.jetbrains.kotlin:kotlin-test'
|
||||
implementation 'org.jetbrains.kotlin:kotlin-test-junit'
|
||||
}
|
||||
}
|
||||
jsTest {
|
||||
dependencies {
|
||||
implementation 'org.jetbrains.kotlin:kotlin-test-js'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
enableFeaturePreview('GRADLE_METADATA')
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.example.lib
|
||||
|
||||
fun <T> id(t: T): T = t
|
||||
|
||||
expect fun expectedFun(): Unit
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.example.lib
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class TestCommonCode {
|
||||
@Test
|
||||
fun testId() {
|
||||
val x = 1
|
||||
val idX = id(x)
|
||||
assertEquals(x, idX)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testExpectedFun() {
|
||||
expectedFun()
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.example.lib
|
||||
|
||||
import com.example.lib.id
|
||||
import com.example.lib.expectedFun
|
||||
|
||||
fun idUsage() = id("123")
|
||||
|
||||
actual fun expectedFun() = Unit
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
expectedFun()
|
||||
}
|
||||
|
||||
fun jsSpecificFun() { expectedFun() }
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.example.lib
|
||||
|
||||
import kotlin.test.Test
|
||||
|
||||
class TestJs {
|
||||
@Test
|
||||
fun testJsSpecificCode() {
|
||||
jsSpecificFun()
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.example.lib
|
||||
|
||||
fun x(): String = "x"
|
||||
|
||||
actual fun expectedFun() {
|
||||
println(id(x()))
|
||||
}
|
||||
|
||||
fun isJavaThere(): Boolean = false
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.example.lib
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.Assert.*
|
||||
|
||||
class TestWithoutJava {
|
||||
@Test
|
||||
fun test() {
|
||||
assertFalse(isJavaThere())
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.example.lib;
|
||||
|
||||
public class JavaClass {
|
||||
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.example.lib
|
||||
|
||||
actual fun expectedFun() { println(id(1)) }
|
||||
|
||||
fun f() = JavaClass()
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.example.lib;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestJava {
|
||||
@Test
|
||||
public void testJava() {
|
||||
new JavaClass();
|
||||
JavaClassUsageKt.f();
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.example.lib
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
class TestWithJava {
|
||||
@Test
|
||||
fun testJavaClass() {
|
||||
JavaClass()
|
||||
f()
|
||||
}
|
||||
|
||||
companion object {
|
||||
val seesJavaTestClass = TestJava::class
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user