waitForOneWhere method

Future<PendingRequest> waitForOneWhere(
  1. bool predicate(
    1. HttpRequest
    ), {
  2. Duration timeout = const Duration(seconds: 5),
  3. String description = 'matching request',
})

Event-driven predicate matching with a bounded wait and diagnostic failure.

Implementation

Future<PendingRequest> waitForOneWhere(bool Function(HttpRequest) predicate,
    {Duration timeout = const Duration(seconds: 5),
    String description = 'matching request'}) async {
  if (timeout <= Duration.zero) throw ArgumentError.value(timeout, 'timeout');
  final result = Completer<PendingRequest>();
  void check() {
    if (result.isCompleted) return;
    try {
      if (_closed) throw StateError('Testing controller closed.');
      final candidates = _pending
          .where((item) => !item.matched && predicate(item.request))
          .toList();
      if (candidates.isEmpty) return;
      if (candidates.length != 1) {
        throw StateError(
            'Expected one $description, found ${candidates.length}. '
            'Outstanding: $_outstanding');
      }
      candidates.single.matched = true;
      result.complete(candidates.single);
    } catch (error, stack) {
      result.completeError(error, stack);
    }
  }

  final subscription = _changes.stream.listen((_) => check());
  final timer = Timer(timeout, () {
    if (result.isCompleted) return;
    result.completeError(TimeoutException(
        'Waiting for $description. '
        'Outstanding: $_outstanding',
        timeout));
  });
  check();
  try {
    return await result.future;
  } finally {
    timer.cancel();
    await subscription.cancel();
  }
}