From aea6681410b85e73a2edb1d9ac4718d6d3e3c4bb Mon Sep 17 00:00:00 2001 From: Leon Linhart Date: Wed, 1 Mar 2023 19:10:29 +0100 Subject: [PATCH] build: migrate tests to Kotlin and JUnit and use Nokee's Gradle plugins --- build.gradle.kts | 32 ++- gradle/libs.versions.toml | 11 + .../gradle/ecj/plugins/ECJPluginTest.kt | 203 ++++++++++++++++++ .../gradle/ecj/plugins/ECJPluginTest.groovy | 137 ------------ 4 files changed, 242 insertions(+), 141 deletions(-) create mode 100644 src/functionalTest/kotlin/io/github/themrmilchmann/gradle/ecj/plugins/ECJPluginTest.kt delete mode 100644 src/test/groovy/io/github/themrmilchmann/gradle/ecj/plugins/ECJPluginTest.groovy diff --git a/build.gradle.kts b/build.gradle.kts index 99d33b1..e738343 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,11 +19,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.KotlinVersion +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile @Suppress("DSL_SCOPE_VIOLATION") // See https://github.com/gradle/gradle/issues/22797 plugins { - groovy + alias(libs.plugins.gradle.plugin.functional.test) alias(libs.plugins.gradle.toolchain.switches) alias(libs.plugins.kotlin.jvm) alias(libs.plugins.kotlin.plugin.samwithreceiver) @@ -46,14 +48,24 @@ kotlin { target { compilations.all { compilerOptions.configure { - apiVersion.set(KotlinVersion.KOTLIN_1_4) + apiVersion.set(KotlinVersion.KOTLIN_1_8) languageVersion.set(KotlinVersion.KOTLIN_1_8) } } + + compilations.named("main").configure { + compilerOptions.configure { + apiVersion.set(KotlinVersion.KOTLIN_1_4) + } + } } } gradlePlugin { + compatibility { + minimumGradleVersion.set("7.4") + } + website.set("https://github.com/TheMrMilchmann/gradle-ecj") vcsUrl.set("https://github.com/TheMrMilchmann/gradle-ecj.git") @@ -74,6 +86,16 @@ samWithReceiver { } tasks { + withType().configureEach { + options.release.set(8) + } + + withType().configureEach { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_1_8) + } + } + withType().configureEach { useJUnitPlatform() @@ -105,6 +127,8 @@ publishing { } dependencies { - testImplementation(platform(libs.spock.bom)) - testImplementation(libs.spock.core) + functionalTestImplementation(platform(libs.junit.bom)) + functionalTestImplementation(libs.junit.jupiter.api) + functionalTestImplementation(libs.junit.jupiter.params) + functionalTestRuntimeOnly(libs.junit.jupiter.engine) } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4b936e1..b238293 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,11 +1,19 @@ [versions] gradle-toolchain-switches = "0.2.0" +junit = "5.9.2" kotlin = "1.8.10" +nokee-gradle-plugin-dev = "1.6.9" plugin-publish = "1.1.0" spock = "2.3-groovy-3.0" [libraries] +# org.junit - JUnit +junit-bom = { module = "org.junit:junit-bom", version.ref = "junit" } +junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } +junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" } +junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit" } + # org.spockframework - Spock spock-bom = { module = "org.spockframework:spock-bom", version.ref = "spock" } spock-core = { module = "org.spockframework:spock-core", version.ref = "spock" } @@ -15,6 +23,9 @@ spock-core = { module = "org.spockframework:spock-core", version.ref = "spock" } # com.gradle.plugin-publish - plugin-publish plugin-publish = { id = "com.gradle.plugin-publish", version.ref = "plugin-publish" } +# dev.gradleplugins - Nokee Gradle Plugin Development Plugins +gradle-plugin-functional-test = { id = "dev.gradleplugins.gradle-plugin-functional-test", version.ref = "nokee-gradle-plugin-dev" } + # io.github.themrmilchmann.toolchain-switches - Gradle Toolchain Switches Plugin gradle-toolchain-switches = { id = "io.github.themrmilchmann.toolchain-switches", version.ref = "gradle-toolchain-switches" } diff --git a/src/functionalTest/kotlin/io/github/themrmilchmann/gradle/ecj/plugins/ECJPluginTest.kt b/src/functionalTest/kotlin/io/github/themrmilchmann/gradle/ecj/plugins/ECJPluginTest.kt new file mode 100644 index 0000000..68045e2 --- /dev/null +++ b/src/functionalTest/kotlin/io/github/themrmilchmann/gradle/ecj/plugins/ECJPluginTest.kt @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2022-2023 Leon Linhart + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package io.github.themrmilchmann.gradle.ecj.plugins + +import org.gradle.api.JavaVersion +import org.gradle.testkit.runner.GradleRunner +import org.junit.jupiter.api.io.TempDir +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.MethodSource +import java.nio.file.Path +import kotlin.io.path.createDirectories +import kotlin.io.path.writeText + +@Suppress("FunctionName") +class ECJPluginTest { + + private companion object { + + @JvmStatic + private fun provideGradleVersions(): List = buildList { + // See https://docs.gradle.org/current/userguide/compatibility.html + val javaVersion = JavaVersion.current() + + add("8.0.2-20230301020537+0000") +// add("8.0.1") +// add("8.0") + add("7.6.1") + add("7.6") + + @Suppress("UnstableApiUsage") + if (javaVersion >= JavaVersion.VERSION_19) return@buildList + + add("7.5.1") + add("7.5") + + @Suppress("UnstableApiUsage") + if (javaVersion >= JavaVersion.VERSION_18) return@buildList + + add("7.4.2") + add("7.4.1") + add("7.4") + } + + } + + @field:TempDir + lateinit var projectDir: Path + + private val buildFile: Path get() = projectDir.resolve("build.gradle") + private val settingsFile: Path get() = projectDir.resolve("settings.gradle") + + @ParameterizedTest + @MethodSource("provideGradleVersions") + fun `Run without project toolchain`(gradleVersion: String) { + writeSettingsFile(gradleVersion) + writeSourceFile() + + buildFile.writeText( + """ + plugins { + id 'java-library' + id 'io.github.themrmilchmann.ecj' + } + + repositories { + mavenCentral() + } + """.trimIndent() + ) + + GradleRunner.create() + .withArguments("build", "--info") + .withGradleVersion(gradleVersion) + .withPluginClasspath() + .withProjectDir(projectDir.toFile()) + .build() + } + + @ParameterizedTest + @MethodSource("provideGradleVersions") + fun `Run with compatible project toolchain`(gradleVersion: String) { + writeSettingsFile(gradleVersion) + writeSourceFile() + + buildFile.writeText( + """ + plugins { + id 'java-library' + id 'io.github.themrmilchmann.ecj' + } + + java { + toolchain { + languageVersion = JavaLanguageVersion.of(17) + } + } + + repositories { + mavenCentral() + } + """.trimIndent() + ) + + GradleRunner.create() + .withArguments("build", "--info") + .withGradleVersion(gradleVersion) + .withPluginClasspath() + .withProjectDir(projectDir.toFile()) + .build() + } + + + @ParameterizedTest + @MethodSource("provideGradleVersions") + fun `Run with incompatible project toolchain`(gradleVersion: String) { + writeSettingsFile(gradleVersion) + writeSourceFile() + + buildFile.writeText( + """ + plugins { + id 'java-library' + id 'io.github.themrmilchmann.ecj' + } + + java { + toolchain { + languageVersion = JavaLanguageVersion.of(8) + } + } + + repositories { + mavenCentral() + } + """.trimIndent() + ) + + GradleRunner.create() + .withArguments("build", "--info") + .withGradleVersion(gradleVersion) + .withPluginClasspath() + .withProjectDir(projectDir.toFile()) + .build() + } + + private fun writeSettingsFile(gradleVersion: String) { + if (gradleVersion < "8.0") return + + settingsFile.writeText( + """ + pluginManagement { + plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.4.0' + } + } + + plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' + } + """.trimIndent() + ) + } + + private fun writeSourceFile() { + projectDir.resolve("src/main/java/com/example") + .createDirectories() + .resolve("Main.java") + .writeText( + """ + package com.example; + + public class Main { + + public static void main(String[] args) { + System.out.println("Hello, World!"); + } + + } + """.trimIndent() + ) + + } + +} \ No newline at end of file diff --git a/src/test/groovy/io/github/themrmilchmann/gradle/ecj/plugins/ECJPluginTest.groovy b/src/test/groovy/io/github/themrmilchmann/gradle/ecj/plugins/ECJPluginTest.groovy deleted file mode 100644 index f25dced..0000000 --- a/src/test/groovy/io/github/themrmilchmann/gradle/ecj/plugins/ECJPluginTest.groovy +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2022-2023 Leon Linhart - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package io.github.themrmilchmann.gradle.ecj.plugins - -import org.gradle.testkit.runner.GradleRunner -import org.gradle.testkit.runner.TaskOutcome -import spock.lang.Specification -import spock.lang.TempDir -import spock.lang.Unroll - -class ECJPluginTest extends Specification { - - private static def GRADLE_VERSIONS = [ - "7.4.2", - "7.5", - "7.6.1" - ] - - @TempDir - File projectDir - File buildFile - File settingsFile - - def setup() { - buildFile = new File(projectDir, "build.gradle") - settingsFile = new File(projectDir, "settings.gradle") - } - - @Unroll - def "run without explicit toolchain (Gradle #gradleVersion)"() { - given: - writeHelloWorld() - buildFile << """\ - plugins { - id 'java-library' - id 'io.github.themrmilchmann.ecj' - } - - repositories { - mavenCentral() - } - """.stripIndent() - - when: - def result = runGradle(gradleVersion, "build", "--info") - - then: - new File(projectDir, "build/classes/java/main/com/example/Main.class").isFile() - result.task(":compileJava").outcome == TaskOutcome.SUCCESS - - where: - gradleVersion << GRADLE_VERSIONS - } - - @Unroll - def "run with toolchain (Gradle #gradleVersion)"() { - given: - writeHelloWorld() - buildFile << """\ - plugins { - id 'java-library' - id 'io.github.themrmilchmann.ecj' - } - - java { - toolchain { - languageVersion = JavaLanguageVersion.of(17) - } - } - - repositories { - mavenCentral() - } - """.stripIndent() - - when: - def result = runGradle(gradleVersion, "build", "--info") - - then: - new File(projectDir, "build/classes/java/main/com/example/Main.class").isFile() - result.task(":compileJava").outcome == TaskOutcome.SUCCESS - - where: - gradleVersion << GRADLE_VERSIONS - } - - private runGradle(String version, String... args) { - def arguments = [] - arguments.addAll(args) - arguments.add("-s") - - GradleRunner.create() - .withGradleVersion(version) - .withProjectDir(projectDir) - .withArguments(arguments) - .withPluginClasspath() - .build() - } - - private void writeHelloWorld(File baseDir = projectDir) { - File outputFile = new File(baseDir, "src/main/java/com/example/Main.java") - outputFile.parentFile.mkdirs() - outputFile.createNewFile() - - outputFile << """\ - package com.example; - - public class Main { - - public static void main(String[] args) { - System.out.println("Hello World!"); - } - - } - """.stripIndent() - } - -} \ No newline at end of file