Skip to content

Commit ff6e864

Browse files
authored
Merge pull request #37 from cucumber/native-case-class-transformer
Add optional Jackson Default DataTable transformer
2 parents f8447ed + d53120a commit ff6e864

File tree

13 files changed

+219
-5
lines changed

13 files changed

+219
-5
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ See also the [CHANGELOG](https://github.com/cucumber/cucumber-jvm/blob/master/CH
1313
### Added
1414

1515
- [Doc] Users documentation on Scala DSL
16+
- [Scala DSL] Support for transformers ([#32](https://github.com/cucumber/cucumber-jvm-scala/issues/32) Gaël Jourdan-Weil)
17+
- See [Transformers](docs/transformers.md)
18+
- [Transformers] Add optional `JacksonDefaultDataTableEntryTransformer` ([#31](https://github.com/cucumber/cucumber-jvm-scala/issues/31) Gaël Jourdan-Weil)
19+
- See [here](docs/default_jackson_datatable_transformer.md)
1620

1721
### Changed
1822

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ The minor version might differ because Cucumber Scala may add Scala-related feat
3030
- [Step Definitions](docs/step_definitions.md)
3131
- [Hooks](docs/hooks.md)
3232
- [Transformers](docs/transformers.md)
33+
- [Default Jackson DataTable Transformer](docs/default_jackson_datatable_transformer.md)
3334
- [Example project](examples/README.md)
3435
- [Reference documentation for Java](https://docs.cucumber.io/docs/cucumber/)
3536
- [Changelog](CHANGELOG.md)
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Default Jackson DataTable Transformer
2+
3+
Cucumber Scala provides an optional Default DataTable Transformer that uses Jackson.
4+
5+
It can be used to automatically convert DataTables to case classes without defining custom converters.
6+
7+
## Add Jackson dependency
8+
9+
To use this optional transformer, you need to have Jackson Scala in your dependencies.
10+
11+
```xml
12+
<dependency>
13+
<groupId>com.fasterxml.jackson.module</groupId>
14+
<artifactId>jackson-module-scala_2.13</artifactId>
15+
<version>2.10.3</version>
16+
<scope>test</scope>
17+
</dependency>
18+
```
19+
20+
Or:
21+
```sbt
22+
libraryDependencies += "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.10.3" % Test
23+
```
24+
25+
26+
The current version of Cucumber Scala has been tested against Jackson Module Scala **version 2.10.3**.
27+
28+
## Add the transformer
29+
30+
The transformer has to be added to your glue code by extending the `JacksonDefaultDataTableEntryTransformer` trait.
31+
32+
For instance:
33+
```scala
34+
class MySteps extends ScalaDsl with EN with JacksonDefaultDataTableEntryTransformer {
35+
// Your usual glue code
36+
}
37+
```
38+
39+
### Empty string replacement
40+
41+
The default empty string replacement used by the default transformer is `[empty]`.
42+
43+
You can override it if you need to:
44+
```scala
45+
override def emptyStringReplacement: String = "[blank]"
46+
```
47+
48+
## Example
49+
50+
Then, let the transformer do its work!
51+
52+
For instance, the following DataTable:
53+
```gherkin
54+
Given I have the following datatable
55+
| field1 | field2 | field3 |
56+
| 1.2 | true | abc |
57+
| 2.3 | false | def |
58+
| 3.4 | true | ghj |
59+
```
60+
61+
will be automatically converted to the following case class:
62+
```scala
63+
case class MyCaseClass(field1: Double, field2: Boolean, field3: String)
64+
65+
Given("I have the following datatable") { (data: java.util.List[MyCaseClass]) =>
66+
// Do something
67+
}
68+
```

docs/transformers.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,8 @@ Default transformers are used when there is no specific transformer.
265265

266266
They can be used with object mappers like Jackson to easily convert from well known strings to objects.
267267

268+
See also [Default Jackson DataTable Transformer](default_jackson_datatable_transformer.md).
269+
268270
### String
269271

270272
For instance, the following definition:
@@ -304,6 +306,8 @@ Given("A step with a datatable") { (dataTable: DataTable) =>
304306
}
305307
```
306308

309+
This is what to `DefaultJacksonDataTableTransformer` uses.
310+
307311
#### Cells
308312

309313
For instance the following definition:

pom.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,30 @@
5555
<artifactId>cucumber-core</artifactId>
5656
<version>${cucumber.version}</version>
5757
</dependency>
58+
<dependency>
59+
<groupId>com.fasterxml.jackson.core</groupId>
60+
<artifactId>jackson-databind</artifactId>
61+
<version>${jackson-databind.version}</version>
62+
<scope>provided</scope>
63+
</dependency>
64+
<dependency>
65+
<groupId>com.fasterxml.jackson.module</groupId>
66+
<artifactId>jackson-module-scala_2.11</artifactId>
67+
<version>${jackson-databind.version}</version>
68+
<scope>provided</scope>
69+
</dependency>
70+
<dependency>
71+
<groupId>com.fasterxml.jackson.module</groupId>
72+
<artifactId>jackson-module-scala_2.12</artifactId>
73+
<version>${jackson-databind.version}</version>
74+
<scope>provided</scope>
75+
</dependency>
76+
<dependency>
77+
<groupId>com.fasterxml.jackson.module</groupId>
78+
<artifactId>jackson-module-scala_2.13</artifactId>
79+
<version>${jackson-databind.version}</version>
80+
<scope>provided</scope>
81+
</dependency>
5882
<dependency>
5983
<groupId>io.cucumber</groupId>
6084
<artifactId>cucumber-junit</artifactId>

scala/pom.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
<groupId>io.cucumber</groupId>
3434
<artifactId>cucumber-core</artifactId>
3535
</dependency>
36+
<dependency>
37+
<groupId>com.fasterxml.jackson.core</groupId>
38+
<artifactId>jackson-databind</artifactId>
39+
<scope>provided</scope>
40+
</dependency>
3641
<dependency>
3742
<groupId>io.cucumber</groupId>
3843
<artifactId>cucumber-junit</artifactId>
@@ -43,11 +48,6 @@
4348
<artifactId>junit</artifactId>
4449
<scope>test</scope>
4550
</dependency>
46-
<dependency>
47-
<groupId>com.fasterxml.jackson.core</groupId>
48-
<artifactId>jackson-databind</artifactId>
49-
<scope>test</scope>
50-
</dependency>
5151
</dependencies>
5252

5353
<build>

scala/scala_2.11/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
<scope>provided</scope>
2020
</dependency>
2121

22+
<!-- Users have to provide it (for JacksonDefaultDataTableTransformer) -->
23+
<dependency>
24+
<groupId>com.fasterxml.jackson.module</groupId>
25+
<artifactId>jackson-module-scala_2.11</artifactId>
26+
<scope>provided</scope>
27+
</dependency>
28+
2229
<dependency>
2330
<groupId>org.scala-lang</groupId>
2431
<artifactId>scala-library</artifactId>

scala/scala_2.12/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
<scope>provided</scope>
2020
</dependency>
2121

22+
<!-- Users have to provide it (for JacksonDefaultDataTableTransformer) -->
23+
<dependency>
24+
<groupId>com.fasterxml.jackson.module</groupId>
25+
<artifactId>jackson-module-scala_2.12</artifactId>
26+
<scope>provided</scope>
27+
</dependency>
28+
2229
<dependency>
2330
<groupId>org.scala-lang</groupId>
2431
<artifactId>scala-library</artifactId>

scala/scala_2.13/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
<scope>provided</scope>
2020
</dependency>
2121

22+
<!-- Users have to provide it (for JacksonDefaultDataTableTransformer) -->
23+
<dependency>
24+
<groupId>com.fasterxml.jackson.module</groupId>
25+
<artifactId>jackson-module-scala_2.13</artifactId>
26+
<scope>provided</scope>
27+
</dependency>
28+
2229
<dependency>
2330
<groupId>org.scala-lang</groupId>
2431
<artifactId>scala-library</artifactId>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package io.cucumber.scala
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper
4+
import com.fasterxml.jackson.module.scala.DefaultScalaModule
5+
6+
/**
7+
* <p>This trait register a `DefaultDataTableEntryTransformer` using Jackson `ObjectMapper`.</p>
8+
*
9+
* <p>The `[empty]` string is used as default empty string replacement. You can override it if you need to.</p>
10+
*
11+
* <p>Note: Jackson is not included with Cucumber Scala, you have to add the dependency:
12+
* `com.fasterxml.jackson.module:jackson-module-scala_2.xx`
13+
* to your project if you want to use this trait.</p>
14+
*/
15+
trait JacksonDefaultDataTableEntryTransformer extends ScalaDsl {
16+
17+
/**
18+
* Define the string to be used as replacement for empty.
19+
* Default is `[empty]`.
20+
*/
21+
def emptyStringReplacement: String = "[empty]"
22+
23+
/**
24+
* Create the Jackson ObjectMapper to be used.
25+
* Default is a simple ObjectMapper with DefaultScalaModule registered.
26+
*/
27+
def createObjectMapper(): ObjectMapper = {
28+
val objectMapper = new ObjectMapper()
29+
objectMapper.registerModule(DefaultScalaModule)
30+
}
31+
32+
private lazy val objectMapper: ObjectMapper = createObjectMapper()
33+
34+
DefaultDataTableEntryTransformer(emptyStringReplacement) { (fromValue: Map[String, String], toValueType: java.lang.reflect.Type) =>
35+
objectMapper.convertValue[AnyRef](fromValue, objectMapper.constructType(toValueType))
36+
}
37+
38+
}

0 commit comments

Comments
 (0)