diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy index 1bddae8b6d..1ac3521e4b 100644 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy @@ -1,7 +1,13 @@ package io.codearte.accurest.plugin -import nebula.test.IntegrationSpec -import nebula.test.functional.GradleRunner +import org.apache.commons.io.FileUtils +import org.gradle.testkit.runner.BuildResult +import org.gradle.testkit.runner.BuildTask +import org.gradle.testkit.runner.GradleRunner +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Specification import java.nio.file.Files import java.nio.file.Path @@ -9,19 +15,44 @@ import java.nio.file.Path import static java.nio.charset.StandardCharsets.UTF_8 /** - * @author Olga Maciaszek-Sharma + * @author Olga Maciaszek-Sharma + * @author Denis Stepanov * @since 23.02.16 */ -class AccurestIntegrationSpec extends IntegrationSpec { +class AccurestIntegrationSpec extends Specification { - public static final String SPOCK = "targetFramework = 'Spock'" - public static final String JUNIT = "targetFramework = 'JUnit'" - public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'" - public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'" + @Rule + TemporaryFolder testProjectDir = new TemporaryFolder() - void setup() { - classpathFilter = GradleRunner.CLASSPATH_ALL //workaround for removing dependant modules by default filter - } + public static final String SPOCK = "targetFramework = 'Spock'" + public static final String JUNIT = "targetFramework = 'JUnit'" + public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'" + public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'" + + protected void setupForProject(String projectRoot) { + copyResourcesToRoot(projectRoot) + + def pluginClasspathResource = getClass().classLoader.findResource("plugin-classpath.txt") + if (pluginClasspathResource == null) { + throw new IllegalStateException("Did not find 'plugin-classpath.txt'") + } + + String pluginClasspath = pluginClasspathResource.readLines() + .collect { it.replace('\\', '\\\\') } // escape backslashes in Windows paths + .collect { "'$it'" } + .join(", ") + + buildFile << """ + buildscript { + dependencies { + classpath files($pluginClasspath) + } + } + """ + + // Extending buildscript is required when 'apply' is used. + // 'GradleRunner#withPluginClasspath' can be used when plugin is added using 'plugins { id...' + } protected void switchToJunitTestFramework() { switchToJunitTestFramework(MVC_SPEC, MVC_TEST) @@ -34,4 +65,57 @@ class AccurestIntegrationSpec extends IntegrationSpec { Files.write(path, content.getBytes(UTF_8)) } + protected void runTasksSuccessfully(String... tasks) { + BuildResult result = run(tasks) + result.tasks.each { + assert it.outcome == TaskOutcome.SUCCESS || it.outcome == TaskOutcome.UP_TO_DATE + } + } + + protected BuildResult validateTasksOutcome(BuildResult result, TaskOutcome expectedOutcome, String... tasks) { + tasks.each { + BuildTask task = result.task(":" + it) + assert task + assert task.outcome == expectedOutcome + } + return result + } + + protected BuildResult run(String... tasks) { + return GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments(tasks) + .build() + } + + protected void copyResourcesToRoot(String srcDir) { + copyResources(srcDir, testProjectDir.root) + } + + protected void copyResources(String srcDir, File destinationFile) { + ClassLoader classLoader = getClass().getClassLoader() + URL resource = classLoader.getResource(srcDir) + if (resource == null) { + throw new RuntimeException("Could not find classpath resource: $srcDir") + } + File resourceFile = new File(resource.toURI()) + if (resourceFile.file) { + FileUtils.copyFile(resourceFile, destinationFile) + } else { + FileUtils.copyDirectory(resourceFile, destinationFile) + } + } + + protected File file(String path) { + return new File(testProjectDir.getRoot(), path) + } + + protected boolean fileExists(String path) { + return file(path).exists() + } + + protected File getBuildFile() { + return new File('build.gradle', testProjectDir.root) + } + } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy index c9278e5f0b..2378342932 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy @@ -1,8 +1,11 @@ package io.codearte.accurest.plugin - import io.codearte.accurest.util.AssertionUtil +import org.gradle.testkit.runner.BuildResult import spock.lang.Stepwise +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS +import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE + @Stepwise class BasicFunctionalSpec extends AccurestIntegrationSpec { @@ -12,18 +15,16 @@ class BasicFunctionalSpec extends AccurestIntegrationSpec { private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/TEST-accurest.twitter_places_analyzer.PairIdSpec.xml" void setup() { - copyResources("functionalTest/bootSimple", "") - runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it + setupForProject("functionalTest/bootSimple") + runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } - def "should pass basic flow"() { - given: - assert fileExists('build.gradle') + def "should pass basic flxow"() { when: - def result = runTasksSuccessfully('check') + BuildResult result = run("check") then: - result.wasExecuted(":generateWireMockClientStubs") - result.wasExecuted(":generateAccurest") + result.task(":generateWireMockClientStubs").outcome == SUCCESS + result.task(":generateAccurest").outcome == SUCCESS and: "tests generated" fileExists(GENERATED_TEST) @@ -37,7 +38,7 @@ class BasicFunctionalSpec extends AccurestIntegrationSpec { def "should generate valid client json stubs for simple input"() { when: - runTasksSuccessfully('generateWireMockClientStubs') + run('generateWireMockClientStubs') then: def generatedClientJsonStub = file(GENERATED_CLIENT_JSON_STUB).text AssertionUtil.assertThatJsonsAreEqual(""" @@ -73,25 +74,24 @@ class BasicFunctionalSpec extends AccurestIntegrationSpec { fileExists(GENERATED_TEST) when: "running generation without change inputs" - def secondExecutionResult = runTasksSuccessfully('generateWireMockClientStubs', 'generateAccurest') + def secondExecutionResult = run('generateWireMockClientStubs', 'generateAccurest') then: "tasks should be up-to-date" - secondExecutionResult.wasUpToDate(":generateWireMockClientStubs") - secondExecutionResult.wasUpToDate(":generateAccurest") + validateTasksOutcome(secondExecutionResult, UP_TO_DATE, 'generateWireMockClientStubs', 'generateAccurest') when: "inputs changed" def groovyDslFile = file(GROOVY_DSL_CONTRACT) groovyDslFile.text = groovyDslFile.text.replace("200", "599") and: "tasks run" - def thirdExecutionResult = runTasksSuccessfully('generateWireMockClientStubs', 'generateAccurest') + def thirdExecutionResult = run('generateWireMockClientStubs', 'generateAccurest') then: "tasks should be reexecuted" - thirdExecutionResult.wasExecuted(":generateWireMockClientStubs") - thirdExecutionResult.wasExecuted(":generateAccurest") + validateTasksOutcome(thirdExecutionResult, SUCCESS, 'generateWireMockClientStubs', 'generateAccurest') and: "changes visible in generate files" file(GENERATED_CLIENT_JSON_STUB).text.contains("599") file(GENERATED_TEST).text.contains("599") } + } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy index df468fdfa7..0d4004ae11 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy @@ -6,7 +6,7 @@ import spock.lang.Stepwise class MessagingProjectSpec extends AccurestIntegrationSpec { void setup() { - copyResources("functionalTest/messagingProject", "") + setupForProject("functionalTest/messagingProject") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy index d314e6c526..82ab2a488e 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy @@ -6,9 +6,8 @@ import spock.lang.Stepwise class SampleJerseyProjectSpec extends AccurestIntegrationSpec { void setup() { - copyResources("functionalTest/sampleJerseyProject", "") - runTasksSuccessfully('clean') - //delete accidental output when previously importing SimpleBoot into Idea to tweak it + setupForProject("functionalTest/sampleJerseyProject") + runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } def "should pass basic flow for Spock"() { diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy index fefe2d9869..451230ad85 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy @@ -6,7 +6,7 @@ import spock.lang.Stepwise class SampleProjectSpec extends AccurestIntegrationSpec { void setup() { - copyResources("functionalTest/sampleProject", "") + setupForProject("functionalTest/sampleProject") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy index 3b300a3ad7..620514dc3a 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy @@ -6,7 +6,7 @@ import spock.lang.Stepwise class ScenarioProjectSpec extends AccurestIntegrationSpec { void setup() { - copyResources("functionalTest/scenarioProject", "") + setupForProject("functionalTest/scenarioProject") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } diff --git a/build.gradle b/build.gradle index a58ce57c62..1035550b83 100644 --- a/build.gradle +++ b/build.gradle @@ -130,9 +130,7 @@ project(':accurest-gradle-plugin') { compile project(':accurest-converters') compile gradleApi() - testCompile('com.netflix.nebula:nebula-test:4.0.0') { - exclude(group: 'org.spockframework') - } + testCompile gradleTestKit() testCompile project(':accurest-testing-utils') } @@ -147,13 +145,50 @@ project(':accurest-gradle-plugin') { } } - // Hack for reusing this in the plugin test + task createClasspathManifest { + def outputDir = file("$buildDir/$name") + + inputs.files sourceSets.main.runtimeClasspath + outputs.dir outputDir + + doLast { + outputDir.mkdirs() + file("$outputDir/plugin-classpath.txt").text = sourceSets.test.runtimeClasspath.join("\n") + // Switch to 'sourceSets.main' after 'test.dependsOn's are removed + } + } + test.dependsOn(':accurest-core:install') test.dependsOn(':accurest-messaging-root:accurest-messaging-core:install') test.dependsOn(':accurest-messaging-root:accurest-messaging-integration:install') + + funcTest.dependsOn(':accurest-core:install') + funcTest.dependsOn(':accurest-messaging-root:accurest-messaging-core:install') + funcTest.dependsOn(':accurest-messaging-root:accurest-messaging-integration:install') + + // Add the classpath file to the test runtime classpath + dependencies { + testRuntime files(createClasspathManifest) + } + uploadArchives.dependsOn { funcTest } } task wrapper(type: Wrapper) { gradleVersion = '2.12' } + + +// REMOVE AFTER https://issues.gradle.org/browse/GRADLE-3433 IS FIXED +buildscript { + repositories { + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "gradle.plugin.com.palantir.ideatestfix:gradle-idea-test-fix:0.1.0" + } +} + +apply plugin: "com.palantir.idea-test-fix" \ No newline at end of file