diff --git a/core/src/main/java/io/cucumber/core/api/TypeRegistryConfigurer.java b/core/src/main/java/io/cucumber/core/api/TypeRegistryConfigurer.java index 86a968e4e6..51dc4cc918 100644 --- a/core/src/main/java/io/cucumber/core/api/TypeRegistryConfigurer.java +++ b/core/src/main/java/io/cucumber/core/api/TypeRegistryConfigurer.java @@ -6,8 +6,12 @@ /** * The type registry configurer allows to configure a new type registry and the locale. + * @deprecated Please use annotation based configuration. + * See Annotation based example + * See Lambda based example */ @API(status = API.Status.STABLE) +@Deprecated public interface TypeRegistryConfigurer { /** * @return The locale to use, or null when language from feature file should be used. diff --git a/examples/java-calculator/src/test/java/io/cucumber/examples/java/ShoppingSteps.java b/examples/java-calculator/src/test/java/io/cucumber/examples/java/ShoppingSteps.java index be6ae05d05..7e0b7c7e54 100644 --- a/examples/java-calculator/src/test/java/io/cucumber/examples/java/ShoppingSteps.java +++ b/examples/java-calculator/src/test/java/io/cucumber/examples/java/ShoppingSteps.java @@ -1,16 +1,45 @@ package io.cucumber.examples.java; +import io.cucumber.java.DataTableType; +import io.cucumber.java.DocStringType; +import io.cucumber.java.ParameterType; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; +import java.math.BigDecimal; +import java.util.Currency; import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertEquals; public class ShoppingSteps { private RpnCalculator calc = new RpnCalculator(); + private List shoppingList; + private List shopStock; + private int groceriesPrice; + + @DataTableType + public Grocery defineGrocery(Map entry) { + return new Grocery(entry.get("name"), ShoppingSteps.Price.fromString(entry.get("price"))); + } + + @ParameterType(name = "amount", value = "\\d+\\.\\d+\\s[a-zA-Z]+") + public Amount defineAmount(String value) { + String [] arr = value.split("\\s"); + return new Amount(new BigDecimal(arr[0]), Currency.getInstance(arr[1])); + } + + @DocStringType(contentType = "shopping_list") + public List defineShoppingList(String docstring) { + return Stream.of(docstring.split("\\s")).map(Grocery::new).collect(Collectors.toList()); + } + @Given("the following groceries:") public void the_following_groceries(List groceries) { for (Grocery grocery : groceries) { @@ -19,9 +48,9 @@ public void the_following_groceries(List groceries) { } } - @When("I pay {}") - public void i_pay(int amount) { - calc.push(amount); + @When("I pay {amount}") + public void i_pay(Amount amount) { + calc.push(amount.price); calc.push("-"); } @@ -30,10 +59,46 @@ public void my_change_should_be_(int change) { assertEquals(-calc.value().intValue(), change); } + @Given("the following shopping list:") + public void the_following_shopping_list(List list) { + shoppingList = list; + } + + @Given("the shop has following groceries:") + public void the_shop_has_following_groceries(List shopStock) { + this.shopStock = shopStock; + + } + + @When("I count shopping price") + public void i_count_shopping_price() { + shoppingList.forEach(grocery -> { + for (Grocery shopGrocery: shopStock) { + if (grocery.equals(shopGrocery)) { + groceriesPrice += shopGrocery.price.value; + } + } + }); + } + + @Then("price would be {int}") + public void price_would_be(int totalPrice) { + assertEquals(groceriesPrice, totalPrice); + } + static class Grocery { private String name; private Price price; + public Grocery(String name, Price price) { + this.name = name; + this.price = price; + } + + public Grocery(String name) { + this.name = name; + } + public void setPrice(Price price) { this.price = price; } @@ -50,6 +115,14 @@ public String getName() { return name; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Grocery grocery = (Grocery) o; + return Objects.equals(name, grocery.name); + } + } static final class Price { @@ -64,4 +137,14 @@ static Price fromString(String value) { } } + + static final class Amount { + private final BigDecimal price; + private final Currency currency; + + public Amount(BigDecimal price, Currency currency) { + this.price = price; + this.currency = currency; + } + } } diff --git a/examples/java-calculator/src/test/resources/io/cucumber/examples/java/shopping.feature b/examples/java-calculator/src/test/resources/io/cucumber/examples/java/shopping.feature index 54723d3a61..945897682e 100644 --- a/examples/java-calculator/src/test/resources/io/cucumber/examples/java/shopping.feature +++ b/examples/java-calculator/src/test/resources/io/cucumber/examples/java/shopping.feature @@ -6,5 +6,21 @@ Feature: Shopping | milk | 9 | | bread | 7 | | soap | 5 | - When I pay 25 - Then my change should be 4 \ No newline at end of file + When I pay 25.0 USD + Then my change should be 4 + + Scenario: Count shopping list cost + Given the following shopping list: + """shopping_list + milk + bread + coffee + """ + And the shop has following groceries: + | name | price | + | milk | 9 | + | bread | 7 | + | coffee| 2 | + | soap | 5 | + When I count shopping price + Then price would be 18 diff --git a/examples/java8-calculator/src/test/java/io/cucumber/examples/java8/RpnCalculatorSteps.java b/examples/java8-calculator/src/test/java/io/cucumber/examples/java8/RpnCalculatorSteps.java index 4636f6da12..50a1a822a7 100644 --- a/examples/java8-calculator/src/test/java/io/cucumber/examples/java8/RpnCalculatorSteps.java +++ b/examples/java8-calculator/src/test/java/io/cucumber/examples/java8/RpnCalculatorSteps.java @@ -5,6 +5,7 @@ import io.cucumber.java8.Scenario; import java.util.List; +import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -45,6 +46,12 @@ public RpnCalculatorSteps() { } }); + DataTableType((Map row) -> new RpnCalculatorSteps.Entry( + Integer.valueOf(row.get("first")), + Integer.valueOf(row.get("second")), + row.get("operation") + )); + } static final class Entry { diff --git a/examples/java8-calculator/src/test/java/io/cucumber/examples/java8/ShoppingSteps.java b/examples/java8-calculator/src/test/java/io/cucumber/examples/java8/ShoppingSteps.java index 7840a811e6..2a4dee8fe5 100644 --- a/examples/java8-calculator/src/test/java/io/cucumber/examples/java8/ShoppingSteps.java +++ b/examples/java8-calculator/src/test/java/io/cucumber/examples/java8/ShoppingSteps.java @@ -1,16 +1,25 @@ package io.cucumber.examples.java8; +import static org.junit.jupiter.api.Assertions.assertEquals; + import io.cucumber.datatable.DataTable; import io.cucumber.java8.En; - +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.Currency; import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; public class ShoppingSteps implements En { private RpnCalculator calc = new RpnCalculator(); + private List shoppingList; + private List shopStock; + private int groceriesPrice; + public ShoppingSteps() { Given("the following groceries:", (DataTable dataTable) -> { @@ -21,24 +30,71 @@ public ShoppingSteps() { } }); - When("I pay {}", (Integer amount) -> { - calc.push(amount); + When("I pay {amount}", (Amount amount) -> { + calc.push(amount.price); calc.push("-"); }); Then("my change should be {}", (Integer change) -> { assertEquals(-calc.value().intValue(), change.intValue()); }); + + Given("the following shopping list:", (Grocery [] array) -> { + shoppingList = Arrays.asList(array); + }); + + Given("the shop has following groceries:", (DataTable dataTable) -> { + this.shopStock = dataTable.asList(Grocery.class); + }); + + When("I count shopping price", () -> shoppingList.forEach(grocery -> { + for (Grocery shopGrocery: shopStock) { + if (grocery.equals(shopGrocery)) { + groceriesPrice += shopGrocery.price.value; + } + } + })); + + Then("price would be {int}", (Integer totalPrice) -> assertEquals(groceriesPrice, totalPrice)); + + DataTableType((Map row) -> new ShoppingSteps.Grocery( + row.get("name"), + ShoppingSteps.Price.fromString(row.get("price")) + )); + + ParameterType("amount", "\\d+\\.\\d+\\s[a-zA-Z]+", (String value) -> { + String [] arr = value.split("\\s"); + return new Amount(new BigDecimal(arr[0]), Currency.getInstance(arr[1])); + }); + + DocStringType("shopping_list", (String docstring) -> { + return Stream.of(docstring.split("\\s")) + .map(Grocery::new) + .toArray(Grocery[]::new); + }); } static class Grocery { private String name; private Price price; + public Grocery(String name) { + this.name = name; + } + Grocery(String name, Price price) { this.name = name; this.price = price; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Grocery grocery = (Grocery) o; + return Objects.equals(name, grocery.name); + } + } static final class Price { @@ -53,4 +109,14 @@ static Price fromString(String value) { } } + + static final class Amount { + private final BigDecimal price; + private final Currency currency; + + public Amount(BigDecimal price, Currency currency) { + this.price = price; + this.currency = currency; + } + } } diff --git a/examples/java8-calculator/src/test/java/io/cucumber/examples/java8/TypeRegistryConfiguration.java b/examples/java8-calculator/src/test/java/io/cucumber/examples/java8/TypeRegistryConfiguration.java deleted file mode 100644 index 87f5d23db2..0000000000 --- a/examples/java8-calculator/src/test/java/io/cucumber/examples/java8/TypeRegistryConfiguration.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.cucumber.examples.java8; - -import io.cucumber.core.api.TypeRegistryConfigurer; -import io.cucumber.core.api.TypeRegistry; -import io.cucumber.datatable.DataTableType; - -import java.util.Locale; -import java.util.Map; - -import static java.util.Locale.ENGLISH; - -public class TypeRegistryConfiguration implements TypeRegistryConfigurer { - - @Override - public Locale locale() { - return ENGLISH; - } - - @Override - public void configureTypeRegistry(TypeRegistry typeRegistry) { - typeRegistry.defineDataTableType(new DataTableType( - RpnCalculatorSteps.Entry.class, - (Map row) -> new RpnCalculatorSteps.Entry( - Integer.valueOf(row.get("first")), - Integer.valueOf(row.get("second")), - row.get("operation") - ) - )); - - typeRegistry.defineDataTableType(new DataTableType( - ShoppingSteps.Grocery.class, - (Map row) -> new ShoppingSteps.Grocery( - row.get("name"), - ShoppingSteps.Price.fromString(row.get("price")) - ) - )); - } -} diff --git a/examples/java8-calculator/src/test/resources/io/cucumber/examples/java8/shopping.feature b/examples/java8-calculator/src/test/resources/io/cucumber/examples/java8/shopping.feature index 54723d3a61..945897682e 100644 --- a/examples/java8-calculator/src/test/resources/io/cucumber/examples/java8/shopping.feature +++ b/examples/java8-calculator/src/test/resources/io/cucumber/examples/java8/shopping.feature @@ -6,5 +6,21 @@ Feature: Shopping | milk | 9 | | bread | 7 | | soap | 5 | - When I pay 25 - Then my change should be 4 \ No newline at end of file + When I pay 25.0 USD + Then my change should be 4 + + Scenario: Count shopping list cost + Given the following shopping list: + """shopping_list + milk + bread + coffee + """ + And the shop has following groceries: + | name | price | + | milk | 9 | + | bread | 7 | + | coffee| 2 | + | soap | 5 | + When I count shopping price + Then price would be 18