assertj / assertj-assertions-generator

Custom assertions generator
https://joel-costigliola.github.io/assertj/assertj-assertions-generator.html
Apache License 2.0
62 stars 42 forks source link

Generated assertions do not preserve generic types #92

Open theangrydev opened 7 years ago

theangrydev commented 7 years ago

For example, if I have: public final Optional<Boolean> foo;,

the generated assertion is: hasFoo(java.util.Optional foo)

when it should be: hasFoo(java.util.Optional<Boolean> foo)

joel-costigliola commented 7 years ago

True, this requires the generator to be migrated to Java 8 in order to properly introspect Optional fields.

joel-costigliola commented 7 years ago

Adding generic support is really complicated because generic bounds (super, extends), @Nava2 and I have given it a fair try but there were some cases difficult to support (although I was able to generate properly Optional assertions), anyone interested can see the work in branch https://github.com/joel-costigliola/assertj-assertions-generator/tree/generics-support

jcogilvie commented 7 years ago

What about passing generic parameters through? For instance given the following inputs, the current generator actually generates code that won't compile:

package com.api.dto;

import java.util.List;

public abstract class PagedResultApi<T> extends BaseApi {
    public int pageNumber;
    public int pageSize;
    public int total;
    public List<T> entities;

    public PagedResultApi() {
    }
}

Assertions are generated for entities that take an argument of type T, but T is not defined anywhere. For this case, defaulting to Object or even omitting the property entirely would be better than generating something we can't compile.

@javax.annotation.Generated(value="assertj-assertions-generator")
public abstract class AbstractPagedResultApiAssert<S extends AbstractPagedResultApiAssert<S, A>, A extends PagedResultApi> extends AbstractBaseApiAssert<S, A> {

  // snip

  /**
   * Verifies that the actual PagedResultApi's entities contains the given T elements.
   * @param entities the given elements that should be contained in actual PagedResultApi's entities.
   * @return this assertion object.
   * @throws AssertionError if the actual PagedResultApi's entities does not contain all given T elements.
   */
  public S hasEntities(T... entities) {
    // check that actual PagedResultApi we want to make assertions on is not null.
    isNotNull();

    // check that given T varargs is not null.
    if (entities == null) failWithMessage("Expecting entities parameter not to be null.");

    // check with standard error message, to set another message call: info.overridingErrorMessage("my error message");
    Iterables.instance().assertContains(info, actual.entities, entities);

    // return the current assertion for method chaining
    return myself;
  }
joel-costigliola commented 7 years ago

At this point without generic support, what we can try is to replace the generic parameter by Object but I'm not sure it is going to work.