Cucumber-jvm: @Transpose doesn't work with a single element

Created on 26 Jun 2014  ·  10Comments  ·  Source: cucumber/cucumber-jvm

public void I_should_get(final @Transpose List expected) works but public void I_should_get(final @Transpose Foo expected) doesn't. However it makes sense to use it for @Then steps.

Just needs to modify cucumber.runtime.table.TableConverter#convert to not throw throw new CucumberException("Not a Map or List type: " + type); but use type as item type then return a single value.

pinned

Most helpful comment

Are there plans to get this working with Cucumber?
The documentation seems to show it supports this, but it doesn't appear to work:
https://cucumber.github.io/api/cucumber/jvm/javadoc/cucumber/api/Transpose.html

Result is:

cucumber.runtime.CucumberException: Not a Map or List type:

Here's an example of what I tried:

Feature.feature

Background:
  Given the following default values:
    | name   | Product A |
    | weight | 16 oz.    |
    | price  | 2.19      |

Product.java

public class Product {
  private String name;
  private String weight;
  private Double price;

  // Getters and Setters below...
}

StepDef.java

  @Given("^the following default values:$")
  public void the_following_default_values(@Transpose Product product) {
    // Code goes here...
  }

All 10 comments

Can you provide an example where this makes sense? Perhaps a pull request with a failing test at the least?

Here is sample with few fixes https://github.com/rmannibucau/cucumber-jvm/commit/c1946bb59a13daf26aed8d24ed229a2f4b8727a3

Fixes are:

  • support to reference as glue directly a single class
  • support @Transpose for single item (no need to get a list)
  • support @Transpose evaluation item by item (we have a list but the @Then is done item by item)

I have some comments about your fix @rmannibucau.

Can you please create a PR then we can move the discussion there?

Thanks

Are there plans to get this working with Cucumber?
The documentation seems to show it supports this, but it doesn't appear to work:
https://cucumber.github.io/api/cucumber/jvm/javadoc/cucumber/api/Transpose.html

Result is:

cucumber.runtime.CucumberException: Not a Map or List type:

Here's an example of what I tried:

Feature.feature

Background:
  Given the following default values:
    | name   | Product A |
    | weight | 16 oz.    |
    | price  | 2.19      |

Product.java

public class Product {
  private String name;
  private String weight;
  private Double price;

  // Getters and Setters below...
}

StepDef.java

  @Given("^the following default values:$")
  public void the_following_default_values(@Transpose Product product) {
    // Code goes here...
  }

This could be fixed changing the line linked below to be something like:

List<T> list = Collections.unmodifiableList((List<T>) xStream.unmarshal(reader));

and add a check that is something like:

return (list.size == 1) ? list.get(0) : list;

This will allow users to specify a step in my feature file like:

    Given a user with the following fields:
      | firstName   | lastName   | birthYear   |
      | Sean        | Franklin   | 1991        |

and a step definition like:

    @Given("^a user with the following fields:$")
    public void aUserWithTheFollowingFields(User user) {
        this.user = user;
    }

instead of what I currently need to do:

    @Given("^a user with the following fields:$")
    public void aUserWithTheFollowingFields(List<User> users) {
        this.user = users.get(0);
    }

This will not solve the issue with the Transpose doc showing that having the field names in the 1st column with the values in the 2nd since this route assumes the field names are in the first row, but allows a single row table to be mapped to an object.

https://github.com/cucumber/cucumber-jvm/blob/45ee6743517968ee086f674f941334660bdc4f82/core/src/main/java/cucumber/runtime/table/TableConverter.java#L104

I thought the Transpose annotation allowed you to use vertical tables rather than horizontal tables? Therefore this bug does not seem specific to when the Transpose annotation is in use.

I think the bug is that it's not possible to convert a data table (transposed or not) into a single object in the step definition. However, as someone has already pointed out, this is shown in the Transpose API docs:

https://cucumber.github.io/api/cucumber/jvm/javadoc/cucumber/api/Transpose.html

I had a look at some of the proposed changes here

If I understand it correctly, this would check the type of the parameter in the method signature and if it's not a list call the step definition once for each entry in the data table. Rather than expecting the step definition to define the parameter as a list and handle the looping yourself.

This would get around the problem I'm having (converting a data table with a single entry and a step definition with a single type parameter rather than a list of those types). I can also see how this could be useful in certain scenarios. However I believe that this could lead to some confusion unless it is well documented. e.g developers writing feature files with data tables that have multiple entries not realising the step def will be called once for each entry.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in a week if no further activity occurs.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings