-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for spock2 #784
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,4 +11,4 @@ class Given extends Stage<Given> { | |
def some_state_$(String param) { | ||
self() | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,4 +8,4 @@ class Then extends Stage<Then> { | |
assert true | ||
self() | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,4 +7,4 @@ class When extends Stage<When> { | |
When some_action() { | ||
self() | ||
} | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for polishing :) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
plugins { | ||
id 'java-library' | ||
} | ||
|
||
apply plugin: 'groovy' | ||
|
||
description = "Module for writing JGiven tests with Spock 2" | ||
|
||
ext { | ||
spock2_version = '2.0-groovy-3.0' | ||
groovy_version = '3.0.9' | ||
} | ||
|
||
dependencies { | ||
api project(':jgiven-junit') | ||
|
||
implementation "org.codehaus.groovy:groovy:$groovy_version" | ||
implementation "org.spockframework:spock-core:$spock2_version" | ||
implementation "org.spockframework:spock-junit4:$spock2_version" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Question: wouldn't it make sense to try to align the spock2 package with JUnit 5 directly? If I recall correctly Spock2 is JUnit5 based and upgrading the published jgiven package later should be significantly harder. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Spock2 uses JUnit Platform used in JUnit5, but it does not use JUnit5. Therefore can not use the Junit5 Extensions. At the end, it is an implementation detail for the user of the library. The user will not see that internally we are using JUnit4 Rules, but we can migrate to native Spock at some point in the future. Using Spock2 allows users of the library to migrate to JDK17 |
||
|
||
testImplementation project(':jgiven-html5-report') | ||
} | ||
|
||
test { | ||
useJUnitPlatform() | ||
finalizedBy(jgivenHtml5Report) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package com.tngtech.jgiven.spock | ||
|
||
import com.google.common.reflect.TypeToken | ||
import com.tngtech.jgiven.annotation.DoNotIntercept | ||
import com.tngtech.jgiven.impl.Scenario | ||
import com.tngtech.jgiven.junit.JGivenClassRule | ||
import com.tngtech.jgiven.spock.junit.JGivenSpockMethodRule | ||
import net.bytebuddy.ByteBuddy | ||
import net.bytebuddy.description.annotation.AnnotationDescription | ||
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy | ||
import net.bytebuddy.implementation.SuperMethodCall | ||
import net.bytebuddy.matcher.ElementMatchers | ||
import org.junit.ClassRule | ||
import org.junit.Rule | ||
import spock.lang.Shared | ||
import spock.lang.Specification | ||
|
||
/** | ||
* ScenarioSpec to use JGiven with Spock2 Framework | ||
* | ||
* @since 1.2.0 | ||
*/ | ||
class ScenarioSpec<GIVEN, WHEN, THEN> extends Specification { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add javadoc and an |
||
@ClassRule @Shared JGivenClassRule writerRule = new JGivenClassRule() | ||
@Rule JGivenSpockMethodRule scenarioRule = new JGivenSpockMethodRule(createScenario()) | ||
|
||
GIVEN given() { | ||
getScenario().given() | ||
} | ||
|
||
WHEN when() { | ||
getScenario().when() | ||
} | ||
|
||
THEN then() { | ||
getScenario().then() | ||
} | ||
|
||
Scenario<GIVEN, WHEN, THEN> getScenario() { | ||
(Scenario<GIVEN, WHEN, THEN>) scenarioRule.getScenario() | ||
} | ||
|
||
Scenario<GIVEN, WHEN, THEN> createScenario() { | ||
Class<GIVEN> givenClass = addDoNotInterceptToMetaClass(new TypeToken<GIVEN>(getClass()) {}.getRawType()) | ||
Class<WHEN> whenClass = addDoNotInterceptToMetaClass(new TypeToken<WHEN>(getClass()) {}.getRawType()) | ||
Class<THEN> thenClass = addDoNotInterceptToMetaClass(new TypeToken<THEN>(getClass()) {}.getRawType()) | ||
|
||
new Scenario<GIVEN, WHEN, THEN>(givenClass, whenClass, thenClass) | ||
} | ||
|
||
private <T> Class<T> addDoNotInterceptToMetaClass(Class<T> clazz) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can understand why this exists, but do you happen to know, why it wasn't needed in the spock1 Package? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is related with Groovy 3 vs Groovy 2 |
||
AnnotationDescription doNotIntercept = AnnotationDescription.Builder.ofType(DoNotIntercept.class).build() | ||
def clazzA = clazz.metaClass.getTheClass() | ||
new ByteBuddy() | ||
.subclass(clazzA) | ||
.method(ElementMatchers.named("getMetaClass")) | ||
.intercept(SuperMethodCall.INSTANCE) | ||
.annotateMethod(doNotIntercept) | ||
.make() | ||
.load(clazzA.getClassLoader(), ClassLoadingStrategy.Default.INJECTION) | ||
.getLoaded() as Class<T> | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.tngtech.jgiven.spock.junit; | ||
|
||
import com.tngtech.jgiven.impl.ScenarioBase; | ||
import com.tngtech.jgiven.junit.JGivenMethodRule; | ||
import org.junit.runners.model.FrameworkMethod; | ||
import org.junit.runners.model.Statement; | ||
import spock.lang.Specification; | ||
|
||
/** | ||
* JUnit Rule to enable JGiven with Spock2 | ||
* | ||
* @since 1.2.0 | ||
*/ | ||
public class JGivenSpockMethodRule extends JGivenMethodRule { | ||
|
||
/** | ||
* @since 1.2.0 | ||
*/ | ||
public JGivenSpockMethodRule(ScenarioBase scenario) { | ||
super(scenario); | ||
} | ||
|
||
@Override | ||
protected void starting(Statement base, FrameworkMethod testMethod, Object target) { | ||
super.starting(base, testMethod, target); | ||
scenario.getScenarioModel().setDescription(methodNameFromSpec(target)); | ||
} | ||
|
||
private String methodNameFromSpec(Object target) { | ||
return ((Specification) target).getSpecificationContext().getCurrentIteration().getParent().getDisplayName(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.tngtech.jgiven.spock | ||
|
||
import com.tngtech.jgiven.annotation.ExtendedDescription | ||
import com.tngtech.jgiven.spock.stages.Given | ||
import com.tngtech.jgiven.spock.stages.Then | ||
import com.tngtech.jgiven.spock.stages.When | ||
|
||
class ShinySpockJGivenShould extends ScenarioSpec<Given, When, Then> { | ||
|
||
def "something should happen"() { | ||
expect: | ||
|
||
given().some_state() | ||
when().some_action() | ||
then().some_outcome() | ||
|
||
assert scenario.scenarioModel.description == "something should happen" | ||
} | ||
|
||
def "be some able to use params"() { | ||
expect: | ||
|
||
given().some_state_$("param") | ||
when().some_action() | ||
then().some_outcome() | ||
|
||
assert scenario.scenarioModel.scenarioCases.first().getStep(0).words.join(" ") == "Given some state param" | ||
} | ||
|
||
@ExtendedDescription("more details") | ||
def "be able to have extended descriptions"() { | ||
expect: | ||
|
||
given().some_state() | ||
when().some_action() | ||
then().some_outcome() | ||
|
||
assert scenario.scenarioModel.extendedDescription == "more details" | ||
} | ||
|
||
def "be able to use tables #param"() { | ||
expect: | ||
given().some_state_$(param) | ||
when().some_action() | ||
then().some_outcome() | ||
|
||
assert scenario.scenarioModel.getDescription() == "be able to use tables #param" | ||
|
||
where: | ||
param | _ | ||
"param" | _ | ||
"word param" | _ | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.tngtech.jgiven.spock.stages | ||
|
||
import com.tngtech.jgiven.Stage | ||
import com.tngtech.jgiven.annotation.As | ||
|
||
class Given extends Stage<Given> { | ||
|
||
Given some_state() { | ||
self() | ||
} | ||
|
||
def some_state_$(String param) { | ||
self() | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.tngtech.jgiven.spock.stages | ||
|
||
import com.tngtech.jgiven.Stage | ||
|
||
class Then extends Stage<Then> { | ||
|
||
Then some_outcome() { | ||
assert true | ||
self() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.tngtech.jgiven.spock.stages | ||
|
||
import com.tngtech.jgiven.Stage | ||
|
||
class When extends Stage<When> { | ||
|
||
When some_action() { | ||
self() | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch :D