From c4607a60ab25f009587865ddcc506c84e7f39af3 Mon Sep 17 00:00:00 2001 From: Sergey Morgunov Date: Fri, 1 Sep 2023 19:11:26 +0300 Subject: [PATCH] [Gradle] Add functional tests --- gradle-twirl/build.gradle.kts | 29 ++---- .../gradle/TwirlPluginFunctionalTest.java | 48 ---------- .../java/play/twirl/gradle/TwirlPlugin.java | 4 +- .../twirl/gradle/AbstractFunctionalTest.java | 93 +++++++++++++++++++ .../gradle/TwirlPluginFunctionalTest.java | 61 ++++++++++++ .../resources/simple/build.gradle.kts.ftlh | 17 ++++ .../simple/src/main/twirl/a/b/c.scala.html | 6 ++ scripts/test-code.sh | 2 +- 8 files changed, 189 insertions(+), 71 deletions(-) delete mode 100644 gradle-twirl/src/functionalTest/java/play/twirl/gradle/TwirlPluginFunctionalTest.java create mode 100644 gradle-twirl/src/test/java/play/twirl/gradle/AbstractFunctionalTest.java create mode 100644 gradle-twirl/src/test/java/play/twirl/gradle/TwirlPluginFunctionalTest.java create mode 100644 gradle-twirl/src/test/resources/simple/build.gradle.kts.ftlh create mode 100644 gradle-twirl/src/test/resources/simple/src/main/twirl/a/b/c.scala.html diff --git a/gradle-twirl/build.gradle.kts b/gradle-twirl/build.gradle.kts index fe0a7ee5..c142d10e 100644 --- a/gradle-twirl/build.gradle.kts +++ b/gradle-twirl/build.gradle.kts @@ -34,6 +34,8 @@ repositories { dependencies { compileOnly("com.typesafe.play:twirl-compiler_2.13:$compilerVersion") testImplementation("org.assertj:assertj-core:3.24.2") + testImplementation("commons-io:commons-io:2.13.0") + testImplementation("org.freemarker:freemarker:2.3.32") } tasks.jar { @@ -44,23 +46,17 @@ tasks.jar { testing { suites { - // Configure the built-in test suite val test by getting(JvmTestSuite::class) { - // Use JUnit Jupiter test framework useJUnitJupiter("5.9.1") - } - - // Create a new test suite - val functionalTest by registering(JvmTestSuite::class) { - dependencies { - // functionalTest test suite depends on the production code in tests - implementation(project()) - } - targets { all { - // This test suite should run after the built-in test suite has run its tests - testTask.configure { shouldRunAfter(test) } + testTask.configure { + systemProperty("twirl.version", compilerVersion) + project.findProperty("scala.version")?.let { scalaVersion -> + val ver = (scalaVersion as String).trimEnd { !it.isDigit() } + systemProperty("scala.version", ver) + } + } } } } @@ -94,8 +90,6 @@ gradlePlugin { } } -gradlePlugin.testSourceSets.add(sourceSets["functionalTest"]) - val headerLicense = "Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc. " val headerLicenseHash = "# $headerLicense" val headerLicenseJava = "/*\n * $headerLicense\n */" @@ -114,8 +108,3 @@ spotless { licenseHeader(headerLicenseHash, "[^#]") } } - -tasks.named("check") { - // Include functionalTest as part of the check lifecycle - dependsOn(testing.suites.named("functionalTest")) -} diff --git a/gradle-twirl/src/functionalTest/java/play/twirl/gradle/TwirlPluginFunctionalTest.java b/gradle-twirl/src/functionalTest/java/play/twirl/gradle/TwirlPluginFunctionalTest.java deleted file mode 100644 index 45a57128..00000000 --- a/gradle-twirl/src/functionalTest/java/play/twirl/gradle/TwirlPluginFunctionalTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc. - */ -package play.twirl.gradle; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; -import org.gradle.testkit.runner.BuildResult; -import org.gradle.testkit.runner.GradleRunner; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -/** A simple functional test for the 'com.playframework.twirl' plugin. */ -class TwirlPluginFunctionalTest { - @TempDir File projectDir; - - private File getBuildFile() { - return new File(projectDir, "build.gradle"); - } - - private File getSettingsFile() { - return new File(projectDir, "settings.gradle"); - } - - @Test - void canRunTask() throws IOException { - writeString(getSettingsFile(), ""); - writeString( - getBuildFile(), - "plugins {" + "id 'application'\n" + " id('com.typesafe.play.twirl')" + "}"); - - // Run the build - GradleRunner runner = GradleRunner.create(); - runner.forwardOutput(); - runner.withPluginClasspath(); - runner.withArguments("compileTwirl"); - runner.withProjectDir(projectDir); - BuildResult result = runner.build(); - } - - private void writeString(File file, String string) throws IOException { - try (Writer writer = new FileWriter(file)) { - writer.write(string); - } - } -} diff --git a/gradle-twirl/src/main/java/play/twirl/gradle/TwirlPlugin.java b/gradle-twirl/src/main/java/play/twirl/gradle/TwirlPlugin.java index b0f3adb7..7c7b33a0 100644 --- a/gradle-twirl/src/main/java/play/twirl/gradle/TwirlPlugin.java +++ b/gradle-twirl/src/main/java/play/twirl/gradle/TwirlPlugin.java @@ -24,7 +24,7 @@ /** A simple 'hello world' plugin. */ public class TwirlPlugin implements Plugin { - private static final String DEFAULT_SCALA_VERSION = "2.13"; + static final String DEFAULT_SCALA_VERSION = "2.13"; private static final Map DEFAULT_TEMPLATE_FORMATS = Map.of( @@ -58,7 +58,7 @@ public void apply(final Project project) { /** Get Twirl version from Gradle Plugin MANIFEST.MF */ private String getDefaultTwirlVersion() { - return getClass().getPackage().getImplementationVersion(); + return System.getProperty("twirl.version", getClass().getPackage().getImplementationVersion()); } private Configuration createDefaultTwirlConfiguration( diff --git a/gradle-twirl/src/test/java/play/twirl/gradle/AbstractFunctionalTest.java b/gradle-twirl/src/test/java/play/twirl/gradle/AbstractFunctionalTest.java new file mode 100644 index 00000000..c52bae43 --- /dev/null +++ b/gradle-twirl/src/test/java/play/twirl/gradle/AbstractFunctionalTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc. + */ +package play.twirl.gradle; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateException; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; +import org.apache.commons.io.FileUtils; +import org.gradle.testkit.runner.BuildResult; +import org.gradle.testkit.runner.GradleRunner; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.io.TempDir; + +abstract class AbstractFunctionalTest { + + @TempDir File projectDir; + + File projectSourceDir; + + GradleRunner runner; + + Configuration freemarkerConf; + + protected abstract File getProjectSourceDir(); + + protected abstract String getBuildFileContent(); + + protected String getSettingsFileContent() { + return ""; + } + + static String getScalaVersion() { + return System.getProperty("scala.version", TwirlPlugin.DEFAULT_SCALA_VERSION); + } + + static String getTwirlVersion() { + return System.getProperty("twirl.version"); + } + + protected Path projectSourcePath(String path) { + return Paths.get(projectSourceDir.getAbsolutePath(), path); + } + + protected Path projectPath(String path) { + return Paths.get(projectDir.getAbsolutePath(), path); + } + + protected Path projectBuildPath(String path) { + return Paths.get(projectDir.getAbsolutePath(), "build/" + path); + } + + @BeforeEach + void init() throws IOException, TemplateException { + projectSourceDir = getProjectSourceDir(); + runner = GradleRunner.create().withProjectDir(projectDir).withPluginClasspath().forwardOutput(); + + initFreemarker(); + + FileUtils.writeStringToFile( + projectPath("build.gradle.kts").toFile(), getBuildFileContent(), UTF_8); + FileUtils.writeStringToFile( + projectPath("settings.gradle.kts").toFile(), getSettingsFileContent(), UTF_8); + } + + protected void initFreemarker() throws IOException { + freemarkerConf = new Configuration(Configuration.VERSION_2_3_32); + freemarkerConf.setDirectoryForTemplateLoading(projectSourceDir); + } + + protected String templateProcess(String template, Map params) { + StringWriter writer = new StringWriter(); + try { + Template buildGradle = freemarkerConf.getTemplate(template); + buildGradle.process(params, writer); + } catch (Exception e) { + throw new RuntimeException(e); + } + return writer.toString(); + } + + protected BuildResult build(String... args) { + return runner.withArguments(args).build(); + } +} diff --git a/gradle-twirl/src/test/java/play/twirl/gradle/TwirlPluginFunctionalTest.java b/gradle-twirl/src/test/java/play/twirl/gradle/TwirlPluginFunctionalTest.java new file mode 100644 index 00000000..d78c6032 --- /dev/null +++ b/gradle-twirl/src/test/java/play/twirl/gradle/TwirlPluginFunctionalTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc. + */ +package play.twirl.gradle; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import org.apache.commons.io.FileUtils; +import org.apache.groovy.util.Maps; +import org.gradle.testkit.runner.BuildResult; +import org.gradle.testkit.runner.BuildTask; +import org.gradle.testkit.runner.TaskOutcome; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +/** A simple functional test to check a Twirl Gradle Plugin. */ +public class TwirlPluginFunctionalTest extends AbstractFunctionalTest { + + @Override + protected File getProjectSourceDir() { + return new File("src/test/resources/simple"); + } + + @Override + protected String getBuildFileContent() { + Map params = + Maps.of( + "scalaVersion", getScalaVersion(), + "twirlVersion", getTwirlVersion()); + return templateProcess("build.gradle.kts.ftlh", params); + } + + @Test + @DisplayName("Test simple Gradle project with Twirl HTML template") + void testSimpleGradleProject() throws IOException { + File simpleSources = projectPath("src").toFile(); + FileUtils.copyDirectory(projectSourcePath("src").toFile(), simpleSources); + + BuildResult result = build("build"); + + BuildTask compileTwirlResult = result.task(":compileTwirl"); + assertThat(compileTwirlResult).isNotNull(); + assertThat(compileTwirlResult.getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + assertThat(projectBuildPath("generated/sources/twirl/main/a/b/html/c.template.scala")) + .isNotEmptyFile(); + + BuildTask compileScalaResult = result.task(":compileScala"); + assertThat(compileScalaResult).isNotNull(); + assertThat(compileScalaResult.getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + assertThat(projectBuildPath("classes/scala/main/a/b/html/c.class")).isNotEmptyFile(); + + result = build("build"); + + compileTwirlResult = result.task(":compileTwirl"); + assertThat(compileTwirlResult).isNotNull(); + assertThat(compileTwirlResult.getOutcome()).isEqualTo(TaskOutcome.UP_TO_DATE); + } +} diff --git a/gradle-twirl/src/test/resources/simple/build.gradle.kts.ftlh b/gradle-twirl/src/test/resources/simple/build.gradle.kts.ftlh new file mode 100644 index 00000000..0425e83b --- /dev/null +++ b/gradle-twirl/src/test/resources/simple/build.gradle.kts.ftlh @@ -0,0 +1,17 @@ +plugins { + application + id("com.typesafe.play.twirl") +} + +repositories { + mavenCentral() + mavenLocal() +} + +dependencies { + implementation("com.typesafe.play:twirl-api_${scalaVersion}:${twirlVersion}") +} + +twirl { + scalaVersion.set("${scalaVersion}") +} diff --git a/gradle-twirl/src/test/resources/simple/src/main/twirl/a/b/c.scala.html b/gradle-twirl/src/test/resources/simple/src/main/twirl/a/b/c.scala.html new file mode 100644 index 00000000..7f0f12e5 --- /dev/null +++ b/gradle-twirl/src/test/resources/simple/src/main/twirl/a/b/c.scala.html @@ -0,0 +1,6 @@ +@**************************************************************************************************************************************************** + * Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc. * + ****************************************************************************************************************************************************@ + +@(name: String) +Hello, @name. diff --git a/scripts/test-code.sh b/scripts/test-code.sh index 584524a5..d0eae6f5 100755 --- a/scripts/test-code.sh +++ b/scripts/test-code.sh @@ -4,4 +4,4 @@ sbt "++$MATRIX_SCALA test" || exit 1 sbt +publishLocal +compiler/publishM2 plugin/test plugin/scripted || exit 1 -(cd gradle-twirl && ./gradlew clean check -x spotlessCheck --no-daemon) || exit 1 +(cd gradle-twirl && ./gradlew clean check -x spotlessCheck --no-daemon -Pscala.version="$MATRIX_SCALA") || exit 1