Skip to content

Commit ce0a6b8

Browse files
authored
[Java] Allow parameter types access to test context (#1677)
# Summary By annotating methods parameter and data table types can be defined as part of the Glue. This enables them to access the test context and makes them eligible for dependency injection. Additionally the type registry is now created for each feature. This means the language of the feature will be used to convert numbers. ## Details ## Parameter and DataTable Type Introduces the `@ParameterType` and `@DataTableType` annotations. This allows parameter and datatable types to be mapped to objects which can only be created by services inside the test context. For example in this scenario ```gherkin Given the awesome catalog When a user places the awestruck eels in his basket Then you will be shocked at what happened next ``` We are now able to look up the "awestruck eels" in the "awesome" catalog. ```java private final Catalog catalog; @ParameterType(".*") public Product product(String name) { return catalog.findProductByName(name); } ``` ## Default Transformer It is now also possible to register default transformers using annotations. Default transformers allow you to specific a transformer that will be used when there is no transform defined. This can be combined with an object mapper like Jackson to quickly transform well known string representations to Java objects. * `@DefaultParameterTransformer` * `@DefaultDataTableEntryTransformer` * `@DefaultDataTableCellTransformer` ```java package com.example.app; import com.fasterxml.jackson.databind.ObjectMapper; import io.cucumber.java.DefaultDataTableCellTransformer; import io.cucumber.java.DefaultDataTableEntryTransformer; import io.cucumber.java.DefaultParameterTransformer; import java.lang.reflect.Type; public class DataTableSteps { private final ObjectMapper objectMapper = new ObjectMapper(); @DefaultParameterTransformer @DefaultDataTableEntryTransformer @DefaultDataTableCellTransformer public Object defaultTransformer(Object fromValue, Type toValueType) { return objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType)); } } ``` ## Localization Some languages uses comma's rather then points to separate decimals. Previously to parse these properly you'd have to use `TypeRegistryConfigurer.locale` to set this globally. When not explicitly provided Cucumber will now take the language from the feature file. This makes the following work without additional configuration: ```gherkin # language: fr Fonctionnalité: Concombres fractionnaires Scénario: dans la ventre Étant donné j'ai 5,5 concombres fractionnaires ``` ```java @Étantdonné("j'ai {bigdecimal} concombres fractionnaires") public void jAiConcombresFractionnaires(BigDecimal arg0) { assertThat(arg0, is(new BigDecimal("5.5"))); } ``` # Motivation & Context Fixes #851. Fixes #1458.
2 parents 0e41a1a + 3e6da03 commit ce0a6b8

File tree

110 files changed

+3198
-864
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+3198
-864
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CO
6363
- Use `io.cucumber.core.cli.Main` instead
6464
* [Core] Deprecate `cucumber.api.Scenario`
6565
- Use `io.cucumber.core.api.Scenario` instead
66+
* [Java] Deprecate `cucumber.api.java.*`
67+
- Use `io.cucumber.java.*` instead
68+
* [Java] Deprecate `cucumber.api.java8.*`
69+
- Use `io.cucumber.java8.*` instead
6670
* [JUnit] Deprecate `cucumber.api.junit.Cucumber`
6771
- Use `io.cucumber.junit.Cucumber` instead.
6872
* [TestNG] Deprecate `cucumber.api.testng.TestNGCucumberRunner`

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
[![Coverage Status](https://coveralls.io/repos/github/cucumber/cucumber-jvm/badge.svg?branch=master)](https://coveralls.io/github/cucumber/cucumber-jvm?branch=master)
99

1010
Cucumber-JVM is a pure Java implementation of Cucumber.
11-
You can [run](https://docs.cucumber.io/cucumber/api/#running-cucumber) it with
11+
You can [run](https://cucumber.io/docs/cucumber/api/#running-cucumber) it with
1212
the tool of your choice.
1313

1414
Cucumber-JVM also integrates with all the popular
15-
[Dependency Injection containers](https://docs.cucumber.io/installation/java/#dependency-injection).
15+
[Dependency Injection containers](https://cucumber.io/docs/installation/java/#dependency-injection).
1616

1717
## Getting started
18-
* [Installation](https://docs.cucumber.io/installation/java/)
18+
* [Installation](https://cucumber.io/docs/installation/java/)
1919
* [Documentation](https://cucumber.io/docs)
2020
* [Hello World project](https://github.com/cucumber/cucumber-java-skeleton)
2121

cdi2/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
22
<modelVersion>4.0.0</modelVersion>
33
<properties>
4+
<project.Automatic-Module-Name>io.cucumber.cdi2</project.Automatic-Module-Name>
45
<openwebbeans.version>2.0.10</openwebbeans.version>
56
</properties>
67

core/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<name>Cucumber-JVM: Core</name>
1313

1414
<properties>
15+
<project.Automatic-Module-Name>io.cucumber.core</project.Automatic-Module-Name>
1516
<!-- version 2.4.0 does not work on Java 7 -->
1617
<jsoup.version>1.12.1</jsoup.version>
1718
<xmlunit.version>1.6</xmlunit.version>

core/src/main/java/io/cucumber/core/api/TypeRegistryConfigurer.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
@API(status = API.Status.STABLE)
1111
public interface TypeRegistryConfigurer {
1212
/**
13-
* @return The locale to use.
13+
* @return The locale to use, or null when language from feature file should be used.
1414
*/
15-
Locale locale();
15+
default Locale locale() {
16+
return null;
17+
}
1618

1719
/**
1820
* Configures the type registry.
21+
*
1922
* @param typeRegistry The new type registry.
2023
*/
2124
void configureTypeRegistry(TypeRegistry typeRegistry);

core/src/main/java/io/cucumber/core/backend/Backend.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,18 @@
99
@API(status = API.Status.STABLE)
1010
public interface Backend {
1111
/**
12-
* Invoked once before all features. This is where stepdefs and hooks should be loaded.
13-
*
14-
* @param glue Glue that provides the stepdefs to be executed.
12+
* Invoked once before all features. This is where steps and hooks should be loaded.
13+
*
14+
* @param glue Glue that provides the steps to be executed.
1515
* @param gluePaths The locations for the glue to be loaded.
1616
*/
1717
void loadGlue(Glue glue, List<URI> gluePaths);
1818

1919
/**
2020
* Invoked before a new scenario starts. Implementations should do any necessary
21-
* setup of new, isolated state here.
21+
* setup of new, isolated state here. Additional scenario scoped step definitions
22+
* can be loaded here. These step definitions should implement
23+
* {@link io.cucumber.core.runner.ScenarioScoped}
2224
*/
2325
void buildWorld();
2426

core/src/main/java/io/cucumber/core/backend/Container.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public interface Container {
88
* Collects glue classes in the classpath. Called once on init.
99
*
1010
* @param glueClass Glue class containing cucumber.api annotations (Before, Given, When, ...)
11-
* @return true if stepdefs and hooks in this class should be used, false if they should be ignored.
11+
* @return true if steps and hook definitions in this class should be used, false if they should be ignored.
1212
*/
1313
boolean addClass(Class<?> glueClass);
1414
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.cucumber.core.backend;
2+
3+
import io.cucumber.datatable.DataTableType;
4+
import org.apiguardian.api.API;
5+
6+
@API(status = API.Status.STABLE)
7+
public interface DataTableTypeDefinition {
8+
9+
DataTableType dataTableType();
10+
11+
/**
12+
* The source line where the data table type is defined.
13+
* Example: com/example/app/Cucumber.test():42
14+
*
15+
* @param detail true if extra detailed location information should be included.
16+
* @return The source line of the step definition.
17+
*/
18+
String getLocation(boolean detail);
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.cucumber.core.backend;
2+
3+
import io.cucumber.datatable.TableCellByTypeTransformer;
4+
import org.apiguardian.api.API;
5+
6+
@API(status = API.Status.STABLE)
7+
public interface DefaultDataTableCellTransformerDefinition {
8+
9+
TableCellByTypeTransformer tableCellByTypeTransformer();
10+
11+
/**
12+
* The source line where the default data table cell is defined.
13+
* Example: com/example/app/Cucumber.test():42
14+
*
15+
* @param detail true if extra detailed location information should be included.
16+
* @return The source line of the step definition.
17+
*/
18+
String getLocation(boolean detail);
19+
20+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.cucumber.core.backend;
2+
3+
import io.cucumber.datatable.TableEntryByTypeTransformer;
4+
import org.apiguardian.api.API;
5+
6+
@API(status = API.Status.STABLE)
7+
public interface DefaultDataTableEntryTransformerDefinition {
8+
9+
TableEntryByTypeTransformer tableEntryByTypeTransformer();
10+
11+
/**
12+
* The source line where the default table entry transformer is defined.
13+
* Example: com/example/app/Cucumber.test():42
14+
*
15+
* @param detail true if extra detailed location information should be included.
16+
* @return The source line of the step definition.
17+
*/
18+
String getLocation(boolean detail);
19+
}

0 commit comments

Comments
 (0)