PyHamcrest
PyHamcrest copied to clipboard
hamcrest.contains_inanyorder is order sensitive
E.g. assert_that([1, 2], contains_inanyorder(anything(), 1))
fails.
Hmmmmm. I can see what's going on here. It's not that contains_inanyorder
is order sensitive, it's that overgeneral matchers can consume items from the actuals, leaving more specific matchers to miss.
In your example, the anything()
matches the 1
from the actual list. The contains_inanyorder
matcher pairs them off, drops them, then moves on, leaving the 2
and the 1
from the matcher list, which of course don't match.
I'm not sure how I'd approach fixing this. Any ideas, @robertwb?
In the meantime, the matcher is working as documented, and you can support your use case by specifying the more specific matchers first, then the less specific.
Yes, in this toy example it's clear to see what the order could be, but that's not always the case.
This could be solved generally with https://en.wikipedia.org/wiki/Maximum_cardinality_matching
Interesting, but I'm not sure I think the complexity is worthwhile. How often is this an issue? If we implemented a maximum cardinality matching algorithm, how would that work with consume-once actuals, such as generators?
In any case, I won't get to look at it until #117 is in.
I've run into it a couple of times, the latest because the set of matchers is derived from a container with non-deterministic ordering. For consume-once actuals, one would either run it against all matchers while iterating (rather than just until one finds a match) or reify it into a list.