All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
mockit.internal.expectations.ReplayPhase Maven / Gradle / Ivy
/*
* Copyright (c) 2006 JMockit developers
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit.internal.expectations;
import java.util.*;
import javax.annotation.*;
import mockit.internal.expectations.invocation.*;
final class ReplayPhase extends Phase
{
@Nonnull final List invocations;
@Nonnull final List invocationInstances;
@Nonnull final List invocationArguments;
ReplayPhase(@Nonnull RecordAndReplayExecution recordAndReplay) {
super(recordAndReplay);
invocations = new ArrayList<>();
invocationInstances = new ArrayList<>();
invocationArguments = new ArrayList<>();
}
@Override @Nullable
Object handleInvocation(
@Nullable Object mock, int mockAccess, @Nonnull String mockClassDesc, @Nonnull String mockNameAndDesc,
@Nullable String genericSignature, boolean withRealImpl, @Nonnull Object[] args
) throws Throwable {
Expectation expectation = recordAndReplay.executionState.findExpectation(mock, mockClassDesc, mockNameAndDesc, args);
Object replacementInstance = mock == null ?
null : recordAndReplay.executionState.equivalentInstances.getReplacementInstanceForMethodInvocation(mock, mockNameAndDesc);
if (expectation == null) {
expectation = createExpectation(
replacementInstance == null ? mock : replacementInstance, mockAccess, mockClassDesc, mockNameAndDesc, genericSignature, args);
}
else if (expectation.recordPhase != null) {
registerNewInstanceAsEquivalentToOneFromRecordedConstructorInvocation(mock, expectation.invocation);
}
invocations.add(expectation);
invocationInstances.add(mock);
invocationArguments.add(args);
expectation.constraints.incrementInvocationCount();
if (withRealImpl && replacementInstance != null) {
return produceResult(expectation, replacementInstance, args);
}
return produceResult(expectation, mock, withRealImpl, args);
}
@Nonnull
private Expectation createExpectation(
@Nullable Object mock, int mockAccess, @Nonnull String mockClassDesc, @Nonnull String mockNameAndDesc,
@Nullable String genericSignature, @Nonnull Object[] args
) {
ExpectedInvocation invocation =
new ExpectedInvocation(mock, mockAccess, mockClassDesc, mockNameAndDesc, false, genericSignature, args);
Expectation expectation = new Expectation(invocation);
recordAndReplay.executionState.addExpectation(expectation);
return expectation;
}
private void registerNewInstanceAsEquivalentToOneFromRecordedConstructorInvocation(
@Nullable Object mock, @Nonnull ExpectedInvocation invocation
) {
if (mock != null && invocation.isConstructor()) {
Map instanceMap = getInstanceMap();
instanceMap.put(mock, invocation.instance);
}
}
@Nullable
private Object produceResult(
@Nonnull Expectation expectation, @Nonnull Object replacementInstance, @Nonnull Object[] args
) throws Throwable {
if (expectation.recordPhase == null) {
expectation.executedRealImplementation = true;
}
else if (expectation.constraints.isInvocationCountMoreThanMaximumExpected()) {
recordAndReplay.setErrorThrown(expectation.invocation.errorForUnexpectedInvocation(args));
return null;
}
return expectation.executeRealImplementation(replacementInstance, args);
}
@Nullable
private Object produceResult(
@Nonnull Expectation expectation, @Nullable Object mock, boolean withRealImpl, @Nonnull Object[] args
) throws Throwable {
boolean executeRealImpl = withRealImpl && expectation.recordPhase == null;
if (executeRealImpl) {
expectation.executedRealImplementation = true;
return Void.class;
}
if (expectation.constraints.isInvocationCountMoreThanMaximumExpected()) {
recordAndReplay.setErrorThrown(expectation.invocation.errorForUnexpectedInvocation(args));
return null;
}
return expectation.produceResult(mock, args);
}
@Nullable
private Object handleUnexpectedInvocation(
@Nullable Object mock, @Nonnull String mockClassDesc, @Nonnull String mockNameAndDesc, boolean withRealImpl,
@Nonnull Object[] replayArgs
) {
if (withRealImpl) {
return Void.class;
}
recordAndReplay.setErrorThrown(
new ExpectedInvocation(mock, mockClassDesc, mockNameAndDesc, replayArgs).errorForUnexpectedInvocation());
return null;
}
@Nullable
Error endExecution() {
Error missingInvocation = getErrorForFirstExpectationThatIsMissing();
return missingInvocation;
}
@Nullable
private Error getErrorForFirstExpectationThatIsMissing() {
List notStrictExpectations = recordAndReplay.executionState.expectations;
// New expectations might get added to the list, so a regular loop would cause a CME.
for (int i = 0, n = notStrictExpectations.size(); i < n; i++) {
Expectation notStrict = notStrictExpectations.get(i);
InvocationConstraints constraints = notStrict.constraints;
if (constraints.isInvocationCountLessThanMinimumExpected()) {
List nonMatchingInvocations = getNonMatchingInvocations(notStrict);
return constraints.errorForMissingExpectations(notStrict.invocation, nonMatchingInvocations);
}
}
return null;
}
@Nonnull
private List getNonMatchingInvocations(@Nonnull Expectation unsatisfiedExpectation) {
ExpectedInvocation unsatisfiedInvocation = unsatisfiedExpectation.invocation;
List nonMatchingInvocations = new ArrayList<>();
for (Expectation replayedExpectation : invocations) {
ExpectedInvocation replayedInvocation = replayedExpectation.invocation;
if (replayedExpectation != unsatisfiedExpectation && replayedInvocation.isMatch(unsatisfiedInvocation)) {
nonMatchingInvocations.add(replayedInvocation);
}
}
return nonMatchingInvocations;
}
}