Add contains stream matcher for checking "in any order"
bertvh opened this issue · 4 comments
I'm looking for something like IsCollectionContaining.<T>hasItems(items);
so that I can write
assertThat(items.stream().map(/*some mapping*/)), hasItems("item1", "item2"));
instead of
assertThat(items.stream().map(/*some mapping*/).collect(Collectors.toList()), hasItems("item1", "item2"));
Thanks, this is a good idea.
I'm implementing this feature now. In the course of doing this, I've noticed that the behaviour of contains
is a bit unexpected:
assertThat(Stream.of("a", "b", "c"), contains( "b", "c"));
passes
but assertThat(Stream.of("a", "b", "c"), contains( "c", "b"));
does not.
In the course of fixing this, I'll create the feature that you've asked for. Thanks for your patience!
Neither of those should pass if we're going to stick with normal hamcrest syntax: http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#contains(E...)
assertThat(Stream.of("a", "b", "c"), contains( "a", "b", "c"))
should pass.
assertThat(Stream.of("a", "b", "c"), contains( "b", "c", "a"))
should not pass.
Nothing should pass unless all of the elements are in the Stream, and no others.
Indeed. I'm not convinced that we should follow hamcrest's conventions, though. Or at least, we should create some matchers with good names, and then allow the hamcrest names to alias them where we think it will help people who are already familiar with the hamcrest style.
Actually, I often find myself using both Hamcrest's matchers and java-8-matchers in the same test class, which prevents me from static importing different matchers with the same name. Which is also a case against trying to make the matcher names in this library "familiar" for existing Hamcrest users by reusing the names. I am also not convinced that following Hamcrest's conventions is a good idea, as their matchers often can be ambiguously or imprecisely named. (It is not immediately obvious that contains
means "containing exactly the elements in the given order".)