TNG / JGiven

Behavior-Driven Development in plain Java
http://jgiven.org
Apache License 2.0
439 stars 98 forks source link

Combine @Table with another formatter? #122

Closed nikowitt closed 8 years ago

nikowitt commented 9 years ago

Hi again,

I'm currently playing again with the @Table annotation:

        public SupplierTestScenario quotations_of_the_same_company_are_awarded_on(
                @Table(numberedRows = true) DateTime... awardDates) throws Exception {
            for (int i = 0; i < awardDates.length; i++) {
                quotation_$_of_the_same_company_is_awarded_on(i + 1, awardDates[i]);
            }
            return self();
        }

returns the result:

    When quotations of the same company are awarded on

     | # |       iMillis | iChronology                  |
     +---+---------------+------------------------------+
     | 1 | 1356994800000 | ISOChronology[Europe/Berlin] |
     | 2 | 1420066800000 | ISOChronology[Europe/Berlin] |
     | 3 | 1388530800000 | ISOChronology[Europe/Berlin] |

By default, all POJO fields are rendered (unless modified with includeFields/excludeFields). The usage of fields basically works fine for POJOs where I have full control of or where I can find fields fields that return a well-formatted value.

In my case, DateTime consists of the fields iMillis or iChronology which are both not very readable. Therefore, my idea is to be able to supply an additional formatter.

If this makes sense for you, there are IMHO two ways: a) The simple approach which probably already works without too much effort results in a one row/column (depending on the formatting) table + a optional numbering row/column. This would (at least for me... currently :) ) meet my requirement as I then would define my method like this

        public SupplierTestScenario quotations_of_the_same_company_are_awarded_on(
                @Table(numberedRows = true) @DateOnly DateTime... awardDates) throws Exception {

and receive an output like

    | # |       dateOnly | 
     +---+---------------+
     | 1 | 2013-01-01|
     | 2 | 2015-01-01 |
     | 3 | 2014-01-01 | 

Another flavour of this idea is to not be able to invoke the toString() method of a POJO, although the formatter idea is more flexible and powerful.

b) The other approach provided a way of post-formatting more than one value. There are several ideas of doing this (Formatter has to return an array? Be able to supply more than one formatter?).

Perhaps this request also makes sense to be included in JGiven.

Best regards, Niko

janschaefer commented 9 years ago

I totally agree that this makes sense, I just haven't thought about that yet ;-). Especially, whether you want to have the POJO rendered by the toString method or a special formatter, or whether you want to have the fields of the POJO treated as columns. In addition, a completely self-defined formatter that translates a POJO into a list of Strings would also make sense. As a workaround for now you could create a wrapper class with one field that holds the DateTime value. Then at least, only one column would be created.

janschaefer commented 9 years ago

I defer this to v0.9.1

janschaefer commented 8 years ago

Ok, after some iterations on this issue, I think it is usable now. It is now possible to combine the @Table annotation with formatters and JGiven will then use the given formatter to format the objects. You can also completely customize the formatting by using the formatter() or rowFormatter() attribute of the @Table annotation.

nikowitt commented 8 years ago

Looks really cool at a first glance when I check the commit. Is there a short documentation with example for this that I can distribute to my colleagues?

janschaefer commented 8 years ago

There is no documentation yet (next on my list). However, it should be more or less straightforward. You have now different options to customize the table formatting.

Using formatter()

If you want to completely define your own table formatting, you use the formatter() attribute. There you specify a TableFormatterFactory class to create your TableFormatter. E.g.

@Table( formatter = MyCustomFormatter.Factory.class) MyClassToBeFormattedAsATable param)

Essentially, you have to implement a method that turns your object into a DataTable

Using rowFormatter()

This is less flexible but easier to implement and only works for parameters that are lists of objects. Here you provide a RowFormatterFactory to create a RowFormatter. You essentially implement a method to translate objects to table rows, i.e. list of strings

Use standard formatter

This only allows you to create tables with a single column. In this case you annotate the parameter with the @Table annotation and in addition with an arbitrary other formatting annotation. JGiven will then use this formatter to format each object to a string.