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.
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Moderne Source Available License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite.java.testing.jmockit;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;
import org.jspecify.annotations.Nullable;
import org.openrewrite.Cursor;
import org.openrewrite.ExecutionContext;
import org.openrewrite.java.JavaParser;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.JavaVisitor;
import org.openrewrite.java.tree.*;
import java.util.ArrayList;
import java.util.List;
import static org.openrewrite.java.testing.jmockit.JMockitBlockType.*;
import static org.openrewrite.java.testing.jmockit.JMockitUtils.MOCKITO_ALL_IMPORT;
import static org.openrewrite.java.testing.jmockit.JMockitUtils.getJavaParser;
class JMockitBlockRewriter {
private static final String WHEN_TEMPLATE_PREFIX = "when(#{any()}).";
private static final String VERIFY_TEMPLATE_PREFIX = "verify(#{any()}";
private static final String VERIFY_NO_INTERACTIONS_TEMPLATE_PREFIX = "verifyNoMoreInteractions(";
private static final String VERIFY_IN_ORDER_TEMPLATE_PREFIX_1 = "InOrder inOrder";
private static final String VERIFY_IN_ORDER_TEMPLATE_PREFIX_2 = " = inOrder(";
private static final String LENIENT_TEMPLATE_PREFIX = "lenient().";
private static final String RETURN_TEMPLATE_PREFIX = "thenReturn(";
private static final String THROW_TEMPLATE_PREFIX = "thenThrow(";
private static final String LITERAL_TEMPLATE_FIELD = "#{}";
private static final String ANY_TEMPLATE_FIELD = "#{any()}";
private static final String MOCKITO_IMPORT_FQN_PREFX = "org.mockito.Mockito";
private static final String IN_ORDER_IMPORT_FQN = "org.mockito.InOrder";
private static String getObjectTemplateField(String fqn) {
return "#{any(" + fqn + ")}";
}
private final JavaVisitor visitor;
private final ExecutionContext ctx;
private final J.NewClass newExpectations;
private final JMockitBlockType blockType;
private final int verificationsInOrderIdx;
// index of the Expectations block in the method body
private final int bodyStatementIndex;
private J.Block methodBody;
private JavaCoordinates nextStatementCoordinates;
private boolean rewriteFailed = false;
boolean isRewriteFailed() {
return rewriteFailed;
}
// keep track of the additional statements being added to the method body, which impacts the statement indices
// used with bodyStatementIndex to obtain the coordinates of the next statement to be written
private int numStatementsAdded = 0;
JMockitBlockRewriter(JavaVisitor visitor, ExecutionContext ctx, J.Block methodBody,
J.NewClass newExpectations, int bodyStatementIndex, JMockitBlockType blockType, int verificationsInOrderIdx) {
this.visitor = visitor;
this.ctx = ctx;
this.methodBody = methodBody;
this.newExpectations = newExpectations;
this.bodyStatementIndex = bodyStatementIndex;
this.blockType = blockType;
this.verificationsInOrderIdx = verificationsInOrderIdx;
this.nextStatementCoordinates = newExpectations.getCoordinates().replace();
}
J.Block rewriteMethodBody() {
visitor.maybeRemoveImport(blockType.getFqn()); // eg mockit.Expectations
assert newExpectations.getBody() != null;
J.Block jmockitBlock = (J.Block) newExpectations.getBody().getStatements().get(0);
if (jmockitBlock.getStatements().isEmpty()) {
// empty Expectations block, remove it
removeBlock();
return methodBody;
}
// rewrite the argument matchers in the expectations block
ArgumentMatchersRewriter amr = new ArgumentMatchersRewriter(visitor, ctx, jmockitBlock);
jmockitBlock = amr.rewriteJMockitBlock();
// iterate over the statements and build a list of grouped method invocations and related statements eg times
List> methodInvocationsToRewrite = new ArrayList<>();
List uniqueMocks = new ArrayList<>();
int methodInvocationIdx = -1;
for (Statement jmockitBlockStatement : jmockitBlock.getStatements()) {
if (jmockitBlockStatement instanceof J.MethodInvocation) {
J.MethodInvocation invocation = (J.MethodInvocation) jmockitBlockStatement;
Expression select = invocation.getSelect();
if (select instanceof J.Identifier) {
J.Identifier mockObj = (J.Identifier) select;
// ensure it's not a returns statement, we add that later to related statements
if (!invocation.getName().getSimpleName().equals("returns")) {
methodInvocationIdx++;
methodInvocationsToRewrite.add(new ArrayList<>());
}
if ((isFullVerifications() || isVerificationsInOrder()) &&
uniqueMocks.stream().noneMatch(mock -> mock.getSimpleName().equals(mockObj.getSimpleName()))) {
uniqueMocks.add(mockObj);
}
}
}
// add the statements corresponding to the method invocation
if (methodInvocationIdx != -1) {
methodInvocationsToRewrite.get(methodInvocationIdx).add(jmockitBlockStatement);
}
}
// remove the jmockit block
if (nextStatementCoordinates.isReplacement()) {
removeBlock();
}
List