Skip to content

Commit 900b90a

Browse files
committed
Add optional Jackson Default DataTable transformer
1 parent a4a9b96 commit 900b90a

File tree

12 files changed

+215
-5
lines changed

12 files changed

+215
-5
lines changed

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+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Feature: As Cucumber Scala, I want to provide a basic DataTable transformer using Jackson
2+
3+
Scenario: Use the default transformer with a basic case class
4+
Given I have the following datatable
5+
| field1 | field2 | field3 |
6+
| 1.2 | true | abc |
7+
| 2.3 | false | def |
8+
| 3.4 | true | ghj |
9+
10+
Scenario: Use the default transformer with a basic case class and empty values
11+
Given I have the following datatable, with an empty value
12+
| field1 | field2 | field3 |
13+
| 1.2 | true | abc |
14+
| 2.3 | false | [blank] |
15+
| 3.4 | true | ghj |

0 commit comments

Comments
 (0)