View Javadoc
1   /*
2    * MIT License
3    * Copyright (c) 2006-2025 JMockit developers
4    * See LICENSE file for full license text.
5    */
6   package mockit.internal.expectations;
7   
8   import edu.umd.cs.findbugs.annotations.NonNull;
9   import edu.umd.cs.findbugs.annotations.Nullable;
10  
11  import java.util.ArrayList;
12  import java.util.List;
13  
14  import mockit.internal.expectations.argumentMatching.ArgumentMatcher;
15  import mockit.internal.expectations.argumentMatching.CaptureMatcher;
16  import mockit.internal.expectations.argumentMatching.ClassMatcher;
17  
18  import org.checkerframework.checker.index.qual.NonNegative;
19  
20  public abstract class TestOnlyPhase extends Phase {
21      boolean matchInstance;
22      @Nullable
23      List<ArgumentMatcher<?>> argMatchers;
24      @Nullable
25      Expectation currentExpectation;
26  
27      TestOnlyPhase(@NonNull PhasedExecutionState executionState) {
28          super(executionState);
29      }
30  
31      public final void addArgMatcher(@NonNull ArgumentMatcher<?> matcher) {
32          getArgumentMatchers().add(matcher);
33      }
34  
35      @NonNull
36      private List<ArgumentMatcher<?>> getArgumentMatchers() {
37          if (argMatchers == null) {
38              argMatchers = new ArrayList<>();
39          }
40  
41          return argMatchers;
42      }
43  
44      final void moveArgMatcher(@NonNegative int originalMatcherIndex, @NonNegative int toIndex) {
45          List<ArgumentMatcher<?>> matchers = getArgumentMatchers();
46          int i = getMatcherPositionIgnoringNulls(originalMatcherIndex, matchers);
47  
48          for (i--; i < toIndex; i++) {
49              matchers.add(i, null);
50          }
51      }
52  
53      @NonNegative
54      private static int getMatcherPositionIgnoringNulls(@NonNegative int originalMatcherIndex,
55              @NonNull List<ArgumentMatcher<?>> matchers) {
56          int i = 0;
57  
58          for (int matchersFound = 0; matchersFound <= originalMatcherIndex; i++) {
59              if (matchers.get(i) != null) {
60                  matchersFound++;
61              }
62          }
63  
64          return i;
65      }
66  
67      final void setExpectedSingleArgumentType(@NonNegative int parameterIndex, @NonNull Class<?> argumentType) {
68          ArgumentMatcher<?> newMatcher = ClassMatcher.create(argumentType);
69          getArgumentMatchers().set(parameterIndex, newMatcher);
70      }
71  
72      final void setExpectedMultiArgumentType(@NonNegative int parameterIndex, @NonNull Class<?> argumentType) {
73          CaptureMatcher<?> matcher = (CaptureMatcher<?>) getArgumentMatchers().get(parameterIndex);
74          matcher.setExpectedType(argumentType);
75      }
76  
77      void setMaxInvocationCount(int maxInvocations) {
78          if (currentExpectation != null) {
79              int currentMinimum = currentExpectation.constraints.minInvocations;
80              int minInvocations = maxInvocations < 0 ? currentMinimum : Math.min(currentMinimum, maxInvocations);
81              handleInvocationCountConstraint(minInvocations, maxInvocations);
82          }
83      }
84  
85      abstract void handleInvocationCountConstraint(int minInvocations, int maxInvocations);
86  
87      static boolean isEnumElement(@NonNull Object mock) {
88          Object[] enumElements = mock.getClass().getEnumConstants();
89  
90          if (enumElements != null) {
91              for (Object enumElement : enumElements) {
92                  if (enumElement == mock) {
93                      return true;
94                  }
95              }
96          }
97  
98          return false;
99      }
100 }