verifyInOrder top-level property Null safety

_InOrderVerification verifyInOrder

Verifies that a list of methods on a mock object have been called with the given arguments. For example:

verifyInOrder([cat.eatFood("Milk"), cat.sound(), cat.eatFood(any)]);

This verifies that eatFood was called with "Milk", sound was called with no arguments, and eatFood was then called with some argument.

Returns a list of verification results, one for each call which was verified.

For example, if verifyInOrder is given these calls to verify:

var verification = verifyInOrder(
    [cat.eatFood(captureAny), cat.chew(), cat.eatFood(captureAny)]);

then verification is a list which contains a captured getter which returns three lists:

  1. a list containing the argument passed to eatFood in the first verified eatFood call,
  2. an empty list, as nothing was captured in the verified chew call,
  3. a list containing the argument passed to eatFood in the second verified eatFood call.

Note: verifyInOrder only verifies that each call was made in the order given, but not that those were the only calls. In the example above, if other calls were made to eatFood or sound between the three given calls, or before or after them, the verification will still succeed.

Implementation

_InOrderVerification get verifyInOrder {
  if (_verifyCalls.isNotEmpty) {
    throw StateError(_verifyCalls.join());
  }
  _verificationInProgress = true;
  return <T>(List<T> responses) {
    if (responses.length != _verifyCalls.length) {
      fail('Used on a non-mockito object');
    }
    _verificationInProgress = false;
    var verificationResults = <VerificationResult>[];
    var time = DateTime.fromMillisecondsSinceEpoch(0);
    var tmpVerifyCalls = List<_VerifyCall>.from(_verifyCalls);
    _verifyCalls.clear();
    var matchedCalls = <RealCall>[];
    for (var verifyCall in tmpVerifyCalls) {
      try {
        var matched = verifyCall._findAfter(time);
        matchedCalls.add(matched.realCall);
        verificationResults.add(VerificationResult._(1, matched.capturedArgs));
        time = matched.realCall.timeStamp;
      } on StateError {
        var mocks = tmpVerifyCalls.map((vc) => vc.mock).toSet();
        var allInvocations =
            mocks.expand((m) => m._realCalls).toList(growable: false);
        allInvocations
            .sort((inv1, inv2) => inv1.timeStamp.compareTo(inv2.timeStamp));
        var otherCalls = '';
        if (allInvocations.isNotEmpty) {
          otherCalls = " All calls: ${allInvocations.join(", ")}";
        }
        fail('Matching call #${tmpVerifyCalls.indexOf(verifyCall)} '
            'not found.$otherCalls');
      }
    }
    for (var call in matchedCalls) {
      call.verified = true;
    }
    return verificationResults;
  };
}