Skip to content

Commit

Permalink
Update examples to use Transform
Browse files Browse the repository at this point in the history
  • Loading branch information
aslakhellesoy committed Jul 6, 2012
1 parent b5c0164 commit 71b300a
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 47 deletions.
2 changes: 1 addition & 1 deletion History.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@

## [1.0.0.RC15](https://github.com/cucumber/cucumber-jvm/compare/v1.0.0.RC14...v1.0.0.RC15)

* [Java] You must use `cucumber.runtime.xstream` instead of `cucumber.runtime.xstream` for custom converters.
* [Java] You must use `cucumber.runtime.xstream` instead of `com.thoughtworks.xstream` for custom converters.
* [Core] XStream and Diffutils are now packaged inside the cucumber-core jar under new package names. ([#179](https://github.com/cucumber/cucumber-jvm/issues/179) Aslak Hellesøy)
* [Core] Fail if no features are found ([#163](https://github.com/cucumber/cucumber-jvm/issues/163) Aslak Hellesøy)
* [Core] Fail if duplicate features are detected ([#165](https://github.com/cucumber/cucumber-jvm/issues/165) Aslak Hellesøy)
Expand Down
8 changes: 0 additions & 8 deletions core/src/main/java/cucumber/api/Transform.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target({ElementType.PARAMETER})
@java.lang.annotation.Documented
/**
* Step definition parameters can be annotated with this annotation to give full
* control over how a step argument gets converted to an object. Although the
* annotation value can be a {@link SingleValueConverter} it is recommended to
* use a {@link Transformer} subclass instead.
*
* @see Transformer
*/
public @interface Transform {
Class<? extends SingleValueConverter> value();
}
44 changes: 32 additions & 12 deletions core/src/main/java/cucumber/api/Transformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,36 @@
import java.lang.reflect.Type;

/**
* <p>
* Allows transformation of a step definition argument to a custom type, giving you full control
* over how that type is instantiated. Consider the following Gherkin step:
* <p/>
* over how that type is instantiated.
* </p>
* <p>
* Consider the following Gherkin step:
* </p>
* <pre>Given I did my laundry 3 days ago</pre>
* <p/>
* Now, let's assume we want Cucumber to transform the substring "3 days ago" into an instance of our custom
* <p>
* Let's assume we want Cucumber to transform the substring "3 days ago" into an instance of our custom
* <code>HumanTime</code> class:
* <p/>
* </p>
* <pre>
* &#064;Given("I did my laundry (.*)")
* public void iDidMyLaundry(HumanTime t) {
* }
* </pre>
* <p/>
* <p>
* If the <code>HumanTime</code> class has a constructor with a single <code>String</code> argument, then
* no explicit transformation is needed. If that's not the case you can annotate the class with your own converter:
* <p/>
* Cucumber will instantiate it without any further ado. However, if the class you want to convert to
* does <em>not</em> have a <code>String</code> constructor you can annotate your parameter:
* </p>
* <pre>
* &#064;XStreamConverter(HumanTimeConverter.class)
* public class HumanTime {
* &#064;Given("I did my laundry (.*)")
* public void iDidMyLaundry(&#064;Transform(HumanTimeConverter.class) HumanTime t) {
* }
* </pre>
* <p>
* And then a <code>HumanTimeConverter</code> class:
* <p/>
* </p>
* <pre>{@code
* public static class HumanTimeConverter extends Transformer<HumanTime> {
* &#064;Override
Expand All @@ -39,8 +45,22 @@
* }
* }
* }</pre>
* <p>
* An alternative to annotating parameters with {@link Transform} is to annotate your class with
* {@link cucumber.runtime.xstream.annotations.XStreamConverter}:
* </p>
* <pre>
* &#064;XStreamConverter(HumanTimeConverter.class)
* public class HumanTime {
* }
* </pre>
* <p>
* This will also enable a {@link cucumber.table.DataTable} to be transformed to
* a <code>List&lt;YourClass;&gt;</code>
* </p>
*
* @param <T>
* @param <T> the type to be instantiated
* @see Transform
*/
public abstract class Transformer<T> implements SingleValueConverter {
private final Type type;
Expand Down
5 changes: 5 additions & 0 deletions examples/groovy-calculator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
</properties>

<dependencies>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-deps</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-groovy</artifactId>
Expand Down
5 changes: 5 additions & 0 deletions examples/java-calculator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
<name>Examples: Java Calculator</name>

<dependencies>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-deps</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
Expand Down
8 changes: 6 additions & 2 deletions examples/java-helloworld/build.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<project name="java-helloworld" basedir="." default="runcukes">
<property name="repo" value="https://oss.sonatype.org/content/repositories/releases"/>
<property name="cucumber-jvm.version" value="1.0.10"/>
<property name="cucumber-jvm.version" value="1.0.11"/>
<property name="cucumber-html.version" value="0.2.1"/>
<property name="gherkin.version" value="2.11.0"/>
<property name="gherkin.version" value="2.11.1"/>
<property name="jchronic.version" value="0.2.6"/>
<property name="junit.version" value="4.10"/>

<property name="jars" value="lib"/>

<target name="download">
Expand All @@ -18,6 +20,8 @@
dest="${jars}/cucumber-junit-${cucumber-jvm.version}.jar"/>
<get src="${repo}/info/cukes/gherkin/${gherkin.version}/gherkin-${gherkin.version}.jar"
dest="${jars}/gherkin-${gherkin.version}.jar"/>
<get src="${repo}/com/rubiconproject/oss/${jchronic.version}/jchronic-${jchronic.version}.jar"
dest="${jars}/jchronic-${jchronic.version}.jar"/>
<get src="${repo}/junit/junit/${junit.version}/junit-${junit.version}.jar"
dest="${jars}/junit-${junit.version}.jar"/>
</target>
Expand Down
10 changes: 8 additions & 2 deletions examples/java-helloworld/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,19 @@
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>1.0.10</version>
<version>1.0.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>1.0.10</version>
<version>1.0.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.rubiconproject.oss</groupId>
<artifactId>jchronic</artifactId>
<version>0.2.6</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,41 @@
package cucumber.examples.java.helloworld;

import com.mdimension.jchronic.Chronic;
import com.mdimension.jchronic.Options;
import com.mdimension.jchronic.utils.Span;
import cucumber.annotation.en.Given;
import cucumber.runtime.xstream.converters.Converter;
import cucumber.runtime.xstream.converters.MarshallingContext;
import cucumber.runtime.xstream.converters.UnmarshallingContext;
import cucumber.runtime.xstream.io.HierarchicalStreamReader;
import cucumber.runtime.xstream.io.HierarchicalStreamWriter;
import cucumber.annotation.en.Then;
import cucumber.api.Transform;
import cucumber.api.Transformer;

import java.util.Calendar;

import static org.junit.Assert.assertEquals;

public class TimeStepdefs {
@Given("^I did laundry (.*) ago$")
public void I_did_laundry_time_ago(HumanTime time) throws Throwable {
}
private static Options options = new Options();
private Calendar laundryDate;

@cucumber.runtime.xstream.annotations.XStreamConverter(HumanTimeConverter.class)
public static class HumanTime {
@Given("^today is \"([^\"]*)\"$")
public void today_is(Calendar today) throws Throwable {
options.setNow(today);
}

public static class HumanTimeConverter implements Converter {
@Override
public boolean canConvert(Class aClass) {
return aClass.equals(HumanTime.class);
}

@Override
public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
@Given("^I did laundry (.*)")
public void I_did_laundry_time_ago(@Transform(ChronicConverter.class) Calendar laundryDate) throws Throwable {
this.laundryDate = laundryDate;
}

}
@Then("^my laundry day must have been \"([^\"]*)\"$")
public void my_laundry_day_must_have_been(Calendar day) throws Throwable {
assertEquals(day, laundryDate);
}

public static class ChronicConverter extends Transformer<Calendar> {
@Override
public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
return null;
public Calendar transform(String value) {
Span span = Chronic.parse(value, options);
return span.getEndCalendar();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ Feature: Hello World
"""

Scenario: Transformation
Given I did laundry 2 days ago
Given today is "Dec 6, 2012"
And I did laundry 2 days ago
Then my laundry day must have been "Dec 4, 2012"
5 changes: 5 additions & 0 deletions examples/java-webbit-websockets-selenium/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
<artifactId>webbit</artifactId>
</dependency>

<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-deps</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-picocontainer</artifactId>
Expand Down
5 changes: 5 additions & 0 deletions examples/scala-calculator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
<name>Examples: Scala Calculator</name>

<dependencies>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-deps</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-scala</artifactId>
Expand Down

0 comments on commit 71b300a

Please sign in to comment.