liangzai-cool / hamcrest

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

Enhancement: matcher that asserts an element occurs before another element in an iterator #174

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
I need a matcher that says that:
   given an actual iterator i
   given an expected element e1
   given an expected element e2 :
      e1 is in i
      e2 is in i
      e1 is before e2 in i

Original issue reported on code.google.com by lexicals...@gmail.com on 7 Feb 2012 at 1:40

GoogleCodeExporter commented 8 years ago
Iterators don't implicitly have any order. In such cases, you cannot guarantee 
that if Iterable is iterated through a second time that the elements will be in 
the same order.

This could make a fragile test that suddenly breaks for no apparent reason. I 
don't know of any generic interface that declares an Iterable as ordered.

Original comment by alan.esc...@gmail.com on 7 Feb 2012 at 2:32

GoogleCodeExporter commented 8 years ago
Ok, I actually have a list, so maybe I was being too general. Perhaps it should 
be:

given an actual list l
   given an expected element e1
   given an expected element e2 :
      e1 is in l
      e2 is in l
      e1 is before e2 in l

Original comment by lexicals...@gmail.com on 7 Feb 2012 at 6:12

GoogleCodeExporter commented 8 years ago
It could be written as:

assertThat(l, hasItems(e1, e2));
assertThat(l.indexOf(e1), is(lessThan(l.indexOf(e2))));

But I guess a more descriptive matcher could read something like:

assertThat(l, hasItems(e1, e2), inOrder(e1, e2));

where:

Matcher<List<T>> inOrder(T... elements)

Is this the kind of syntax that you had in mind?

Original comment by alan.esc...@gmail.com on 8 Feb 2012 at 11:02

GoogleCodeExporter commented 8 years ago
Sorry, that last example should have been:

assertThat(l, allOf(hasItems(e1, e2), inOrder(e1, e2)));

If you wanted to, you could also have a convenience matcher that assumes that 
all elements wanted in order must also be present in the list, for example:

assertThat(l, hasItemsInOrder(e1, e2));

Original comment by alan.esc...@gmail.com on 8 Feb 2012 at 11:08

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
Yeah, that looks very good. 

I am trying to make assertions about the result of a topological sort of a 
directed graph, where only a small number of the vertices have edges between 
them. So I don't care what order the list is in, except that for those few 
pairs of vertices the order must be correct.

So, just to clarify, both the lists:

e1,e2

and 

e5,e1,e3,e4,e2 are acceptable.

Original comment by lexicals...@gmail.com on 8 Feb 2012 at 1:38

GoogleCodeExporter commented 8 years ago
Sounds reasonable. If you want to check specific positions, then you'd want to 
explicitly test the indices of the elements.

I can however imagine that someone would want to test that e1 and e2 are 
adjacent and in a correct order, but anywhere in a list, i.e.
e5,e1,e2,e4,e3 is okay. I guess another matcher like:

Matcher<List<T>> inSequence(T... elememts)

would work well.

I only started following Hamcrest yesterday, as you posted the enhancement 
request.
If it works anything like JUnit, then nothing speaks against writing the 
feature and asking for a pull request.

Could anyone who's already implemented features for Hamcrest can give us hints 
about how this process works?

Original comment by alan.esc...@gmail.com on 8 Feb 2012 at 1:54

GoogleCodeExporter commented 8 years ago
I would bet the project devs would be willing to accept a patch file attached 
to this issue.

Original comment by dharkn...@gmail.com on 14 Feb 2012 at 11:10

GoogleCodeExporter commented 8 years ago
tagged Java

Original comment by t.denley on 12 May 2012 at 10:13