emitsThrough function
Returns a StreamMatcher that matches any number of events followed by
events that match matcher
.
This consumes all events matched by matcher
, as well as all events before.
If the stream emits a done event without matching matcher
, this fails and
consumes no events.
Implementation
StreamMatcher emitsThrough(matcher) {
var streamMatcher = emits(matcher);
return StreamMatcher((queue) async {
var failures = <String>[];
tryHere() => queue.withTransaction((copy) async {
var result = await streamMatcher.matchQueue(copy);
if (result == null) return true;
failures.add(result);
return false;
});
while (await queue.hasNext) {
if (await tryHere()) return null;
await queue.next;
}
// Try after the queue is done in case the matcher can match an empty
// stream.
if (await tryHere()) return null;
var result = "never did ${streamMatcher.description}";
var failureMessages =
bullet(failures.where((failure) => failure.isNotEmpty));
if (failureMessages.isNotEmpty) {
result += result.contains("\n") ? "\n" : " ";
result += "because it:\n$failureMessages";
}
return result;
}, "eventually ${streamMatcher.description}");
}