peterlck / hamcrest

Automatically exported from code.google.com/p/hamcrest
0 stars 0 forks source link

(Java) containsInAnyOrder incorrect generic type specification causes wrong method to have higher precedence #188

Open GoogleCodeExporter opened 10 years ago

GoogleCodeExporter commented 10 years ago
In Matchers.java:

  public static <T> org.hamcrest.Matcher<java.lang.Iterable<? extends T>> containsInAnyOrder(T... items) {
    return org.hamcrest.collection.IsIterableContainingInAnyOrder.<T>containsInAnyOrder(items);
  }

  public static <T> org.hamcrest.Matcher<java.lang.Iterable<? extends T>> containsInAnyOrder(java.util.Collection<org.hamcrest.Matcher<? super T>> matchers) {
    return org.hamcrest.collection.IsIterableContainingInAnyOrder.<T>containsInAnyOrder(matchers);
  }

assume:

public class Widget { ... }

public class WidgetMatcher extends BaseMatcher<Widget> {

  public WidgetMatcher(Widget widget) {
    this.widget = widget;
  }

  ...

  public static WidgetMatcher widget(Widget widget) { ... }

  public static Collection<WidgetMatcher> widgets(Widget... widgets) {
    List<WidgetMatcher> widgetMatchers = new ArrayList<WidgetMatcher>();
    for (Widget widget : widgets) {
      widgetMatchers.add(new WidgetMatcher(widget));
    }
    return widgetMatchers;
  }    
}

If you then attempt to call:

containsInAnyOrder(widgetMatchers(widget1, widget2));

it calls containsInAnyOrder(T... items) rather than the Collection variant. I 
believe this is because the signature should be:

  public static <T> org.hamcrest.Matcher<java.lang.Iterable<? extends T>> containsInAnyOrder(java.util.Collection<? extends org.hamcrest.Matcher<? super T>> matchers) {

Java doesn't seem to allow any other "safe" way of calling this method other 
than using a naked generic type:

containsInAnyOrder((Collection) widgetMatchers(...))

Original issue reported on code.google.com by wshie...@google.com on 10 Aug 2012 at 2:06