From f46a39cd6a938a88a4fe2395676c6f76c38ae24b Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Thu, 12 Nov 2020 12:51:22 +0300 Subject: [PATCH] Add Gradle plugin integration tests --- gradle-plugins/compose/build.gradle.kts | 24 +++++++++ .../compose/desktop/DesktopExtension.kt | 5 +- .../internal/configureApplication.kt | 18 +++---- .../compose/DesktopApplicationTest.kt | 53 +++++++++++++++++++ .../compose/test/GradlePluginTestBase.kt | 13 +++++ .../org/jetbrains/compose/test/TestProject.kt | 48 +++++++++++++++++ .../jetbrains/compose/test/TestProjects.kt | 7 +++ .../jetbrains/compose/test/TestProperties.kt | 12 +++++ .../org/jetbrains/compose/test/fileUtils.kt | 13 +++++ .../application/jvm/build.gradle | 29 ++++++++++ .../application/jvm/settings.gradle | 11 ++++ .../application/jvm/src/main/kotlin/main.kt | 1 + .../application/jvmKotlinDsl/build.gradle.kts | 28 ++++++++++ .../application/jvmKotlinDsl/settings.gradle | 11 ++++ .../jvmKotlinDsl/src/main/kotlin/main.kt | 1 + .../application/mpp/build.gradle | 39 ++++++++++++++ .../application/mpp/settings.gradle | 11 ++++ .../mpp/src/jvmMain/kotlin/main.kt | 1 + 18 files changed, 313 insertions(+), 12 deletions(-) create mode 100644 gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/DesktopApplicationTest.kt create mode 100644 gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/GradlePluginTestBase.kt create mode 100644 gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/TestProject.kt create mode 100644 gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/TestProjects.kt create mode 100644 gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/TestProperties.kt create mode 100644 gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/fileUtils.kt create mode 100644 gradle-plugins/compose/src/test/test-projects/application/jvm/build.gradle create mode 100644 gradle-plugins/compose/src/test/test-projects/application/jvm/settings.gradle create mode 100644 gradle-plugins/compose/src/test/test-projects/application/jvm/src/main/kotlin/main.kt create mode 100644 gradle-plugins/compose/src/test/test-projects/application/jvmKotlinDsl/build.gradle.kts create mode 100644 gradle-plugins/compose/src/test/test-projects/application/jvmKotlinDsl/settings.gradle create mode 100644 gradle-plugins/compose/src/test/test-projects/application/jvmKotlinDsl/src/main/kotlin/main.kt create mode 100644 gradle-plugins/compose/src/test/test-projects/application/mpp/build.gradle create mode 100644 gradle-plugins/compose/src/test/test-projects/application/mpp/settings.gradle create mode 100644 gradle-plugins/compose/src/test/test-projects/application/mpp/src/jvmMain/kotlin/main.kt diff --git a/gradle-plugins/compose/build.gradle.kts b/gradle-plugins/compose/build.gradle.kts index 70620ef474..5dafe2e65e 100644 --- a/gradle-plugins/compose/build.gradle.kts +++ b/gradle-plugins/compose/build.gradle.kts @@ -1,4 +1,5 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.getCurrentOperatingSystem plugins { kotlin("jvm") @@ -31,6 +32,7 @@ dependencies { compileOnly(kotlin("gradle-plugin-api")) compileOnly(kotlin("gradle-plugin")) testImplementation(gradleTestKit()) + testImplementation("junit:junit:4.13") fun embeddedCompileOnly(dep: String) { compileOnly(dep) @@ -54,3 +56,25 @@ val jar = tasks.named("jar") { from(zipTree(shadow.get().archiveFile)) this.duplicatesStrategy = DuplicatesStrategy.INCLUDE } + +val gradleVersionForTests = "6.7" +val java14Home: String? = when (JavaVersion.current()) { + JavaVersion.VERSION_14 -> System.getProperty("java.home") + else -> System.getenv("JDK_14") +} +val isWindows = getCurrentOperatingSystem().isWindows + +afterEvaluate { + tasks.named("test") { + dependsOn("publishToMavenLocal") + systemProperty("compose.plugin.version", BuildProperties.deployVersion(project)) + systemProperty("gradle.version.for.tests", gradleVersionForTests) + + if (java14Home != null) { + val executableFileName = if (isWindows) "java.exe" else "java" + executable = File(java14Home).resolve("bin/$executableFileName").absolutePath + } else { + doFirst { error("Use JDK 14 to run tests or set up JDK_14 env. var") } + } + } +} diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/DesktopExtension.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/DesktopExtension.kt index bd5cd52ce1..5f9d0f1764 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/DesktopExtension.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/DesktopExtension.kt @@ -1,5 +1,6 @@ package org.jetbrains.compose.desktop +import org.gradle.api.Action import org.gradle.api.model.ObjectFactory import org.gradle.api.plugins.ExtensionAware import org.jetbrains.compose.desktop.application.dsl.Application @@ -14,7 +15,7 @@ abstract class DesktopExtension @Inject constructor(private val objectFactory: O objectFactory.newInstance(Application::class.java, "main") } - fun application(fn: Application.() -> Unit) { - application.fn() + fun application(fn: Action) { + fn.execute(application) } } diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/configureApplication.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/configureApplication.kt index 6d80e687cc..c672b1f411 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/configureApplication.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/configureApplication.kt @@ -17,18 +17,16 @@ import java.util.* // todo: file associations // todo: use workers fun configureApplicationImpl(project: Project, app: Application) { - project.afterEvaluate { - if (app._isDefaultConfigurationEnabled) { - if (project.plugins.hasPlugin("org.jetbrains.kotlin.multiplatform")) { - project.configureFromMppPlugin(app) - } else if (project.plugins.hasPlugin("org.jetbrains.kotlin.jvm")) { - val mainSourceSet = project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets.getByName("main") - app.from(mainSourceSet) - } + if (app._isDefaultConfigurationEnabled) { + if (project.plugins.hasPlugin("org.jetbrains.kotlin.multiplatform")) { + project.configureFromMppPlugin(app) + } else if (project.plugins.hasPlugin("org.jetbrains.kotlin.jvm")) { + val mainSourceSet = project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets.getByName("main") + app.from(mainSourceSet) } - project.configurePackagingTasks(listOf(app)) - project.configureWix() } + project.configurePackagingTasks(listOf(app)) + project.configureWix() } internal fun Project.configureFromMppPlugin(mainApplication: Application) { diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/DesktopApplicationTest.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/DesktopApplicationTest.kt new file mode 100644 index 0000000000..225ff1b27d --- /dev/null +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/DesktopApplicationTest.kt @@ -0,0 +1,53 @@ +package org.jetbrains.compose + +import org.gradle.testkit.runner.TaskOutcome +import org.jetbrains.compose.desktop.application.internal.OS +import org.jetbrains.compose.desktop.application.internal.currentOS +import org.jetbrains.compose.test.* +import org.junit.Assert.assertEquals +import org.junit.Test + +class DesktopApplicationTest : GradlePluginTestBase() { + @Test + fun smokeTestRunTask() = with(testProject(TestProjects.jvm)) { + file("build.gradle").modify { + it + """ + afterEvaluate { + tasks.getByName("run").doFirst { + throw new StopExecutionException("Skip run task") + } + } + """.trimIndent() + } + val result = gradle("run").build() + assertEquals(TaskOutcome.SUCCESS, result.task(":run")?.outcome) + } + + @Test + fun kotlinDsl(): Unit = with(testProject(TestProjects.jvmKotlinDsl)) { + gradle(":package", "--dry-run").build() + } + + @Test + fun packageJvm() = with(testProject(TestProjects.jvm)) { + testPackage() + } + + @Test + fun packageMpp() = with(testProject(TestProjects.mpp)) { + testPackage() + } + + private fun TestProject.testPackage() { + val result = gradle(":package").build() + val ext = when (currentOS) { + OS.Linux -> "deb" + OS.Windows -> "msi" + OS.MacOS -> "dmg" + } + file("build/compose/binaries/main/$ext/simple-1.0.$ext") + .checkExists() + assertEquals(TaskOutcome.SUCCESS, result.task(":package${ext.capitalize()}")?.outcome) + assertEquals(TaskOutcome.SUCCESS, result.task(":package")?.outcome) + } +} diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/GradlePluginTestBase.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/GradlePluginTestBase.kt new file mode 100644 index 0000000000..c7b19846a2 --- /dev/null +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/GradlePluginTestBase.kt @@ -0,0 +1,13 @@ +package org.jetbrains.compose.test + +import org.junit.Rule +import org.junit.rules.TemporaryFolder + +abstract class GradlePluginTestBase { + @Rule + @JvmField + val testDir: TemporaryFolder = TemporaryFolder() + + fun testProject(name: String): TestProject = + TestProject(name, workingDir = testDir.root) +} diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/TestProject.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/TestProject.kt new file mode 100644 index 0000000000..c2b0aa5a42 --- /dev/null +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/TestProject.kt @@ -0,0 +1,48 @@ +package org.jetbrains.compose.test + +import org.gradle.testkit.runner.GradleRunner +import java.io.File + +data class TestProject( + private val name: String, + private val workingDir: File, + private val defaultGradleVersion: String = TestProperties.defaultGradleVersionForTests +) { + private val additionalArgs = listOf("--stacktrace") + + init { + val originalTestRoot = File("src/test/test-projects").resolve(name).also { + check(it.exists()) { "Test project is not found: ${it.absolutePath}" } + } + for (orig in originalTestRoot.walk()) { + if (!orig.isFile) continue + + val target = workingDir.resolve(orig.relativeTo(originalTestRoot)) + target.parentFile.mkdirs() + + if (orig.name.endsWith(".gradle") || orig.name.endsWith(".gradle.kts")) { + val origContent = orig.readText() + val newContent = origContent.replace("COMPOSE_VERSION_PLACEHOLDER", TestProperties.composeVersion) + target.writeText(newContent) + } else { + orig.copyTo(target) + } + } + } + + fun gradle(vararg args: String): GradleRunner = + GradleRunner.create().apply { + withGradleVersion(defaultGradleVersion) + withProjectDir(workingDir) + withArguments(args.toList() + additionalArgs) + } + + @Suppress("DeprecatedCallableAddReplaceWith") + @Deprecated("Do not commit!") + fun gradleDebug(vararg args: String): GradleRunner = + gradle(*args).withDebug(true) + + fun file(path: String): File = + workingDir.resolve(path) +} + diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/TestProjects.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/TestProjects.kt new file mode 100644 index 0000000000..7dbe1dbb62 --- /dev/null +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/TestProjects.kt @@ -0,0 +1,7 @@ +package org.jetbrains.compose.test + +object TestProjects { + const val jvm = "application/jvm" + const val mpp = "application/mpp" + const val jvmKotlinDsl = "application/jvmKotlinDsl" +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/TestProperties.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/TestProperties.kt new file mode 100644 index 0000000000..96c5342116 --- /dev/null +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/TestProperties.kt @@ -0,0 +1,12 @@ +package org.jetbrains.compose.test + +object TestProperties { + val java14Home: String + get() = System.getProperty("jdk.14.home") ?: error("Run test using JDK 14 or set JDK_14 env var") + + val composeVersion: String + get() = System.getProperty("compose.plugin.version")!! + + val defaultGradleVersionForTests: String + get() = System.getProperty("gradle.version.for.tests")!! +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/fileUtils.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/fileUtils.kt new file mode 100644 index 0000000000..315b5e7e07 --- /dev/null +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/fileUtils.kt @@ -0,0 +1,13 @@ +package org.jetbrains.compose.test + +import java.io.File + +fun File.modify(fn: (String) -> String) { + val content = readText() + val newContent = fn(content) + writeText(newContent) +} + +fun File.checkExists(): File = apply { + check(exists()) { "File does not exist: $absolutePath" } +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/application/jvm/build.gradle b/gradle-plugins/compose/src/test/test-projects/application/jvm/build.gradle new file mode 100644 index 0000000000..f2c1a05ef2 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/application/jvm/build.gradle @@ -0,0 +1,29 @@ +import org.jetbrains.compose.desktop.application.dsl.TargetFormat + +plugins { + id "org.jetbrains.kotlin.jvm" + id "org.jetbrains.compose" +} + +repositories { + google() + mavenCentral() + jcenter() + maven { + url "https://maven.pkg.jetbrains.space/public/p/compose/dev" + } +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib" + implementation compose.desktop.currentOs +} + +compose.desktop { + application { + mainClass = "MainKt" + nativeDistributions { + targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) + } + } +} diff --git a/gradle-plugins/compose/src/test/test-projects/application/jvm/settings.gradle b/gradle-plugins/compose/src/test/test-projects/application/jvm/settings.gradle new file mode 100644 index 0000000000..55d44ed154 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/application/jvm/settings.gradle @@ -0,0 +1,11 @@ +pluginManagement { + plugins { + id 'org.jetbrains.kotlin.jvm' version '1.4.10' + id 'org.jetbrains.compose' version 'COMPOSE_VERSION_PLACEHOLDER' + } + repositories { + mavenLocal() + gradlePluginPortal() + } +} +rootProject.name = "simple" \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/application/jvm/src/main/kotlin/main.kt b/gradle-plugins/compose/src/test/test-projects/application/jvm/src/main/kotlin/main.kt new file mode 100644 index 0000000000..78e3db2779 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/application/jvm/src/main/kotlin/main.kt @@ -0,0 +1 @@ +fun main() {} \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/application/jvmKotlinDsl/build.gradle.kts b/gradle-plugins/compose/src/test/test-projects/application/jvmKotlinDsl/build.gradle.kts new file mode 100644 index 0000000000..d5cdb6fb73 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/application/jvmKotlinDsl/build.gradle.kts @@ -0,0 +1,28 @@ +import org.jetbrains.compose.compose +import org.jetbrains.compose.desktop.application.dsl.TargetFormat + +plugins { + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.compose") +} + +repositories { + google() + mavenCentral() + jcenter() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") +} + +dependencies { + implementation(kotlin("stdlib")) + implementation(compose.desktop.currentOs) +} + +compose.desktop { + application { + mainClass = "MainKt" + nativeDistributions { + targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) + } + } +} diff --git a/gradle-plugins/compose/src/test/test-projects/application/jvmKotlinDsl/settings.gradle b/gradle-plugins/compose/src/test/test-projects/application/jvmKotlinDsl/settings.gradle new file mode 100644 index 0000000000..55d44ed154 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/application/jvmKotlinDsl/settings.gradle @@ -0,0 +1,11 @@ +pluginManagement { + plugins { + id 'org.jetbrains.kotlin.jvm' version '1.4.10' + id 'org.jetbrains.compose' version 'COMPOSE_VERSION_PLACEHOLDER' + } + repositories { + mavenLocal() + gradlePluginPortal() + } +} +rootProject.name = "simple" \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/application/jvmKotlinDsl/src/main/kotlin/main.kt b/gradle-plugins/compose/src/test/test-projects/application/jvmKotlinDsl/src/main/kotlin/main.kt new file mode 100644 index 0000000000..78e3db2779 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/application/jvmKotlinDsl/src/main/kotlin/main.kt @@ -0,0 +1 @@ +fun main() {} \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/application/mpp/build.gradle b/gradle-plugins/compose/src/test/test-projects/application/mpp/build.gradle new file mode 100644 index 0000000000..3086e46281 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/application/mpp/build.gradle @@ -0,0 +1,39 @@ +import org.jetbrains.compose.desktop.application.dsl.TargetFormat + +plugins { + id "org.jetbrains.kotlin.multiplatform" + id "org.jetbrains.compose" +} + +repositories { + google() + mavenCentral() + jcenter() + maven { + url "https://maven.pkg.jetbrains.space/public/p/compose/dev" + } +} + +kotlin { + jvm { + withJava() + } + sourceSets { + named("jvmMain") { + dependencies { + implementation("org.jetbrains.kotlin:kotlin-stdlib") + implementation(compose.desktop.currentOs) + } + } + } +} + + +compose.desktop { + application { + mainClass = "MainKt" + nativeDistributions { + targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) + } + } +} diff --git a/gradle-plugins/compose/src/test/test-projects/application/mpp/settings.gradle b/gradle-plugins/compose/src/test/test-projects/application/mpp/settings.gradle new file mode 100644 index 0000000000..394e45d2c1 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/application/mpp/settings.gradle @@ -0,0 +1,11 @@ +pluginManagement { + plugins { + id 'org.jetbrains.kotlin.multiplatform' version '1.4.10' + id 'org.jetbrains.compose' version 'COMPOSE_VERSION_PLACEHOLDER' + } + repositories { + mavenLocal() + gradlePluginPortal() + } +} +rootProject.name = "simple" \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/application/mpp/src/jvmMain/kotlin/main.kt b/gradle-plugins/compose/src/test/test-projects/application/mpp/src/jvmMain/kotlin/main.kt new file mode 100644 index 0000000000..78e3db2779 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/application/mpp/src/jvmMain/kotlin/main.kt @@ -0,0 +1 @@ +fun main() {} \ No newline at end of file