emitsInAnyOrder function

StreamMatcher emitsInAnyOrder(
  1. Iterable matchers

Returns a StreamMatcher that matches the stream if each matcher in matchers matches, in any order.

If any matcher fails to match, this fails and consumes no events. If the matchers match in multiple different possible orders, this chooses the order that consumes as many events as possible.

If any sequence of matchers matches the stream, no errors from other sequences are thrown. If no sequences match and multiple sequences throw errors, the first error is re-thrown.

Note that checking every ordering of matchers is O(n!) in the worst case, so this should only be called when there are very few matchers.


StreamMatcher emitsInAnyOrder(Iterable matchers) {
  var streamMatchers = matchers.map(emits).toSet();
  if (streamMatchers.length == 1) return streamMatchers.first;
  var description = 'do the following in any order:\n'
      '${bullet(streamMatchers.map((matcher) => matcher.description))}';

  return StreamMatcher(
      (queue) async => await _tryInAnyOrder(queue, streamMatchers) ? null : '',