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 mockit.internal.expectations.invocation.ExpectedInvocation;
11  import mockit.internal.expectations.invocation.InvocationConstraints;
12  import mockit.internal.expectations.invocation.InvocationResults;
13  import mockit.internal.expectations.invocation.ReturnTypeConversion;
14  import mockit.internal.util.TypeDescriptor;
15  
16  final class Expectation {
17      @Nullable
18      final RecordPhase recordPhase;
19      @NonNull
20      final ExpectedInvocation invocation;
21      @NonNull
22      final InvocationConstraints constraints;
23      @Nullable
24      private InvocationResults results;
25      boolean executedRealImplementation;
26  
27      Expectation(@NonNull ExpectedInvocation invocation) {
28          recordPhase = null;
29          this.invocation = invocation;
30          constraints = new InvocationConstraints(true);
31      }
32  
33      Expectation(@NonNull RecordPhase recordPhase, @NonNull ExpectedInvocation invocation, boolean nonStrict) {
34          this.recordPhase = recordPhase;
35          this.invocation = invocation;
36          constraints = new InvocationConstraints(nonStrict);
37      }
38  
39      @NonNull
40      InvocationResults getResults() {
41          if (results == null) {
42              results = new InvocationResults(invocation, constraints);
43          }
44  
45          return results;
46      }
47  
48      @Nullable
49      Object produceResult(@Nullable Object invokedObject, @NonNull Object[] invocationArgs) throws Throwable {
50          if (results == null) {
51              return invocation.getDefaultValueForReturnType();
52          }
53  
54          return results.produceResult(invokedObject, invocationArgs);
55      }
56  
57      @NonNull
58      Class<?> getReturnType() {
59          String resolvedReturnType = invocation.getSignatureWithResolvedReturnType();
60          return TypeDescriptor.getReturnType(resolvedReturnType);
61      }
62  
63      void addSequenceOfReturnValues(@NonNull Object[] values) {
64          int n = values.length - 1;
65          Object firstValue = values[0];
66          Object[] remainingValues = new Object[n];
67          System.arraycopy(values, 1, remainingValues, 0, n);
68  
69          InvocationResults sequence = getResults();
70  
71          if (!new SequenceOfReturnValues(this, firstValue, remainingValues).addResultWithSequenceOfValues()) {
72              sequence.addReturnValue(firstValue);
73              sequence.addReturnValues(remainingValues);
74          }
75      }
76  
77      @SuppressWarnings("UnnecessaryFullyQualifiedName")
78      void addResult(@Nullable Object value) {
79          InvocationResults invocationResults = getResults();
80  
81          if (value == null) {
82              invocationResults.addReturnValueResult(null);
83          } else if (value instanceof Throwable) {
84              invocationResults.addThrowable((Throwable) value);
85          } else if (value instanceof mockit.Delegate) {
86              invocationResults.addDelegatedResult((mockit.Delegate<?>) value);
87          } else if (invocation.isConstructor()) {
88              throw new IllegalArgumentException("Invalid assignment to result field for constructor expectation");
89          } else {
90              Class<?> rt = getReturnType();
91  
92              if (rt.isInstance(value)) {
93                  invocationResults.addReturnValueResult(value);
94              } else {
95                  new ReturnTypeConversion(invocation, invocationResults, rt, value).addConvertedValue();
96              }
97          }
98      }
99  
100     @Nullable
101     Error verifyConstraints(@NonNull ExpectedInvocation replayInvocation, @NonNull Object[] replayArgs,
102             int minInvocations, int maxInvocations) {
103         Error error = verifyConstraints(minInvocations);
104 
105         if (error != null) {
106             return error;
107         }
108 
109         return constraints.verifyUpperLimit(replayInvocation, replayArgs, maxInvocations);
110     }
111 
112     @Nullable
113     Error verifyConstraints(int minInvocations) {
114         return constraints.verifyLowerLimit(invocation, minInvocations);
115     }
116 }