Skip to content

Commit

Permalink
Fix JGiven Plugin to be a cacheable task
Browse files Browse the repository at this point in the history
Signed-off-by: javier.salinas <javier.salinas@zopa.com>
  • Loading branch information
jsalinaspolo committed Jan 27, 2020
1 parent b8409a9 commit 2a2f4e5
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 35 deletions.
4 changes: 3 additions & 1 deletion jgiven-gradle-plugin/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id "java-gradle-plugin"
id "com.gradle.plugin-publish" version "0.10.1"
id "groovy"
}

dependencies {
Expand All @@ -9,8 +10,9 @@ dependencies {
implementation "com.google.guava:guava:$guavaVersion"
implementation "com.google.code.gson:gson:$gsonVersion"

testImplementation gradleTestKit()
testImplementation project(':jgiven-junit')
testImplementation 'org.spockframework:spock-core:1.3-groovy-2.5'

}

gradlePlugin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.internal.ConventionMapping;
import org.gradle.api.internal.IConventionAware;
import org.gradle.api.plugins.ReportingBasePlugin;
Expand All @@ -18,19 +19,19 @@

public class JGivenPlugin implements Plugin<Project> {
@Override
public void apply( final Project project ) {
public void apply( final Project project ){
project.getPluginManager().apply( ReportingBasePlugin.class );

addTaskExtension( project );
addDefaultReports( project );
configureJGivenReportDefaults( project );
}

private void addTaskExtension( Project project ) {
private void addTaskExtension( Project project ){
project.getTasks().withType( Test.class, this::applyTo );
}

private void applyTo( Test test ) {
private void applyTo( Test test ){
final String testName = test.getName();
final JGivenTaskExtension extension = test.getExtensions().create( "jgiven", JGivenTaskExtension.class );
final Project project = test.getProject();
Expand All @@ -42,45 +43,42 @@ private void applyTo( Test test ) {
test.getOutputs().dir( resultsDir ).withPropertyName( "jgiven.resultsDir" );
}

test.prependParallelSafeAction( task ->
( (Test) task ).systemProperty( Config.JGIVEN_REPORT_DIR, extension.getResultsDir().getAbsolutePath() ) );
// Java lambda classes are created at runtime with a non-deterministic classname.
// Therefore, the class name does not identify the implementation of the lambda and changes between different Gradle runs.
// https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:how_does_it_work
test.prependParallelSafeAction( new Action<Task>() {
@Override
public void execute( Task task ){
((Test) task).systemProperty( Config.JGIVEN_REPORT_DIR, extension.getResultsDir().getAbsolutePath() );
}
} );
}

private void configureJGivenReportDefaults( Project project ) {
project.getTasks().withType( JGivenReportTask.class,
reportTask -> reportTask.getReports().all( (Action<Report>) report -> {
ConventionMapping mapping = ( (IConventionAware) report ).getConventionMapping();
mapping.map( "enabled", new Callable<Boolean>() {
@Override
public Boolean call() {
return report.getName().equals( JGivenHtmlReportImpl.NAME );
}
} );
} ) );
private void configureJGivenReportDefaults( Project project ){
project.getTasks().withType( JGivenReportTask.class, reportTask -> reportTask.getReports().all( (Action<Report>) report -> {
ConventionMapping mapping = ( (IConventionAware) report ).getConventionMapping();
mapping.map( "enabled", (Callable<Boolean>) () -> report.getName().equals( JGivenHtmlReportImpl.NAME ) );
} ) );
}

private void addDefaultReports( final Project project ) {
private void addDefaultReports( final Project project ){
final ReportingExtension reportingExtension = project.getExtensions().findByType( ReportingExtension.class );
project.getTasks().withType( Test.class,
test -> {
JGivenReportTask reportTask = project.getTasks()
.create( "jgiven" + WordUtil.capitalize( test.getName() ) + "Report", JGivenReportTask.class );
configureDefaultReportTask( test, reportTask, reportingExtension );
} );
project.getTasks().withType( Test.class, test -> {
final JGivenReportTask reportTask = project.getTasks()
.create( "jgiven" + WordUtil.capitalize( test.getName() ) + "Report", JGivenReportTask.class );
configureDefaultReportTask( test, reportTask, reportingExtension );
} );
}

private void configureDefaultReportTask( final Test test, JGivenReportTask reportTask,
final ReportingExtension reportingExtension ) {
final ReportingExtension reportingExtension ){
ConventionMapping mapping = ( (IConventionAware) reportTask ).getConventionMapping();
mapping.map( "results",
(Callable<File>) () -> test.getExtensions().getByType( JGivenTaskExtension.class ).getResultsDir() );
mapping.getConventionValue( reportTask.getReports(), "reports", false ).all( new Action<Report>() {
@Override
public void execute( final Report report ) {
ConventionMapping reportMapping = ( (IConventionAware) report ).getConventionMapping();
reportMapping.map( "destination",
(Callable<File>) () -> reportingExtension.file( "jgiven" + "/" + test.getName() + "/" + report.getName() ) );
}
} );
mapping.map( "results", (Callable<File>) () -> test.getExtensions().getByType( JGivenTaskExtension.class ).getResultsDir() );
mapping.getConventionValue( reportTask.getReports(), "reports", false )
.all( (Action<Report>) report -> {
ConventionMapping reportMapping = ( (IConventionAware) report ).getConventionMapping();
reportMapping.map( "destination",
(Callable<File>) () -> reportingExtension.file( "jgiven" + "/" + test.getName() + "/" + report.getName() ) );
} );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.tngtech.jgiven.gradle


import com.google.common.io.Resources
import org.gradle.testkit.runner.GradleRunner
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import spock.lang.Specification

import static org.gradle.testkit.runner.TaskOutcome.FROM_CACHE
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS

class JGivenPluginShould extends Specification {

@Rule
TemporaryFolder testProjectDir = new TemporaryFolder()
File buildFile

def setup() {
buildFile = testProjectDir.newFile('build.gradle')
}

def "test is cacheable"() {
given:
buildFile << """
plugins {
id 'java'
id 'com.tngtech.jgiven.gradle-plugin'
}
repositories { jcenter() }
dependencies {
testImplementation 'com.tngtech.jgiven:jgiven-junit:1.0.0-RC4'
testImplementation 'junit:junit:4.12'
}
"""

testProjectDir.newFolder("src", "test", "java")
File scenario = testProjectDir.newFile("src/test/java/SimpleScenario.java")
scenario << Resources.toByteArray(Resources.getResource("SimpleScenario.java"))

when:
def result = GradleRunner.create()
.withProjectDir(testProjectDir.getRoot())
.withArguments("--build-cache", "test", "jgivenTestReport")
.withPluginClasspath()
.build()

then:
result.task(":test").outcome == SUCCESS
result.task(":jgivenTestReport").outcome == SUCCESS

when:
new File(testProjectDir.root, 'build').deleteDir()
result = GradleRunner.create()
.withProjectDir(testProjectDir.getRoot())
.withArguments("--build-cache", "test", "jgivenTestReport")
.withPluginClasspath()
.build()


then:
result.task(":test").outcome == FROM_CACHE
result.task(":jgivenTestReport").outcome == FROM_CACHE

}
}

0 comments on commit 2a2f4e5

Please sign in to comment.