JavaHamcrest
JavaHamcrest copied to clipboard
Add generic boundaries to everyItem factory method
The factory method Every.everyItem
currently returns a Matcher<Iterable<U>>
. Wouldn't a Matcher<Iterable<? extends U>>
make sense here? This would be in accordance with the guidelines for wildcard use.
Other collection matchers, such as IsIterableContainingInOrder
already do this.
Yes it does make more sense this way. +1
I agree. And further, should it actually be a Matcher<? extends Iterable<? extends U>>?
(Aarrggh!)
@npryce Strongly disagree!!!
I'm unable to upgrade from 1.3 to 2.x because of this change, since my tests using everyItem
wouldn't compile anymore (using Java 8).
Actually @bjoernpollex misinterpreted the guidelines for wildcard use. See in particular this note:
These guidelines do not apply to a method's return type. Using a wildcard as a return type should be avoided because it forces programmers using the code to deal with wildcards.
Thus everyItem
should keep returning Matcher<Iterable<U>>
. A wildcard was indeed missing, but it should have been added to the item matcher parameter instead. Since the item matcher is in "out" mode (because it will receive items from the iterable), it must be written Matcher<? super U>
.
To sum up, the factory signature should be Matcher<Iterable<U>> everyItem(Matcher<? super U> itemMatcher)
, and the Every
class should extend TypeSafeDiagnosingMatcher<Iterable<T>>
(without wildcard).
(My tests compile again after applying this change)
Just checking the current code and it's public static <U> Matcher<Iterable<? extends U>> everyItem(final Matcher<U> itemMatcher) {
And you and it to be; public static <U> Matcher<Iterable<U>> everyItem(final Matcher<? extends U> itemMatcher) {
Does this solution break https://github.com/hamcrest/JavaHamcrest/issues/289