JavaHamcrest icon indicating copy to clipboard operation
JavaHamcrest copied to clipboard

hasEntry matcher needs proper variance declarations

Open kwin opened this issue 10 years ago • 2 comments

The return type of the hasEntry matcher is invariant on its type parameters which prevents javac/jdt from inferring compatible types. This prevents writing

  public void testFoo() {
    Map<String, Number> m = new HashMap<String,Number>();
    Integer foo = new Integer(6);
    m.put("foo", foo);
    MatcherAssert.assertThat(m, Matcher.hasEntry("foo", foo));
  }

instead, you have to write

MatcherAssert.assertThat(m, Matcher.<String,Number>hasEntry("foo", foo));

or

MatcherAssert.assertThat(m, Matcher.hasEntry("foo", (Number)foo));

If the signature for hasEntry were instead

  public static <K,V> Matcher<Map<? super K,? super V>> hasEntry(K k, V v)

the original example would work fine. This same problem likely applies to other collection matchers like hasItem, hasKey, etc.

Copied from https://code.google.com/p/hamcrest/issues/detail?id=103

kwin avatar Jun 09 '15 14:06 kwin

Actually org.hamcrest.core.IsCollectionContaining.hasItems should have a similar signature to org.hamcrest.collection.IsIterableContainingInOrder.contains or org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder

kwin avatar Feb 10 '16 10:02 kwin

Agree -hasItem(s) is completely broken with return values.

The hasItem returns Matcher<Iterable<? super T>>: <T> Matcher<Iterable<? super T>> hasItem(Matcher<? super T> itemMatcher) The hasItems returns Matcher<Iterable<T>>: <T> Matcher<Iterable<T>> hasItems(Matcher<? super T>... itemMatchers)

The 'contains ' method returns Matcher<Iterable<? extends T>>: <E> Matcher<Iterable<? extends E>> contains(Matcher<? super E> itemMatcher)

foal avatar Mar 20 '22 12:03 foal