Giter Site home page Giter Site logo

Comments (7)

scordio avatar scordio commented on July 24, 2024 2

Although it's possible to obtain the previous behavior, similar to how you did it with TypeAwareListAssert, I believe we should provide better support for such use cases.

However, I wouldn't reintroduce what we've been deprecating as it's less discoverable.

What if we would add an API to configure the assertions for the available navigation methods?

Something like:

assertThat(List.of("a", "b", "c"))
  .withElementAssert(StringAssert::new)
  // further assertions on the list
  .hasSize(3)
  // navigation method
  .first() // returns StringAssert instead of ObjectAssert<String>
  // further String assertions on the element
  ...

Then, your example would become:

public AbstractListAssert<?, List<? extends String>, String, ? extends AbstractStringAssert<?>> arguments() {
  isNotNull();

  var arguments = actual.getArguments();

  return Assertions.assertThat(arguments)
      .withElementAssert(StringAssert::new)
      .as("Compiler arguments %s", StringUtils.quotedIterable(arguments));
}

from assertj.

Adrodoc55 avatar Adrodoc55 commented on July 24, 2024 2

I also heavily use FactoryBasedNavigableListAssert and love the proposal for withElementAssert. I actually wanted to open an issue for improving the generics, but then saw this issue about it beeing deprecated. So I'll post here.

Currently FactoryBasedNavigableListAssert and by extension the deprecated assertThat method requires the ELEMENT_ASSERT to extend AbstractAssert<ELEMENT_ASSERT, ELEMENT>. This sounds reasonable at first and works fine for concrete assert classes, but the bound is too tight for generic assert classes such as abstract ones.

Consider the following example:

import java.util.List;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.AbstractIntegerAssert;
import org.assertj.core.api.AssertFactory;
import org.assertj.core.api.Assertions;
import org.assertj.core.api.ClassAssert;
import org.assertj.core.api.FactoryBasedNavigableListAssert;

public class Test {
  public static void main(String[] args) {
    List<Class<?>> actualClasses = List.of(Integer.class);
    ClassAssert classAsserter1 = Assertions.assertThat(actualClasses.get(0));
    ClassAssert classAsserter2 = Assertions.assertThat(actualClasses, Assertions::assertThat).element(0);
    ClassAssert classAsserter3 = assertThat2(actualClasses, Assertions::assertThat).element(0);

    List<Integer> actualIntegers = List.of(0);
    AbstractIntegerAssert<?> integerAsserter1 = Assertions.assertThat(actualIntegers.get(0));
    AbstractIntegerAssert<?> integerAsserter2 =
        Assertions.assertThat(actualIntegers, Assertions::assertThat).element(0);
    AbstractIntegerAssert<?> integerAsserter3 = assertThat2(actualIntegers, Assertions::assertThat).element(0);
  }

  public static <ACTUAL extends List<? extends ELEMENT>, ELEMENT, ELEMENT_ASSERT extends AbstractAssert<? extends ELEMENT_ASSERT, ELEMENT>> FactoryBasedNavigableListAssert<?, ACTUAL, ELEMENT, ELEMENT_ASSERT> assertThat2(
      List<? extends ELEMENT> actual, AssertFactory<ELEMENT, ELEMENT_ASSERT> assertFactory) {
    return null;
  }
}

For the List<Class<?>> everything works fine, because assertThat(Class<?> actual) returns the non-generic type ClassAssert, but for integers it does not compile. The reason is that AbstractIntegerAssert<?> which is the return type of assertThat(Integer actual) does not satisfy the bound i mentioned above: AbstractAssert<ELEMENT_ASSERT, ELEMENT>. The bound should really be AbstractAssert<? extends ELEMENT_ASSERT, ELEMENT>. To prove this change makes it work I added the method assertThat2 in the example. This method doesn't compile because the incorrect upper bound also appears in the declaration of FactoryBasedNavigableListAssert and its superclasses, but the call to assertThat2 does compile.

from assertj.

scordio avatar scordio commented on July 24, 2024 1

Thanks for your feedback, @ascopes!

Please give me a bit of time to get familiar with your use case – I'll get back to you.

from assertj.

ascopes avatar ascopes commented on July 24, 2024 1

This sounds like a very good idea, and would be very helpful! I struggled with getting generics to work consistently for this so any help would be greatly appreciated like this on AssertJ's side to simplify this.

from assertj.

ascopes avatar ascopes commented on July 24, 2024 1

Sounds sensible to me! I'd need to release a new version to change to a new API anyway so there is no rush

from assertj.

scordio avatar scordio commented on July 24, 2024

Would it be okay if we introduce such a change in 3.27.0?

I'd prefer to have enough time to digest it properly, and the deprecations will only be removed in version 4.

from assertj.

scordio avatar scordio commented on July 24, 2024

Thanks a lot for your feedback, @Adrodoc55. I'll keep that in mind!

from assertj.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.