From fe5a55d754ec6bee09e49473a542e290e6f4abeb Mon Sep 17 00:00:00 2001 From: "R. Tyler Croy" Date: Fri, 14 Aug 2015 11:24:32 -0700 Subject: [PATCH] Introduce some GradleTestKit-based tests and the supporting infra to run them Some of this was unapologetically pilfered from the core plugins --- build.gradle | 21 ++++++--- buildSrc/.gitignore | 2 + buildSrc/src/main/groovy/GradleDist.groovy | 44 +++++++++++++++++++ examples/word-count/build.gradle | 5 +-- gradle.properties | 2 +- gradle/integration-test.gradle | 18 +++++++- .../JRubyStormTaskIntegrationSpec.groovy | 39 +++++++++------- .../jrubygradle/storm/JRubyStorm.groovy | 30 ++----------- .../jrubygradle/storm/JRubyStormPlugin.groovy | 4 +- .../storm/internal/JRubyStorm.groovy | 31 +++++++++++++ .../storm/internal/JRubyStormJar.groovy | 8 ++++ .../storm/internal/JRubyStormJarSpec.groovy | 17 +++++++ .../storm/internal/JRubyStormSpec.groovy | 29 ++++++++++++ 13 files changed, 193 insertions(+), 57 deletions(-) create mode 100644 buildSrc/.gitignore create mode 100644 buildSrc/src/main/groovy/GradleDist.groovy create mode 100644 src/main/groovy/com/github/jrubygradle/storm/internal/JRubyStorm.groovy create mode 100644 src/main/groovy/com/github/jrubygradle/storm/internal/JRubyStormJar.groovy create mode 100644 src/test/groovy/com/github/jrubygradle/storm/internal/JRubyStormJarSpec.groovy create mode 100644 src/test/groovy/com/github/jrubygradle/storm/internal/JRubyStormSpec.groovy diff --git a/build.gradle b/build.gradle index 006c9cc..82eccd9 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,6 @@ buildscript { classpath "org.ysb33r.gradle:gradletest:0.5.4" } } - apply plugin: 'codenarc' apply plugin: 'groovy' apply plugin: 'maven' @@ -28,8 +27,7 @@ repositories { } dependencies { - compile gradleApi() - compile localGroovy() + compile new GradleDist(project, '2.0').asFileTree ['jruby-gradle-plugin', 'jruby-gradle-jar-plugin'].each { String plugin -> String pluginDependency = "com.github.jruby-gradle:${plugin}:${jrubyGradleMinVersion}" @@ -37,13 +35,26 @@ dependencies { gradleTest pluginDependency } - compile 'com.github.jengelman.gradle.plugins:shadow:1.2.2+' - testCompile ("org.spockframework:spock-core:0.7-groovy-${gradle.gradleVersion.startsWith('1.')?'1.8':'2.0'}") { exclude module : 'groovy-all' } } +plugins.withType(JavaPlugin) { + sourceCompatibility = 1.7 + targetCompatibility = 1.7 + + project.tasks.withType(JavaCompile) { task -> + task.sourceCompatibility = project.sourceCompatibility + task.targetCompatibility = project.targetCompatibility + } + + project.tasks.withType(GroovyCompile) { task -> + task.sourceCompatibility = project.sourceCompatibility + task.targetCompatibility = project.targetCompatibility + } +} + codenarc { sourceSets = [sourceSets.main] configFile = file('gradle/codenarc.xml') diff --git a/buildSrc/.gitignore b/buildSrc/.gitignore new file mode 100644 index 0000000..0066219 --- /dev/null +++ b/buildSrc/.gitignore @@ -0,0 +1,2 @@ +build/ +*swp* diff --git a/buildSrc/src/main/groovy/GradleDist.groovy b/buildSrc/src/main/groovy/GradleDist.groovy new file mode 100644 index 0000000..28456c7 --- /dev/null +++ b/buildSrc/src/main/groovy/GradleDist.groovy @@ -0,0 +1,44 @@ +import org.gradle.api.Project +import org.gradle.api.file.FileTree +import org.gradle.wrapper.Download +import org.gradle.wrapper.Install +import org.gradle.wrapper.Logger +import org.gradle.wrapper.PathAssembler +import org.gradle.wrapper.WrapperConfiguration + +/** + * Include this in your project's buildSrc, then add a dependency to your project: + * compile new GradleDist(project, '2.6').asFileTree + * + * Code courtesy of @ajoberstar + */ +class GradleDist { + private final Project project + final String version + + GradleDist(Project project, String version) { + this.project = project + this.version = version + } + + String getPath() { + return "https://services.gradle.org/distributions/gradle-${version}-bin.zip" + } + + File getAsFile() { + return project.file(getPath()) + } + + URI getAsURI() { + return project.uri(getPath()) + } + + FileTree getAsFileTree() { + Logger logger = new Logger(true) + Install install = new Install(logger, new Download(logger, 'gradle', ''), new PathAssembler(project.gradle.gradleUserHomeDir)) + WrapperConfiguration config = new WrapperConfiguration() + config.distribution = getAsURI() + File file = install.createDist(config) + return project.fileTree(dir:file, include:'**/*.jar') + } +} diff --git a/examples/word-count/build.gradle b/examples/word-count/build.gradle index 198cd72..2aba2b9 100644 --- a/examples/word-count/build.gradle +++ b/examples/word-count/build.gradle @@ -6,13 +6,12 @@ buildscript { } dependencies { - //classpath 'com.github.jruby-gradle:jruby-gradle-storm-plugin:0.2.0' + classpath 'com.github.jruby-gradle:jruby-gradle-jar-plugin:1.0.2' /* Replace "%%VERSION%%" with the version of JRuby/Gradle Storm you wish to * use if you want to use this build.gradle outside of gradleTest */ classpath 'com.github.jruby-gradle:jruby-gradle-storm-plugin:%%VERSION%%' - classpath 'com.github.jruby-gradle:jruby-gradle-plugin:1.0.1' - classpath 'com.github.jruby-gradle:jruby-gradle-jar-plugin:1.0.1' + //classpath 'com.github.jruby-gradle:jruby-gradle-storm-plugin:0.2.0' } } diff --git a/gradle.properties b/gradle.properties index c5df95c..055e24f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,4 +4,4 @@ bintrayKey= sourceCompatibility=1.7 targetCompatibility=1.7 -jrubyGradleMinVersion=1.0.1 +jrubyGradleMinVersion=1.0.2 diff --git a/gradle/integration-test.gradle b/gradle/integration-test.gradle index 580e0ab..6779bb7 100644 --- a/gradle/integration-test.gradle +++ b/gradle/integration-test.gradle @@ -3,7 +3,7 @@ import groovy.json.JsonOutput apply plugin: 'org.ysb33r.gradletest' configurations { - integrationTestCompile.extendsFrom testCompile + integrationTestCompile.extendsFrom testCompile, compile integrationTestRuntime.extendsFrom testRuntime, integrationTestCompile } @@ -52,7 +52,21 @@ gradleTest { } dependencies { - integrationTestCompile gradleTestKit() + /* Without pruning the groovy-all dependency from this file list, we end up + * with two groovys running around and this exception at runtime: + * groovy.lang.GroovyRuntimeException: Conflicting module versions. Module [groovy-all is loaded in version 2.3.10 and you are trying to load version 2.3.3 + at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl$DefaultModuleListener.onModule(MetaClassRegistryImpl.java:509) + at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanExtensionModuleFromProperties(ExtensionModuleScanner.java:77) + at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanExtensionModuleFromMetaInf(ExtensionModuleScanner.java:71) + at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanClasspathModules(ExtensionModuleScanner.java:53) + at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.(MetaClassRegistryImpl.java:110) + at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.(MetaClassRegistryImpl.java:71) + at groovy.lang.GroovySystem.(GroovySystem.java:33) + */ + integrationTestCompile files(gradleTestKit().resolve().findAll { File f -> + !f.name.matches(/groovy-all-(.*).jar/) + }) + /* add our TestKit classpath to our test runtime so we can find it again */ integrationTestRuntime files(prepareGradleTestKitClasspath) } diff --git a/src/integTest/groovy/com/github/jrubygradle/storm/JRubyStormTaskIntegrationSpec.groovy b/src/integTest/groovy/com/github/jrubygradle/storm/JRubyStormTaskIntegrationSpec.groovy index 91a6236..bb20d36 100644 --- a/src/integTest/groovy/com/github/jrubygradle/storm/JRubyStormTaskIntegrationSpec.groovy +++ b/src/integTest/groovy/com/github/jrubygradle/storm/JRubyStormTaskIntegrationSpec.groovy @@ -11,25 +11,8 @@ import org.junit.rules.TemporaryFolder import spock.lang.* /** - * This integration test will stand up Gradle integration tests using */ class JRubyStormTaskIntegrationSpec extends Specification { - @Rule - final TemporaryFolder testProjectDir = new TemporaryFolder() - File buildFile - String pluginDependencies - - def setup() { - buildFile = testProjectDir.newFile('build.gradle') - def pluginClasspathResource = getClass().classLoader.findResource("plugin-classpath.json") - - if (pluginClasspathResource == null) { - throw new IllegalStateException("Did not find plugin classpath resource, run `testClasses` build task.") - } - - pluginDependencies = pluginClasspathResource.text //(new JsonSlurper()).parseText(pluginClasspathResource.text) - } - def "evaluation of the project should result in an assemble and run task"() { given: Project project = ProjectBuilder.builder().build() @@ -71,6 +54,25 @@ class JRubyStormTaskIntegrationSpec extends Specification { it.name == 'storm-core' } } +} + +/** Integration tests which actually execute Gradle via the GradleTestKit */ +class JRubyStormTestKitSpec extends Specification { + @Rule + final TemporaryFolder testProjectDir = new TemporaryFolder() + File buildFile + String pluginDependencies + + def setup() { + buildFile = testProjectDir.newFile('build.gradle') + def pluginClasspathResource = getClass().classLoader.findResource("plugin-classpath.json") + + if (pluginClasspathResource == null) { + throw new IllegalStateException("Did not find plugin classpath resource, run `testClasses` build task.") + } + + pluginDependencies = pluginClasspathResource.text + } def "executing the assemble task produces a jar artifact"() { given: @@ -81,6 +83,7 @@ buildscript { } } apply plugin: 'com.github.jruby-gradle.storm' + jrubyStorm { } """ @@ -94,6 +97,8 @@ jrubyStorm { then: File[] artifacts = (new File(testProjectDir.root, ['build', 'libs'].join(File.separator))).listFiles() artifacts && artifacts.size() == 1 + + and: result.task(":assembleJRubyStorm").outcome == TaskOutcome.SUCCESS } } \ No newline at end of file diff --git a/src/main/groovy/com/github/jrubygradle/storm/JRubyStorm.groovy b/src/main/groovy/com/github/jrubygradle/storm/JRubyStorm.groovy index ab07269..627bac9 100644 --- a/src/main/groovy/com/github/jrubygradle/storm/JRubyStorm.groovy +++ b/src/main/groovy/com/github/jrubygradle/storm/JRubyStorm.groovy @@ -3,12 +3,13 @@ package com.github.jrubygradle.storm import com.github.jrubygradle.JRubyPlugin import org.gradle.api.DefaultTask -import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.artifacts.Configuration import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional +import com.github.jrubygradle.storm.internal.JRubyStorm as JRubyStormInternal + /** * Implement the custom behaviors needed to build a JRubyStorm topology */ @@ -72,8 +73,8 @@ class JRubyStorm extends DefaultTask { super() configuration = project.configurations.maybeCreate(DEFAULT_CONFIGURATION_NAME) this.group JRubyPlugin.TASK_GROUP_NAME - this.runTask = this.createRunTask(this.project, this.name) - this.assembleTask = this.createAssembleTask(this.project, this.name) + this.runTask = JRubyStormInternal.createRunTask(this.project, this.name, this) + this.assembleTask = JRubyStormInternal.createAssembleTask(this.project, this.name) project.afterEvaluate { this.updateDependencies() } } @@ -109,27 +110,4 @@ class JRubyStorm extends DefaultTask { this.runTask?.group newGroup this.assembleTask?.group newGroup } - - private Task createRunTask(Project project, String baseName) { - JRubyStormLocal runTask = project.task("run${prepareNameForSuffix(baseName)}", - type: JRubyStormLocal) - runTask.parentTask = this - return runTask - } - - private Task createAssembleTask(Project project, String baseName) { - return project.task("assemble${prepareNameForSuffix(baseName)}") - } - - /** - * Prepare a name for suffixing to a task name, i.e. with a baseName of - * "foo" if I need a task to prepare foo, this will return 'Foo' so I can - * make a "prepareFoo" task and it cases properly - * - * This method has a special handling for the string 'jruby' where it will - * case it properly like "JRuby" instead of "Jruby" - */ - private String prepareNameForSuffix(String baseName) { - return baseName.replaceAll("(?i)jruby", 'JRuby').capitalize() - } } diff --git a/src/main/groovy/com/github/jrubygradle/storm/JRubyStormPlugin.groovy b/src/main/groovy/com/github/jrubygradle/storm/JRubyStormPlugin.groovy index f49e030..ca1ed19 100644 --- a/src/main/groovy/com/github/jrubygradle/storm/JRubyStormPlugin.groovy +++ b/src/main/groovy/com/github/jrubygradle/storm/JRubyStormPlugin.groovy @@ -15,9 +15,7 @@ class JRubyStormPlugin implements Plugin { project.extensions.create('storm', JRubyStormExtension) project.task('jrubyStorm', type: JRubyStorm) - project.afterEvaluate { - updateRepositories(project) - } + updateRepositories(project) } @PackageScope diff --git a/src/main/groovy/com/github/jrubygradle/storm/internal/JRubyStorm.groovy b/src/main/groovy/com/github/jrubygradle/storm/internal/JRubyStorm.groovy new file mode 100644 index 0000000..0f400b2 --- /dev/null +++ b/src/main/groovy/com/github/jrubygradle/storm/internal/JRubyStorm.groovy @@ -0,0 +1,31 @@ +package com.github.jrubygradle.storm.internal + +import com.github.jrubygradle.storm.JRubyStormLocal +import org.gradle.api.Project +import org.gradle.api.Task + + +class JRubyStorm { + static Task createAssembleTask(Project project, String baseName) { + return project.task("assemble${prepareNameForSuffix(baseName)}", type: JRubyStormJar) + } + + /** + * Prepare a name for suffixing to a task name, i.e. with a baseName of + * "foo" if I need a task to prepare foo, this will return 'Foo' so I can + * make a "prepareFoo" task and it cases properly + * + * This method has a special handling for the string 'jruby' where it will + * case it properly like "JRuby" instead of "Jruby" + */ + static String prepareNameForSuffix(String baseName) { + return baseName.replaceAll("(?i)jruby", 'JRuby').capitalize() + } + + static Task createRunTask(Project project, String baseName, Task parent) { + JRubyStormLocal runTask = project.task("run${prepareNameForSuffix(baseName)}", + type: JRubyStormLocal) + runTask.parentTask = parent + return runTask + } +} \ No newline at end of file diff --git a/src/main/groovy/com/github/jrubygradle/storm/internal/JRubyStormJar.groovy b/src/main/groovy/com/github/jrubygradle/storm/internal/JRubyStormJar.groovy new file mode 100644 index 0000000..a9d4980 --- /dev/null +++ b/src/main/groovy/com/github/jrubygradle/storm/internal/JRubyStormJar.groovy @@ -0,0 +1,8 @@ +package com.github.jrubygradle.storm.internal + +import com.github.jrubygradle.jar.JRubyJar +import groovy.transform.InheritConstructors + +@InheritConstructors +class JRubyStormJar extends JRubyJar { +} diff --git a/src/test/groovy/com/github/jrubygradle/storm/internal/JRubyStormJarSpec.groovy b/src/test/groovy/com/github/jrubygradle/storm/internal/JRubyStormJarSpec.groovy new file mode 100644 index 0000000..6217293 --- /dev/null +++ b/src/test/groovy/com/github/jrubygradle/storm/internal/JRubyStormJarSpec.groovy @@ -0,0 +1,17 @@ +package com.github.jrubygradle.storm.internal + +import com.github.jrubygradle.jar.JRubyJar +import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder +import spock.lang.* + +class JRubyStormJarSpec extends Specification { + def "when constructing the task"() { + given: + Project project = ProjectBuilder.builder().build() + project.apply plugin: 'com.github.jruby-gradle.storm' + + expect: "the task to be a JRubyJar" + project.task('spock', type: JRubyStormJar) instanceof JRubyJar + } +} diff --git a/src/test/groovy/com/github/jrubygradle/storm/internal/JRubyStormSpec.groovy b/src/test/groovy/com/github/jrubygradle/storm/internal/JRubyStormSpec.groovy new file mode 100644 index 0000000..fb493c5 --- /dev/null +++ b/src/test/groovy/com/github/jrubygradle/storm/internal/JRubyStormSpec.groovy @@ -0,0 +1,29 @@ +package com.github.jrubygradle.storm.internal + +import com.github.jrubygradle.storm.JRubyStormLocal +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.tasks.bundling.Jar +import org.gradle.testfixtures.ProjectBuilder +import spock.lang.* + +class JRubyStormSpec extends Specification { + Project project + + def setup() { + project = ProjectBuilder.builder().build() + project.apply plugin: 'com.github.jruby-gradle.storm' + } + def "createAssembleTask() should return a Jar type task"() { + expect: + JRubyStorm.createAssembleTask(project, 'spock') instanceof Jar + } + + def "createRunTask() should return a JRubyStormLocal type task"() { + given: + Task task = project.task('spockParent', type: com.github.jrubygradle.storm.JRubyStorm) + + expect: + JRubyStorm.createRunTask(project, 'spock', task) instanceof JRubyStormLocal + } +}