Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hasEntry matcher needs proper variance declarations #107

Closed
kwin opened this issue Jun 9, 2015 · 3 comments
Closed

hasEntry matcher needs proper variance declarations #107

kwin opened this issue Jun 9, 2015 · 3 comments

Comments

@kwin
Copy link

kwin commented Jun 9, 2015

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
Copy link
Author

kwin commented Feb 10, 2016

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

@foal
Copy link

foal commented Mar 20, 2022

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

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

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

@tumbarumba
Copy link
Member

I looked at this a bit closer. As far as I can tell by the commit history, this was fixed in 2008, when the signature of the IsMapContaining.hasItem was changed, and flowed through to the top level alias in org.hamcrest.Matchers.hasItem in 2014.

I've added a test to IsMapContainerTest to verify this (part of #422). I'm marking this as closed

tumbarumba added a commit that referenced this issue Sep 22, 2024
This fix PECS rule (producer extends, consumer super) to the Hamcrest IsIterableContaining matcher, as well as dependant implementations. In this instance, a collection of items should be treated as a producer according to this rule, while a matcher acts as a consumer.

There is also an extra test for type variance in hasEntry (#107)

Closes #252
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants