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(Object? matcher) {
var streamMatcher = emits(matcher);
return StreamMatcher((queue) async {
var failures = <String>[];
Future<bool> 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}');
}