Reputation: 10882
I am obviously confused about how to use Hamcrest's IsIterableContainingInOrder
to verify List equality beyond just using .equals()
. I'd like to see Hamcrest's helpful messages in my reports.
Why are the tests below failing to even compile? Some of them are more counter-intuitive than others, at least for me. I get, I think, the general principle that the type parameter will be inferred to what I pass to a method with a varargs signature so it will consider arrays of T as varargs of T and so will generate a Matcher based on T and not on array of T, iterable of T, or anything like that.
I could use an explanation, please, as to why some of the lines that are most intuitive actually fail to even compile.
Particularly:
The compiler warning on the line marked as such is even more mysterious to me.
@org.junit.Test
public void testTest() {
String string1 = "A";
String string2 = "B";
String string3 = "C";
List<String> list1 = Lists.newArrayList(string1, string2, string3);
List<String> list2 = Lists.newArrayList(string1, string2, "C");
String[] array1 = list1.toArray(new String[list1.size()]);
String[] array2 = list2.toArray(new String[list2.size()]);
// -------------------------------------------------------------------------
// 1) The assertion after this comment line DOES NOT COMPILE
// Assert.assertThat(array2, IsIterableContainingInOrder.contains(array1));
// -------------------------------------------------------------------------
// 2) The assertion after this comment line DOES NOT COMPILE
// Assert.assertThat(list2, IsIterableContainingInOrder.contains(list1));
// -------------------------------------------------------------------------
// 3) The assertion after this comment line SUCCEEDS
Assert.assertThat(list2, IsIterableContainingInOrder.contains(array1));
// -------------------------------------------------------------------------
// 4) The assertion after this comment line DOES NOT COMPILE + HAS WARNING
// Assert.assertThat(array2, IsIterableContainingInOrder.contains(list1));
// -------------------------------------------------------------------------
// 5) The assertion after this comment line DOES NOT COMPILE
// Assert.assertThat(array2, IsIterableContainingInOrder.contains(string1));
// -------------------------------------------------------------------------
// 6) The assertion after this comment line COMPILES but fails
Assert.assertThat(list2, IsIterableContainingInOrder.contains(string1));
// -------------------------------------------------------------------------
// 7) The assertion after this comment line COMPILES and succeeds
Assert.assertThat(list2,
IsIterableContainingInOrder.contains(string1, string2, string3));
// -------------------------------------------------------------------------
}
PS I realise all of the astonishment comes from my own ignorance and nothing else. I should brush up on Generics, type inference, varargs, etc. I could really use a thorough explanation on this, and I would probably refer back to it a few times going forward.
PPS I did try to read the code first but look at it for a sec... ;) Not for the feint of heart:
@SuppressWarnings("unchecked")
@Factory
public static <E> Matcher<Iterable<? extends E>> contains(final Matcher<? super E> itemMatcher) {
return contains(new ArrayList<Matcher<? super E>>(asList(itemMatcher)));
}
Upvotes: 2
Views: 2431
Reputation: 29907
Here are the aswers... hopefully correct ones :)
// 1) The assertion after this comment line DOES NOT COMPILE
// Assert.assertThat(array2, IsIterableContainingInOrder.contains(array1));
This one does doesn't compile, because arrays don't implement Iteratable.
// 2) The assertion after this comment line DOES NOT COMPILE
// Assert.assertThat(list2, IsIterableContainingInOrder.contains(list1));
For this to work, list2 should be a List<List<String>>
, as contains only verifies that the iteratable contains the item that is passed
// 3) The assertion after this comment line SUCCEEDS
Assert.assertThat(list2, IsIterableContainingInOrder.contains(array1));
Passes because array1 is taken as a vararg.
// 4) & 5)
Same as 1
// 6) The assertion after this comment line COMPILES but fails
Assert.assertThat(list2, IsIterableContainingInOrder.contains(string1));
Contains expects all the items in the collection, not just a subset.
// 7)
Similar as 3, but with each item passed.
Upvotes: 6