View Javadoc
1   /*
2    * Copyright (c) 2006 JMockit developers
3    * This file is subject to the terms of the MIT license (see LICENSE.txt).
4    */
5   package mockit.internal.expectations;
6   
7   import edu.umd.cs.findbugs.annotations.NonNull;
8   import edu.umd.cs.findbugs.annotations.Nullable;
9   
10  import java.util.ArrayList;
11  import java.util.List;
12  
13  import mockit.internal.expectations.invocation.ExpectedInvocation;
14  
15  class UnorderedVerificationPhase extends BaseVerificationPhase {
16      @NonNull
17      private final List<VerifiedExpectation> verifiedExpectations;
18  
19      UnorderedVerificationPhase(@NonNull ReplayPhase replayPhase) {
20          super(replayPhase);
21          verifiedExpectations = new ArrayList<>();
22      }
23  
24      @NonNull
25      @Override
26      final List<ExpectedInvocation> findExpectation(@Nullable Object mock, @NonNull String mockClassDesc,
27              @NonNull String mockNameAndDesc, @NonNull Object[] args) {
28          if (!matchInstance && executionState.isToBeMatchedOnInstance(mock, mockNameAndDesc)) {
29              matchInstance = true;
30          }
31  
32          replayIndex = -1;
33          List<Expectation> expectationsInReplayOrder = replayPhase.invocations;
34          Expectation verification = currentVerification;
35          List<ExpectedInvocation> matchingInvocationsWithDifferentArgs = new ArrayList<>();
36  
37          for (int i = 0, n = expectationsInReplayOrder.size(); i < n; i++) {
38              Expectation replayExpectation = expectationsInReplayOrder.get(i);
39              Object replayInstance = replayPhase.invocationInstances.get(i);
40              Object[] replayArgs = replayPhase.invocationArguments.get(i);
41  
42              if (matches(mock, mockClassDesc, mockNameAndDesc, args, replayExpectation, replayInstance, replayArgs)) {
43                  replayIndex = i;
44  
45                  if (verification != null) {
46                      verification.constraints.invocationCount++;
47                  }
48  
49                  currentExpectation = replayExpectation;
50              } else if (matchingInvocationWithDifferentArgs != null) {
51                  matchingInvocationsWithDifferentArgs.add(matchingInvocationWithDifferentArgs);
52              }
53          }
54  
55          if (verification != null && replayIndex >= 0) {
56              pendingError = verifyConstraints(verification);
57          }
58  
59          return matchingInvocationsWithDifferentArgs;
60      }
61  
62      @Nullable
63      private Error verifyConstraints(@NonNull Expectation verification) {
64          ExpectedInvocation lastInvocation = replayPhase.invocations.get(replayIndex).invocation;
65          Object[] lastArgs = replayPhase.invocationArguments.get(replayIndex);
66          return verification.verifyConstraints(lastInvocation, lastArgs, 1, -1);
67      }
68  
69      @Override
70      final void addVerifiedExpectation(@NonNull Expectation expectation, @NonNull Object[] args) {
71          VerifiedExpectation verifiedExpectation = new VerifiedExpectation(expectation, args, argMatchers, -1);
72          addVerifiedExpectation(verifiedExpectation);
73          verifiedExpectations.add(verifiedExpectation);
74      }
75  
76      @Override
77      final void handleInvocationCountConstraint(int minInvocations, int maxInvocations) {
78          pendingError = null;
79  
80          Expectation verifying = currentVerification;
81  
82          if (verifying == null) {
83              return;
84          }
85  
86          Error errorThrown;
87  
88          if (replayIndex >= 0) {
89              ExpectedInvocation replayInvocation = replayPhase.invocations.get(replayIndex).invocation;
90              Object[] replayArgs = replayPhase.invocationArguments.get(replayIndex);
91              errorThrown = verifying.verifyConstraints(replayInvocation, replayArgs, minInvocations, maxInvocations);
92          } else {
93              errorThrown = verifying.verifyConstraints(minInvocations);
94          }
95  
96          if (errorThrown != null) {
97              throw errorThrown;
98          }
99      }
100 }