diff --git a/.gitignore b/.gitignore index a59b1cb..49bacff 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /.idea/shelf /.idea/libraries /.idea/modules +/.idea/atlassian-ide-plugin.xml out dist diff --git a/build.gradle b/build.gradle index 2a4f07e..1f9ebfc 100644 --- a/build.gradle +++ b/build.gradle @@ -32,11 +32,14 @@ buildscript { group 'com.cursive-ide' version '1.1.0' +ext.pluginId = 'com.cursive-ide.clojure' +ext.pluginImplementationClass = 'cursive.ClojurePlugin' apply plugin: 'kotlin' apply plugin: 'groovy' apply plugin: 'maven' apply plugin: 'com.gradle.plugin-publish' +apply plugin: "java-gradle-plugin" project.afterEvaluate { // Ugh, see https://discuss.gradle.org/t/kotlin-groovy-and-java-compilation/14903/9 @@ -55,6 +58,18 @@ dependencies { compile gradleApi() compile localGroovy() compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + testCompile gradleTestKit() + testCompile "junit:junit:4.12" + testCompile 'net.wuerl.kotlin:assertj-core-kotlin:0.1.3' +} + +gradlePlugin { + plugins { + clojurePlugin { + id = pluginId + implementationClass = pluginImplementationClass + } + } } pluginBundle { @@ -65,7 +80,7 @@ pluginBundle { plugins { clojurePlugin { - id = 'com.cursive-ide.clojure' + id = pluginId displayName = 'Gradle Clojure plugin' } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 3baa851..d3b8398 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradlew.bat b/gradlew.bat index 832fdb6..f6d5974 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,90 +1,90 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/kotlin/cursive/ClojurePlugin.kt b/src/main/kotlin/cursive/ClojurePlugin.kt index d1e8d54..87b9c36 100644 --- a/src/main/kotlin/cursive/ClojurePlugin.kt +++ b/src/main/kotlin/cursive/ClojurePlugin.kt @@ -22,7 +22,6 @@ import org.gradle.api.Project import org.gradle.api.file.FileCollection import org.gradle.api.file.SourceDirectorySet import org.gradle.api.internal.ConventionTask -import org.gradle.api.internal.HasConvention import org.gradle.api.internal.file.FileResolver import org.gradle.api.internal.file.collections.SimpleFileCollection import org.gradle.api.internal.plugins.DslObject @@ -34,12 +33,14 @@ import org.gradle.api.plugins.JavaPluginConvention import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.compile.AbstractCompile +import org.gradle.api.tasks.incremental.IncrementalTaskInputs import org.gradle.process.JavaForkOptions import org.gradle.process.internal.DefaultJavaForkOptions import org.gradle.process.internal.ExecException import org.gradle.process.internal.JavaExecHandleBuilder import org.gradle.util.ConfigureUtil import java.io.File +import java.io.IOException import java.io.OutputStream import java.util.* import java.util.regex.Pattern @@ -48,65 +49,38 @@ import javax.inject.Inject /** * @author Colin Fleming */ +@Suppress("unused") class ClojurePlugin : Plugin { val logger = Logging.getLogger(this.javaClass) override fun apply(project: Project) { logger.info("Applying ClojurePlugin") - val javaBasePlugin = project.plugins.apply(JavaBasePlugin::class.java) + project.plugins.apply(JavaBasePlugin::class.java) + project.plugins.apply(JavaPlugin::class.java) + val javaPluginConvention = project.convention.getPlugin(JavaPluginConvention::class.java) - project.plugins.apply(JavaPlugin::class.java) + javaPluginConvention.sourceSets?.all { sourceSet -> + val compileTask = createClojureCompileTask(project, sourceSet) - val mainSourceSet = javaPluginConvention.sourceSets?.getByName(SourceSet.MAIN_SOURCE_SET_NAME) - if (mainSourceSet is HasConvention) { - val mainCompileTask = createCompileTask(project, mainSourceSet) - val conventionMapping = mainCompileTask.conventionMapping - conventionMapping.map("classpath", { - mainSourceSet.compileClasspath - .plus(SimpleFileCollection(mainSourceSet.allSource.srcDirs)) - .plus(SimpleFileCollection(mainSourceSet.output.classesDir)) - }) - conventionMapping.map("namespaces", { - mainCompileTask.findNamespaces() - }) - } - val testSourceSet = javaPluginConvention.sourceSets?.getByName(SourceSet.TEST_SOURCE_SET_NAME) - if (testSourceSet is HasConvention) { - val testCompileTask = createCompileTask(project, testSourceSet) - - val mainSrcDirs = mainSourceSet?.allSource?.srcDirs ?: emptyList() - val testSrcDirs = testSourceSet.allSource.srcDirs - val outputDirs = if (mainSourceSet != null) - listOf(mainSourceSet.output.classesDir, testSourceSet.output.classesDir) - else - listOf(testSourceSet.output.classesDir) - - val compileMapping = testCompileTask.conventionMapping - compileMapping.map("classpath", { - testSourceSet.compileClasspath - .plus(SimpleFileCollection(mainSrcDirs + testSrcDirs + outputDirs)) - }) - compileMapping.map("namespaces", { - testCompileTask.findNamespaces() - }) - - val testTask = createTestTask(project) - - val testRunnerMapping = testTask.conventionMapping - testRunnerMapping.map("classpath", { - testSourceSet.runtimeClasspath.plus(SimpleFileCollection(mainSrcDirs + testSrcDirs + outputDirs)) - }) - testRunnerMapping.map("namespaces", { - testCompileTask.findNamespaces() - }) - - testTask.dependsOn(testCompileTask.name) + if (sourceSet.name == SourceSet.TEST_SOURCE_SET_NAME) { + val testTask = createTestTask(project) + + val testTaskMapping = testTask.conventionMapping + testTaskMapping.map("classpath", { + sourceSet.runtimeClasspath + }) + testTaskMapping.map("namespaces", { + compileTask.findNamespaces() + }) + + testTask.dependsOn(compileTask.name) + } } } - fun createCompileTask(project: Project, sourceSet: SourceSet): ClojureCompiler { + fun createClojureCompileTask(project: Project, sourceSet: SourceSet): ClojureCompile { val projectInternal = project as ProjectInternal val sourceRootDir: String = "src/${sourceSet.name}/clojure" @@ -124,26 +98,32 @@ class ClojurePlugin : Plugin { sourceSet.resources?.filter?.exclude { clojureDirSet.contains(it.file) } val name = sourceSet.getCompileTaskName("clojure") - val compilerClass = ClojureCompiler::class.java - logger.info("Creating Clojure compile task $name with class $compilerClass") - val compile = project.tasks.create(name, compilerClass) - compile.description = "Compiles the $sourceSet Clojure code" - - val javaTask = project.tasks.findByName(sourceSet.compileJavaTaskName) - if (javaTask != null) { - compile.dependsOn(javaTask.name) + val clojureCompileClass = ClojureCompile::class.java + logger.info("Creating Clojure compile task $name with class $clojureCompileClass") + val clojureCompileTask = project.tasks.create(name, clojureCompileClass) + clojureCompileTask.description = "Compiles the $sourceSet Clojure code" + + val javaCompileTask = project.tasks.findByName(sourceSet.compileJavaTaskName) + if (javaCompileTask != null) { + clojureCompileTask.dependsOn(javaCompileTask.name) } - project.tasks.findByName(sourceSet.classesTaskName)?.dependsOn(compile.name) + project.tasks.findByName(sourceSet.classesTaskName)?.dependsOn(clojureCompileTask.name) - val conventionMapping = compile.conventionMapping + val conventionMapping = clojureCompileTask.conventionMapping + conventionMapping.map("classpath", { + sourceSet.compileClasspath + }) + conventionMapping.map("namespaces", { + clojureCompileTask.findNamespaces() + }) conventionMapping.map("destinationDir", { sourceSet.output.classesDir }) - compile.source(clojureDirSet) + clojureCompileTask.source(clojureDirSet) - return compile + return clojureCompileTask } } @@ -161,7 +141,6 @@ fun createTestTask(project: Project): ClojureTestRunner { return testRunner } - interface ClojureSourceSet { fun getClojure(): SourceDirectorySet fun clojure(configureClosure: Closure?): ClojureSourceSet @@ -178,14 +157,20 @@ open class ClojureSourceSetImpl(displayName: String?, resolver: FileResolver?) : override fun getClojure(): SourceDirectorySet = clojure override fun clojure(configureClosure: Closure?): ClojureSourceSet { - ApiFacade.configureByClosure(this, configureClosure) + ApiFacade.configureByClosure(clojure, configureClosure) return this } } class ReflectionWarnings(var enabled: Boolean, var projectOnly: Boolean, var asErrors: Boolean) -open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) : +object FileCopyErrorHandler : (File, IOException) -> OnErrorAction { + override fun invoke(file: File, exception: IOException): OnErrorAction { + throw ExecException("Could not copy ${file} to output directory", exception) + } +} + +open class ClojureCompile @Inject constructor(val fileResolver: FileResolver) : AbstractCompile(), JavaForkOptions by DefaultJavaForkOptions(fileResolver) { @@ -197,21 +182,38 @@ open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) : var elideMeta: Collection = emptyList() var directLinking: Boolean = false + @Suppress("unused") var namespaces: Collection = emptyList() + @Suppress("unused") fun reflectionWarnings(configureClosure: Closure?): ReflectionWarnings { ConfigureUtil.configure(configureClosure, reflectionWarnings) return reflectionWarnings } + @Suppress("UNUSED_PARAMETER") @TaskAction + fun compile(inputs: IncrementalTaskInputs) { + compile() + } + override fun compile() { - logger.info("Starting ClojureCompiler task") + logger.info("Starting ClojureCompile task") + + val tmpDestinationDir = temporaryDir.resolve("classes") + removeObsoleteClassFiles(destinationDir, tmpDestinationDir) + + if (!tmpDestinationDir.deleteRecursively()) { + throw ExecException("Could not delete ${tmpDestinationDir}") + } + tmpDestinationDir.mkdirs() + destinationDir.mkdirs() if (copySourceToOutput ?: !aotCompile) { project.copy { - it.from(getSource()).into(destinationDir) + it.from(getSource()).into(tmpDestinationDir) } + copyToDestination(tmpDestinationDir) return } @@ -228,7 +230,7 @@ open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) : logger.info("Compiling " + namespaces.joinToString(", ")) val script = listOf("(try", - " (binding [*compile-path* \"${destinationDir.canonicalPath}\"", + " (binding [*compile-path* \"${tmpDestinationDir.canonicalPath}\"", " *warn-on-reflection* ${reflectionWarnings.enabled}", " *compiler-options* {:disable-locals-clearing $disableLocalsClearing", " :elide-meta [${elideMeta.map { ":$it" }.joinToString(" ")}]", @@ -240,8 +242,6 @@ open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) : "(System/exit 0)") .joinToString("\n") - // println(script) - val stdout = object : LineProcessingOutputStream() { override fun processLine(line: String) { System.out.print(line) @@ -278,6 +278,8 @@ open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) : executeScript(script, stdout, stderr) + copyToDestination(tmpDestinationDir) + if (libraryReflectionWarningCount > 0) { System.err.println("$libraryReflectionWarningCount reflection warnings from dependencies") } @@ -287,18 +289,40 @@ open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) : } } + private fun copyToDestination(tmpDestinationDir: File) { + tmpDestinationDir.copyRecursively(target = destinationDir, overwrite = true, onError = FileCopyErrorHandler) + } + + private fun removeObsoleteClassFiles(destinationDir: File, tmpDestinationDir: File) { + tmpDestinationDir.walkBottomUp().forEach { + val relativeFile = it.relativeTo(tmpDestinationDir) + val fileInDestination = destinationDir.resolve(relativeFile) + if (fileInDestination.exists()) { + if (fileInDestination.delete()) { + logger.debug("Deleted obsolete output file {}", fileInDestination) + } else { + logger.warn("Couldn't delete obsolete output file {}", fileInDestination) + } + } + } + } + private fun executeScript(script: String, stdout: OutputStream, stderr: OutputStream) { val file = createTempFile("clojure-compiler", ".clj", temporaryDir) file.bufferedWriter().use { out -> out.write("$script\n") } - // println("Classpath: " + classpath.joinToString(", ")) - val exec = JavaExecHandleBuilder(fileResolver) copyTo(exec) exec.main = "clojure.main" - exec.classpath = classpath + + // clojure.core/compile requires following on its classpath: + // - libs (this.classpath) + // - namespaces sources to be compiled (getSourceRootsFiles) + // - *compile-path* directory (this.destinationDir) + exec.classpath = classpath + SimpleFileCollection(getSourceRootsFiles()) + SimpleFileCollection(destinationDir) + exec.setArgs(listOf("-i", file.canonicalPath)) exec.defaultCharacterEncoding = "UTF8" @@ -329,20 +353,21 @@ open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) : } val sources = getSource() - // println("Sources: " + sources.joinToString(", ")) val roots = getSourceRoots() - // println("Roots: " + roots.joinToString(", ")) - val namespaces = sources.map { findNamespace(it, roots) }.toList() + val namespaces = sources.map { findNamespace(it, roots) } return namespaces } private fun getSourceRoots(): HashSet { - val roots = source - .filter { it is SourceDirectorySet } - .flatMap { (it as SourceDirectorySet).srcDirs } + return getSourceRootsFiles() .map { it.canonicalPath } .toHashSet() - return roots + } + + private fun getSourceRootsFiles(): List { + return source + .filter { it is SourceDirectorySet } + .flatMap { (it as SourceDirectorySet).srcDirs } } companion object { @@ -379,6 +404,7 @@ open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) : val REFLECTION_WARNING_PREFIX = "Reflection warning, " + @Suppress("unused") fun munge(name: String): String { val sb = StringBuilder() for (c in name) { @@ -416,7 +442,9 @@ open class ClojureTestRunner @Inject constructor(val fileResolver: FileResolver) ConventionTask(), JavaForkOptions by DefaultJavaForkOptions(fileResolver) { + @Suppress("unused") var classpath: FileCollection = SimpleFileCollection() + @Suppress("unused") var namespaces: Collection = emptyList() var junitReport: File? = null @@ -440,8 +468,6 @@ open class ClojureTestRunner @Inject constructor(val fileResolver: FileResolver) val script = "$testRunnerScript\n$runnerInvocation" - // println(script) - executeScript(script) } @@ -453,8 +479,6 @@ open class ClojureTestRunner @Inject constructor(val fileResolver: FileResolver) val classpath = conventionMapping.getConventionValue(SimpleFileCollection(), "classpath", false) - // println("Classpath: " + classpath.joinToString(", ")) - val exec = JavaExecHandleBuilder(fileResolver) copyTo(exec) exec.main = "clojure.main" diff --git a/src/main/resources/META-INF/gradle-plugins/com.cursive-ide.clojure.properties b/src/main/resources/META-INF/gradle-plugins/com.cursive-ide.clojure.properties deleted file mode 100644 index e615d51..0000000 --- a/src/main/resources/META-INF/gradle-plugins/com.cursive-ide.clojure.properties +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright 2016 Colin Fleming -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -implementation-class=cursive.ClojurePlugin diff --git a/src/test/int-tests-projects/cursive/BasicClojureProjectTest/build.gradle b/src/test/int-tests-projects/cursive/BasicClojureProjectTest/build.gradle new file mode 100644 index 0000000..2e3ff66 --- /dev/null +++ b/src/test/int-tests-projects/cursive/BasicClojureProjectTest/build.gradle @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id 'com.cursive-ide.clojure' +} + +repositories { + mavenCentral() +} + +dependencies { + compile 'org.clojure:clojure:1.8.0' +} diff --git a/src/test/int-tests-projects/cursive/BasicClojureProjectTest/src/main/clojure/basic_project/core.clj b/src/test/int-tests-projects/cursive/BasicClojureProjectTest/src/main/clojure/basic_project/core.clj new file mode 100644 index 0000000..831e480 --- /dev/null +++ b/src/test/int-tests-projects/cursive/BasicClojureProjectTest/src/main/clojure/basic_project/core.clj @@ -0,0 +1,23 @@ +; +; Copyright 2017 Colin Fleming +; +; Licensed under the Apache License, Version 2.0 (the "License") +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; + +(ns basic-project.core) + +(defprotocol ITest) + +(defn hello [name] + (println "Generating message for" name) + (str "Hello " name)) diff --git a/src/test/int-tests-projects/cursive/BasicClojureProjectTest/src/test/clojure/basic_project/core_test.clj b/src/test/int-tests-projects/cursive/BasicClojureProjectTest/src/test/clojure/basic_project/core_test.clj new file mode 100644 index 0000000..7940020 --- /dev/null +++ b/src/test/int-tests-projects/cursive/BasicClojureProjectTest/src/test/clojure/basic_project/core_test.clj @@ -0,0 +1,22 @@ +; +; Copyright 2017 Colin Fleming +; +; Licensed under the Apache License, Version 2.0 (the "License") +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; + +(ns basic-project.core-test + (:require [basic-project.core :refer [hello]] + [clojure.test :refer :all])) + +(deftest test-hello + (is (= "Hello World" (hello "World")))) diff --git a/src/test/int-tests-projects/cursive/IncrementalCompilationTest/build.gradle b/src/test/int-tests-projects/cursive/IncrementalCompilationTest/build.gradle new file mode 100644 index 0000000..2e3ff66 --- /dev/null +++ b/src/test/int-tests-projects/cursive/IncrementalCompilationTest/build.gradle @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id 'com.cursive-ide.clojure' +} + +repositories { + mavenCentral() +} + +dependencies { + compile 'org.clojure:clojure:1.8.0' +} diff --git a/src/test/int-tests-projects/cursive/IncrementalCompilationTest/src/main/clojure/basic_project/core.clj b/src/test/int-tests-projects/cursive/IncrementalCompilationTest/src/main/clojure/basic_project/core.clj new file mode 100644 index 0000000..d0ac77d --- /dev/null +++ b/src/test/int-tests-projects/cursive/IncrementalCompilationTest/src/main/clojure/basic_project/core.clj @@ -0,0 +1,22 @@ +; +; Copyright 2017 Colin Fleming +; +; Licensed under the Apache License, Version 2.0 (the "License") +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; + +(ns basic-project.core) + +(defprotocol ITest) + +(defn hello [name] + (str "Hello " name)) diff --git a/src/test/int-tests-projects/cursive/JavaAndClojureInOneSourceSetTest/build.gradle b/src/test/int-tests-projects/cursive/JavaAndClojureInOneSourceSetTest/build.gradle new file mode 100644 index 0000000..e013c7e --- /dev/null +++ b/src/test/int-tests-projects/cursive/JavaAndClojureInOneSourceSetTest/build.gradle @@ -0,0 +1,31 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id 'com.cursive-ide.clojure' +} + +repositories { + mavenCentral() +} + +dependencies { + compile 'org.clojure:clojure:1.8.0' +} + +compileClojure { + aotCompile = true +} diff --git a/src/test/int-tests-projects/cursive/JavaAndClojureInOneSourceSetTest/src/main/clojure/clj_example/core.clj b/src/test/int-tests-projects/cursive/JavaAndClojureInOneSourceSetTest/src/main/clojure/clj_example/core.clj new file mode 100644 index 0000000..0db8f9a --- /dev/null +++ b/src/test/int-tests-projects/cursive/JavaAndClojureInOneSourceSetTest/src/main/clojure/clj_example/core.clj @@ -0,0 +1,19 @@ +; +; Copyright 2017 Colin Fleming +; +; Licensed under the Apache License, Version 2.0 (the "License") +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; + +(ns clj-example.core) + +(defn test []) diff --git a/src/test/int-tests-projects/cursive/JavaAndClojureInOneSourceSetTest/src/main/java/javaExample/Example.java b/src/test/int-tests-projects/cursive/JavaAndClojureInOneSourceSetTest/src/main/java/javaExample/Example.java new file mode 100644 index 0000000..969f60a --- /dev/null +++ b/src/test/int-tests-projects/cursive/JavaAndClojureInOneSourceSetTest/src/main/java/javaExample/Example.java @@ -0,0 +1,22 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javaExample; + +public class Example { + public void test() { + } +} \ No newline at end of file diff --git a/src/test/int-tests-projects/cursive/MixedClojureJavaTest/build.gradle b/src/test/int-tests-projects/cursive/MixedClojureJavaTest/build.gradle new file mode 100644 index 0000000..81a11bd --- /dev/null +++ b/src/test/int-tests-projects/cursive/MixedClojureJavaTest/build.gradle @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id 'com.cursive-ide.clojure' +} + +repositories { + mavenCentral() +} + +dependencies { + compile 'org.clojure:clojure:1.8.0' +} + +sourceSets { + cljSS { + compileClasspath += configurations.compile + runtimeClasspath += configurations.compile + } + javaSS { + compileClasspath += configurations.compile + runtimeClasspath += configurations.compile + compileClasspath += cljSS.output + runtimeClasspath += cljSS.output + } +} + +compileCljSSClojure { + aotCompile = true +} diff --git a/src/test/int-tests-projects/cursive/MixedClojureJavaTest/src/cljSS/clojure/cljSS/Example.clj b/src/test/int-tests-projects/cursive/MixedClojureJavaTest/src/cljSS/clojure/cljSS/Example.clj new file mode 100644 index 0000000..929886f --- /dev/null +++ b/src/test/int-tests-projects/cursive/MixedClojureJavaTest/src/cljSS/clojure/cljSS/Example.clj @@ -0,0 +1,20 @@ +; +; Copyright 2017 Colin Fleming +; +; Licensed under the Apache License, Version 2.0 (the "License") +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; + +(ns cljSS.Example + (:gen-class :methods [[test [] void]])) + +(defn -test [this]) diff --git a/src/test/int-tests-projects/cursive/MixedClojureJavaTest/src/javaSS/java/javaSS/Test.java b/src/test/int-tests-projects/cursive/MixedClojureJavaTest/src/javaSS/java/javaSS/Test.java new file mode 100644 index 0000000..dd13d18 --- /dev/null +++ b/src/test/int-tests-projects/cursive/MixedClojureJavaTest/src/javaSS/java/javaSS/Test.java @@ -0,0 +1,9 @@ +package javaSS; + +import cljSS.Example; + +public class Test { + public void test() { + new Example().test(); + } +} \ No newline at end of file diff --git a/src/test/int-tests-projects/cursive/MixedJavaClojureTest/build.gradle b/src/test/int-tests-projects/cursive/MixedJavaClojureTest/build.gradle new file mode 100644 index 0000000..9962cbc --- /dev/null +++ b/src/test/int-tests-projects/cursive/MixedJavaClojureTest/build.gradle @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id 'com.cursive-ide.clojure' +} + +repositories { + mavenCentral() +} + +dependencies { + compile 'org.clojure:clojure:1.8.0' +} + +sourceSets { + javaSS { + compileClasspath += configurations.compile + runtimeClasspath += configurations.compile + } + cljSS { + compileClasspath += configurations.compile + runtimeClasspath += configurations.compile + compileClasspath += javaSS.output + runtimeClasspath += javaSS.output + } +} + +compileCljSSClojure { + aotCompile = true +} diff --git a/src/test/int-tests-projects/cursive/MixedJavaClojureTest/src/cljSS/clojure/cljSS/core.clj b/src/test/int-tests-projects/cursive/MixedJavaClojureTest/src/cljSS/clojure/cljSS/core.clj new file mode 100644 index 0000000..c4edd31 --- /dev/null +++ b/src/test/int-tests-projects/cursive/MixedJavaClojureTest/src/cljSS/clojure/cljSS/core.clj @@ -0,0 +1,22 @@ +; +; Copyright 2017 Colin Fleming +; +; Licensed under the Apache License, Version 2.0 (the "License") +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; + +(ns cljSS.core + (:import (javaSS Example1 Example2))) + +(defn test [] + (.test (Example1.)) + (.test (Example2.))) diff --git a/src/test/int-tests-projects/cursive/MixedJavaClojureTest/src/javaSS/java/javaSS/Example1.java b/src/test/int-tests-projects/cursive/MixedJavaClojureTest/src/javaSS/java/javaSS/Example1.java new file mode 100644 index 0000000..a4eb91f --- /dev/null +++ b/src/test/int-tests-projects/cursive/MixedJavaClojureTest/src/javaSS/java/javaSS/Example1.java @@ -0,0 +1,22 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javaSS; + +public class Example1 { + public void test() { + } +} \ No newline at end of file diff --git a/src/test/int-tests-projects/cursive/MixedJavaClojureTest/src/javaSS/java/javaSS/Example2.java b/src/test/int-tests-projects/cursive/MixedJavaClojureTest/src/javaSS/java/javaSS/Example2.java new file mode 100644 index 0000000..4141d5e --- /dev/null +++ b/src/test/int-tests-projects/cursive/MixedJavaClojureTest/src/javaSS/java/javaSS/Example2.java @@ -0,0 +1,22 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javaSS; + +public class Example2 { + public void test() { + } +} \ No newline at end of file diff --git a/src/test/int-tests-projects/cursive/MultipleSourceSetsTest/build.gradle b/src/test/int-tests-projects/cursive/MultipleSourceSetsTest/build.gradle new file mode 100644 index 0000000..cdc9aee --- /dev/null +++ b/src/test/int-tests-projects/cursive/MultipleSourceSetsTest/build.gradle @@ -0,0 +1,50 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id 'com.cursive-ide.clojure' +} + +repositories { + mavenCentral() +} + +dependencies { + compile 'org.clojure:clojure:1.8.0' +} + +sourceSets { + ss1 { + } + ss2 { + compileClasspath += configurations.compile + compileClasspath += ss1.output + runtimeClasspath += configurations.compile + runtimeClasspath += ss1.output + } + test { + compileClasspath += configurations.compile + runtimeClasspath += configurations.compile + compileClasspath += ss1.output + runtimeClasspath += ss1.output + compileClasspath += ss2.output + runtimeClasspath += ss2.output + } +} + +compileSs2Clojure { + aotCompile = true +} diff --git a/src/test/int-tests-projects/cursive/MultipleSourceSetsTest/src/ss1/clojure/ss1/core.clj b/src/test/int-tests-projects/cursive/MultipleSourceSetsTest/src/ss1/clojure/ss1/core.clj new file mode 100644 index 0000000..6213fce --- /dev/null +++ b/src/test/int-tests-projects/cursive/MultipleSourceSetsTest/src/ss1/clojure/ss1/core.clj @@ -0,0 +1,20 @@ +; +; Copyright 2017 Colin Fleming +; +; Licensed under the Apache License, Version 2.0 (the "License") +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; + +(ns ss1.core) + +(defn hello [] + "SourceSet1") diff --git a/src/test/int-tests-projects/cursive/MultipleSourceSetsTest/src/ss2/clojure/ss2/core.clj b/src/test/int-tests-projects/cursive/MultipleSourceSetsTest/src/ss2/clojure/ss2/core.clj new file mode 100644 index 0000000..fe664e1 --- /dev/null +++ b/src/test/int-tests-projects/cursive/MultipleSourceSetsTest/src/ss2/clojure/ss2/core.clj @@ -0,0 +1,21 @@ +; +; Copyright 2017 Colin Fleming +; +; Licensed under the Apache License, Version 2.0 (the "License") +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; + +(ns ss2.core + (:require [ss1.core])) + +(defn hello [] + (str "SourceSet2 " (ss1.core/hello))) diff --git a/src/test/int-tests-projects/cursive/MultipleSourceSetsTest/src/test/clojure/test/core_test.clj b/src/test/int-tests-projects/cursive/MultipleSourceSetsTest/src/test/clojure/test/core_test.clj new file mode 100644 index 0000000..3cdb59a --- /dev/null +++ b/src/test/int-tests-projects/cursive/MultipleSourceSetsTest/src/test/clojure/test/core_test.clj @@ -0,0 +1,24 @@ +; +; Copyright 2017 Colin Fleming +; +; Licensed under the Apache License, Version 2.0 (the "License") +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; + +(ns test.core-test + (:require [ss1.core] + [ss2.core] + [clojure.test :refer :all])) + +(deftest hello-test + (println "Test1" (ss1.core/hello)) + (println "Test2" (ss2.core/hello))) diff --git a/src/test/int-tests-projects/cursive/TestFailureFailsBuildTest/build.gradle b/src/test/int-tests-projects/cursive/TestFailureFailsBuildTest/build.gradle new file mode 100644 index 0000000..2e3ff66 --- /dev/null +++ b/src/test/int-tests-projects/cursive/TestFailureFailsBuildTest/build.gradle @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id 'com.cursive-ide.clojure' +} + +repositories { + mavenCentral() +} + +dependencies { + compile 'org.clojure:clojure:1.8.0' +} diff --git a/src/test/int-tests-projects/cursive/TestFailureFailsBuildTest/src/main/clojure/basic_project/core.clj b/src/test/int-tests-projects/cursive/TestFailureFailsBuildTest/src/main/clojure/basic_project/core.clj new file mode 100644 index 0000000..f8b3b7c --- /dev/null +++ b/src/test/int-tests-projects/cursive/TestFailureFailsBuildTest/src/main/clojure/basic_project/core.clj @@ -0,0 +1,21 @@ +; +; Copyright 2017 Colin Fleming +; +; Licensed under the Apache License, Version 2.0 (the "License") +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; + +(ns basic-project.core) + +(defn hello [name] + (println "Generating message for" name) + (str "Hello " name)) diff --git a/src/test/int-tests-projects/cursive/TestFailureFailsBuildTest/src/test/clojure/basic_project/core_test.clj b/src/test/int-tests-projects/cursive/TestFailureFailsBuildTest/src/test/clojure/basic_project/core_test.clj new file mode 100644 index 0000000..34ebd19 --- /dev/null +++ b/src/test/int-tests-projects/cursive/TestFailureFailsBuildTest/src/test/clojure/basic_project/core_test.clj @@ -0,0 +1,22 @@ +; +; Copyright 2017 Colin Fleming +; +; Licensed under the Apache License, Version 2.0 (the "License") +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; + +(ns basic-project.core-test + (:require [basic-project.core :refer [hello]] + [clojure.test :refer :all])) + +(deftest test-hello + (is (= "Hello World!" (hello "World")))) diff --git a/src/test/kotlin/cursive/BasicClojureProjectTest.kt b/src/test/kotlin/cursive/BasicClojureProjectTest.kt new file mode 100644 index 0000000..a8991af --- /dev/null +++ b/src/test/kotlin/cursive/BasicClojureProjectTest.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cursive + +import org.assertj.core.api.KotlinAssertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Assert.assertTrue +import org.junit.Test + +class BasicClojureProjectTest : IntegrationTestBase() { + val coreNsSourceFile = testProjectDir.resolve("src/main/clojure/basic_project/core.clj") + + @Test + fun `Build without AOT only copies clj files to output directory`() { + // when + val result = projectBuildRunner().withArguments("check").build() + + // then + assertThat(result.task(":compileClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":compileTestClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":testClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + + assertSourceFileIsOnlyCopiedToOutputDir(coreNsSourceFile) + + assertThat(result.output).contains("Generating message for World") + } + + @Test + fun `Build with AOT compiles to class files without copying clj files to output directory`() { + // given + projectGradleFile().appendText("compileClojure.aotCompile = true") + + // when + val result = projectBuildRunner().withArguments("check").build() + + // then + assertThat(result.task(":compileClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":compileTestClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":testClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + + assertSourceFileIsOnlyCompiledToOutputDir(coreNsSourceFile) + assertTrue("Protocol class file exists", testProjectDir.resolve("build/classes/main/basic_project/core/ITest.class").exists()) + + assertThat(result.output).contains("Generating message for World") + } +} diff --git a/src/test/kotlin/cursive/IncrementalCompilationTest.kt b/src/test/kotlin/cursive/IncrementalCompilationTest.kt new file mode 100644 index 0000000..9fe3f46 --- /dev/null +++ b/src/test/kotlin/cursive/IncrementalCompilationTest.kt @@ -0,0 +1,119 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cursive + +import org.assertj.core.api.KotlinAssertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Assert.assertFalse +import org.junit.Test + +class IncrementalCompilationTest : IntegrationTestBase() { + val coreNsSourceFile = testProjectDir.resolve("src/main/clojure/basic_project/core.clj") + + @Test + fun `Incremental compile task without AOT is up-to-date when no input changes`() { + // when + val firstRunResult = projectBuildRunner().withArguments("check").build() + + // then + assertThat(firstRunResult.task(":compileClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertSourceFileIsOnlyCopiedToOutputDir(coreNsSourceFile) + + // when + val secondRunResult = projectBuildRunner().withArguments("check").build() + + // then + assertThat(secondRunResult.task(":compileClojure").outcome).isEqualTo(TaskOutcome.UP_TO_DATE) + assertSourceFileIsOnlyCopiedToOutputDir(coreNsSourceFile) + } + + @Test + fun `Incremental compile task with AOT is up-to-date when no input changes`() { + // given + projectGradleFile().appendText("compileClojure.aotCompile = true") + + // when + val firstRunResult = projectBuildRunner().withArguments("check").build() + + // then + assertThat(firstRunResult.task(":compileClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertSourceFileIsOnlyCompiledToOutputDir(coreNsSourceFile) + + // when + val secondRunResult = projectBuildRunner().withArguments("check").build() + + // then + assertThat(secondRunResult.task(":compileClojure").outcome).isEqualTo(TaskOutcome.UP_TO_DATE) + assertSourceFileIsOnlyCompiledToOutputDir(coreNsSourceFile) + } + + @Test + fun `Incremental compile task without AOT processes outdated source files when input changes`() { + // given + val utilsNsSourceFile = testProjectDir.resolve("src/main/clojure/basic_project/utils.clj") + + // when + val firstRunResult = projectBuildRunner().withArguments("check").build() + + // then + assertThat(firstRunResult.task(":compileClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertSourceFileIsOnlyCopiedToOutputDir(coreNsSourceFile) + assertSourceFileNotCopiedToOutputDir(utilsNsSourceFile) + assertSourceFileNotCompiledToOutputDir(utilsNsSourceFile) + + coreNsSourceFile.delete() + utilsNsSourceFile.writeText("""(ns basic-project.utils) (defn ping [] "pong")""") + + // when + val secondRunResult = projectBuildRunner().withArguments("check").build() + + // then + assertThat(secondRunResult.task(":compileClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertSourceFileNotCopiedToOutputDir(coreNsSourceFile) + assertSourceFileNotCompiledToOutputDir(coreNsSourceFile) + assertSourceFileIsOnlyCopiedToOutputDir(utilsNsSourceFile) + } + + @Test + fun `Incremental compile task with AOT processes outdated source files when input changes`() { + // given + projectGradleFile().appendText("compileClojure.aotCompile = true") + val utilsNsSourceFile = testProjectDir.resolve("src/main/clojure/basic_project/utils.clj") + + // when + val firstRunResult = projectBuildRunner().withArguments("check").build() + + // then + assertThat(firstRunResult.task(":compileClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertSourceFileCompiledToOutputDir(coreNsSourceFile) + assertSourceFileNotCopiedToOutputDir(utilsNsSourceFile) + assertSourceFileNotCompiledToOutputDir(utilsNsSourceFile) + + coreNsSourceFile.delete() + utilsNsSourceFile.writeText("""(ns basic-project.utils) (defn ping [] "pong")""") + + // when + val secondRunResult = projectBuildRunner().withArguments("check").build() + + // then + assertThat(secondRunResult.task(":compileClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertSourceFileNotCopiedToOutputDir(coreNsSourceFile) + assertSourceFileNotCompiledToOutputDir(coreNsSourceFile) + assertSourceFileIsOnlyCompiledToOutputDir(utilsNsSourceFile) + assertFalse("Protocol class file doesn't exists", testProjectDir.resolve("build/classes/main/basic_project/core/ITest.class").exists()) + } +} diff --git a/src/test/kotlin/cursive/IntegrationTestBase.kt b/src/test/kotlin/cursive/IntegrationTestBase.kt new file mode 100644 index 0000000..f20d04d --- /dev/null +++ b/src/test/kotlin/cursive/IntegrationTestBase.kt @@ -0,0 +1,150 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cursive + +import org.gradle.testkit.runner.GradleRunner +import org.junit.Assert.* +import org.junit.Before +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import java.io.File +import java.util.* + +open class IntegrationTestBase { + @Rule + @JvmField + val tempDir: TemporaryFolder = initTempDir() + val testProjectDir: File = tempDir.root + + @Before + fun setup() { + val sourceDirectory = File("src/test/int-tests-projects", this.javaClass.name.replace('.', '/')) + + if (sourceDirectory.exists()) { + sourceDirectory.copyRecursively(target = testProjectDir, overwrite = true) + } else { + println("Source directory ${sourceDirectory.absolutePath} doesn't exist") + } + } + + fun projectBuildRunner(): GradleRunner { + return GradleRunner.create().withPluginClasspath().withProjectDir(testProjectDir) + } + + fun projectGradleFile(): File { + return testProjectDir.resolve("build.gradle") + } + + fun buildDirFiles(): List { + return testProjectDir.resolve("build").walkTopDown().toList() + } + + fun assertSourceFileCopiedToOutputDir( + sourceFile: File, + sourceBaseDir: File = testProjectDir.resolve("src/main/clojure"), + outputDir: File = testProjectDir.resolve("build/classes/main")) { + + val expectedOutputFile = outputFileForSourceFile(sourceFile, sourceBaseDir, outputDir) + if (!expectedOutputFile.exists()) { + fail("Expected output file doesn't exist for source file ${sourceFile}") + } + val sourceFileContents = sourceFile.readText() + val outputFileContents = expectedOutputFile.readText() + assertEquals("Source and output files content", sourceFileContents, outputFileContents) + } + + fun assertSourceFileCompiledToOutputDir( + sourceFile: File, + sourceBaseDir: File = testProjectDir.resolve("src/main/clojure"), + outputDir: File = testProjectDir.resolve("build/classes/main")) { + + val classFiles = compiledClassFilesForSourceFile(sourceFile, sourceBaseDir, outputDir) + if (classFiles.isEmpty()) { + fail("No compiled files have been found for source file ${sourceFile}") + } + } + + fun assertSourceFileNotCopiedToOutputDir( + sourceFile: File, + sourceBaseDir: File = testProjectDir.resolve("src/main/clojure"), + outputDir: File = testProjectDir.resolve("build/classes/main")) { + + assertFalse( + "Source file exists in output dir", + outputFileForSourceFile(sourceFile, sourceBaseDir, outputDir).exists()) + } + + fun assertSourceFileNotCompiledToOutputDir( + sourceFile: File, + sourceBaseDir: File = testProjectDir.resolve("src/main/clojure"), + outputDir: File = testProjectDir.resolve("build/classes/main")) { + + assertTrue( + "Compiled files exists in output dir", + compiledClassFilesForSourceFile(sourceFile, sourceBaseDir, outputDir).isEmpty()) + } + + fun assertSourceFileIsOnlyCopiedToOutputDir( + sourceFile: File, + sourceBaseDir: File = testProjectDir.resolve("src/main/clojure"), + outputDir: File = testProjectDir.resolve("build/classes/main")) { + + assertSourceFileCopiedToOutputDir(sourceFile, sourceBaseDir, outputDir) + assertSourceFileNotCompiledToOutputDir(sourceFile, sourceBaseDir, outputDir) + } + + fun assertSourceFileIsOnlyCompiledToOutputDir( + sourceFile: File, + sourceBaseDir: File = testProjectDir.resolve("src/main/clojure"), + outputDir: File = testProjectDir.resolve("build/classes/main")) { + + assertSourceFileNotCopiedToOutputDir(sourceFile, sourceBaseDir, outputDir) + assertSourceFileCompiledToOutputDir(sourceFile, sourceBaseDir, outputDir) + } + + fun outputFileForSourceFile( + sourceFile: File, + sourceBaseDir: File = testProjectDir.resolve("src/main/clojure"), + outputDir: File = testProjectDir.resolve("build/classes/main")): File { + + val relativeSourceFile = sourceFile.relativeTo(sourceBaseDir) + return outputDir.resolve(relativeSourceFile) + } + + fun compiledClassFilesForSourceFile( + sourceFile: File, + sourceBaseDir: File = testProjectDir.resolve("src/main/clojure"), + outputDir: File = testProjectDir.resolve("build/classes/main")): List { + + val relativeSourceFile = sourceFile.relativeTo(sourceBaseDir) + val relativeSourceFileDir = relativeSourceFile.parentFile + val sourceFileName = sourceFile.nameWithoutExtension + + return outputDir + .resolve(relativeSourceFileDir) + .listFiles { file -> + file.nameWithoutExtension.startsWith(sourceFileName) && file.extension == "class"} + ?.toList() + ?: Collections.emptyList() + } + + private fun initTempDir(): TemporaryFolder { + val tmpDir = TemporaryFolder() + tmpDir.create() + return tmpDir + } +} diff --git a/src/test/kotlin/cursive/JavaAndClojureInOneSourceSetTest.kt b/src/test/kotlin/cursive/JavaAndClojureInOneSourceSetTest.kt new file mode 100644 index 0000000..0e923fe --- /dev/null +++ b/src/test/kotlin/cursive/JavaAndClojureInOneSourceSetTest.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cursive + +import org.assertj.core.api.KotlinAssertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Test + +class JavaAndClojureInOneSourceSetTest : IntegrationTestBase() { + val coreNsSourceFile = testProjectDir.resolve("src/main/clojure/clj_example/core.clj") + val utilsNsSourceFile = testProjectDir.resolve("src/main/clojure/clj_example/utils.clj") + val javaClassFile = testProjectDir.resolve("build/classes/main/javaExample/Example.class") + + @Test + fun `Incremental compile task does not remove Java class files`() { + // when + val firstRunResult = projectBuildRunner().withArguments("build").build() + + // then + assertThat(firstRunResult.task(":compileClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(firstRunResult.task(":compileJava").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertSourceFileIsOnlyCompiledToOutputDir(coreNsSourceFile) + assertThat(javaClassFile.exists()).isTrue() + + coreNsSourceFile.delete() + utilsNsSourceFile.writeText("""(ns clj-example.utils) (defn ping [] "pong")""") + + // when + val secondRunResult = projectBuildRunner().withArguments("build").build() + + // then + assertThat(secondRunResult.task(":compileClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(secondRunResult.task(":compileJava").outcome).isEqualTo(TaskOutcome.UP_TO_DATE) + assertSourceFileNotCopiedToOutputDir(coreNsSourceFile) + assertSourceFileNotCompiledToOutputDir(coreNsSourceFile) + assertSourceFileIsOnlyCompiledToOutputDir(utilsNsSourceFile) + assertThat(javaClassFile.exists()).isTrue() + } +} diff --git a/src/test/kotlin/cursive/MixedClojureJavaTest.kt b/src/test/kotlin/cursive/MixedClojureJavaTest.kt new file mode 100644 index 0000000..e87c929 --- /dev/null +++ b/src/test/kotlin/cursive/MixedClojureJavaTest.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cursive + +import org.assertj.core.api.KotlinAssertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Test + +class MixedClojureJavaTest : IntegrationTestBase() { + @Test + fun `Compilation with Java code depending on Clojure code`() { + // given + val cljSourceDir = testProjectDir.resolve("src/cljSS/clojure") + val cljExampleNsFile = cljSourceDir.resolve("cljSS/Example.clj") + val cljOutputDir = testProjectDir.resolve("build/classes/cljSS") + + val javaOutputDir = testProjectDir.resolve("build/classes/javaSS") + val javaClassFile = javaOutputDir.resolve("javaSS/Test.class") + + // when + val result = projectBuildRunner().withArguments("compileJavaSSJava").build() + + // then + assertThat(result.task(":compileCljSSClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":compileJavaSSJava").outcome).isEqualTo(TaskOutcome.SUCCESS) + + assertSourceFileIsOnlyCompiledToOutputDir(cljExampleNsFile, cljSourceDir, cljOutputDir) + assertThat(javaClassFile.exists()).isTrue() + } +} diff --git a/src/test/kotlin/cursive/MixedJavaClojureTest.kt b/src/test/kotlin/cursive/MixedJavaClojureTest.kt new file mode 100644 index 0000000..0181ed5 --- /dev/null +++ b/src/test/kotlin/cursive/MixedJavaClojureTest.kt @@ -0,0 +1,96 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cursive + +import org.assertj.core.api.KotlinAssertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Test + +class MixedJavaClojureTest : IntegrationTestBase() { + val javaOutputDir = testProjectDir.resolve("build/classes/javaSS") + val javaExample1SourceFile = testProjectDir.resolve("src/javaSS/java/javaSS/Example1.java") + val javaExample1ClassFile = javaOutputDir.resolve("javaSS/Example1.class") + val javaExample2ClassFile = javaOutputDir.resolve("javaSS/Example2.class") + + val cljSourceDir = testProjectDir.resolve("src/cljSS/clojure") + val cljCoreNsFile = cljSourceDir.resolve("cljSS/core.clj") + val cljOutputDir = testProjectDir.resolve("build/classes/cljSS") + + @Test + fun `Compilation with Clojure code depending on Java code`() { + // when + val result = projectBuildRunner().withArguments("compileCljSSClojure").build() + + // then + assertThat(result.task(":compileJavaSSJava").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":compileCljSSClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + + assertThat(javaExample1ClassFile.exists()).isTrue() + assertThat(javaExample2ClassFile.exists()).isTrue() + assertSourceFileIsOnlyCompiledToOutputDir(cljCoreNsFile, cljSourceDir, cljOutputDir) + } + + @Test + fun `Incremental compilation with Clojure code depending on Java code when Java source unchanged`() { + // when + val firstResult = projectBuildRunner().withArguments("compileCljSSClojure").build() + + // then + assertThat(firstResult.task(":compileJavaSSJava").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(firstResult.task(":compileCljSSClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + + assertThat(javaExample1ClassFile.exists()).isTrue() + assertThat(javaExample2ClassFile.exists()).isTrue() + assertSourceFileIsOnlyCompiledToOutputDir(cljCoreNsFile, cljSourceDir, cljOutputDir) + + // when + val secondResult = projectBuildRunner().withArguments("compileCljSSClojure").build() + + // then + println(secondResult.output) + assertThat(secondResult.task(":compileJavaSSJava").outcome).isEqualTo(TaskOutcome.UP_TO_DATE) + assertThat(secondResult.task(":compileCljSSClojure").outcome).isEqualTo(TaskOutcome.UP_TO_DATE) + + assertThat(javaExample1ClassFile.exists()).isTrue() + assertThat(javaExample2ClassFile.exists()).isTrue() + assertSourceFileIsOnlyCompiledToOutputDir(cljCoreNsFile, cljSourceDir, cljOutputDir) + } + + @Test + fun `Incremental compilation with Clojure code depending on Java code when Java source changes`() { + // when + val firstResult = projectBuildRunner().withArguments("compileCljSSClojure").build() + + // then + assertThat(firstResult.task(":compileJavaSSJava").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(firstResult.task(":compileCljSSClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + + assertThat(javaExample1ClassFile.exists()).isTrue() + assertThat(javaExample2ClassFile.exists()).isTrue() + assertSourceFileIsOnlyCompiledToOutputDir(cljCoreNsFile, cljSourceDir, cljOutputDir) + + // when + javaExample1SourceFile.delete() + val secondResult = projectBuildRunner().withArguments("compileCljSSClojure").buildAndFail() + + // then + assertThat(secondResult.task(":compileJavaSSJava").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(secondResult.task(":compileCljSSClojure").outcome).isEqualTo(TaskOutcome.FAILED) + + assertThat(secondResult.output).contains("java.lang.ClassNotFoundException: javaSS.Example1") + } +} \ No newline at end of file diff --git a/src/test/kotlin/cursive/MultipleSourceSetsTest.kt b/src/test/kotlin/cursive/MultipleSourceSetsTest.kt new file mode 100644 index 0000000..6436e1e --- /dev/null +++ b/src/test/kotlin/cursive/MultipleSourceSetsTest.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cursive + +import org.assertj.core.api.KotlinAssertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Test + +class MultipleSourceSetsTest : IntegrationTestBase() { + @Test + fun `Compilation with multiple source sets`() { + // given + val ss1SourceDir = testProjectDir.resolve("src/ss1/clojure") + val ss1CoreNsFile = ss1SourceDir.resolve("ss1/core.clj") + val ss1OutputDir = testProjectDir.resolve("build/classes/ss1") + + val ss2SourceDir = testProjectDir.resolve("src/ss2/clojure") + val ss2CoreNsFile = ss2SourceDir.resolve("ss2/core.clj") + val ss2OutputDir = testProjectDir.resolve("build/classes/ss2") + + // when + val result = projectBuildRunner().withArguments("check").build() + + // then + assertThat(result.task(":compileSs1Clojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":compileSs2Clojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":compileTestClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + + assertSourceFileIsOnlyCopiedToOutputDir(ss1CoreNsFile, ss1SourceDir, ss1OutputDir) + assertSourceFileIsOnlyCompiledToOutputDir(ss2CoreNsFile, ss2SourceDir, ss2OutputDir) + + assertThat(result.output).contains("Test1 SourceSet1") + assertThat(result.output).contains("Test2 SourceSet2 SourceSet1") + } +} diff --git a/src/test/kotlin/cursive/TestFailureFailsBuildTest.kt b/src/test/kotlin/cursive/TestFailureFailsBuildTest.kt new file mode 100644 index 0000000..b074d0a --- /dev/null +++ b/src/test/kotlin/cursive/TestFailureFailsBuildTest.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Colin Fleming + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cursive + +import org.assertj.core.api.KotlinAssertions +import org.gradle.testkit.runner.GradleRunner +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Test + +class TestFailureFailsBuildTest : IntegrationTestBase() { + @Test + fun `testClojure task failure fails build`() { + // when + val result = projectBuildRunner().withArguments("check").buildAndFail() + + // then + KotlinAssertions.assertThat(result.task(":compileClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + KotlinAssertions.assertThat(result.task(":compileTestClojure").outcome).isEqualTo(TaskOutcome.SUCCESS) + KotlinAssertions.assertThat(result.task(":testClojure").outcome).isEqualTo(TaskOutcome.FAILED) + } +}