diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/ArgumentMatchersRewriter.java b/src/main/java/org/openrewrite/java/testing/jmockit/ArgumentMatchersRewriter.java index 7d5efe007..8b24ee034 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/ArgumentMatchersRewriter.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/ArgumentMatchersRewriter.java @@ -60,6 +60,7 @@ class ArgumentMatchersRewriter { } private static final Map PRIMITIVE_TO_MOCKITO_ARGUMENT_MATCHER = new HashMap<>(); + static { PRIMITIVE_TO_MOCKITO_ARGUMENT_MATCHER.put(JavaType.Primitive.Int, "anyInt"); PRIMITIVE_TO_MOCKITO_ARGUMENT_MATCHER.put(JavaType.Primitive.Long, "anyLong"); @@ -81,7 +82,7 @@ class ArgumentMatchersRewriter { this.expectationsBlock = expectationsBlock; } - J.Block rewriteExpectationsBlock() { + J.Block rewriteJMockitBlock() { List newStatements = new ArrayList<>(expectationsBlock.getStatements().size()); for (Statement expectationStatement : expectationsBlock.getStatements()) { // for each statement, check if it's a method invocation and replace any argument matchers diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/ExpectationsBlockRewriter.java b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java similarity index 58% rename from src/main/java/org/openrewrite/java/testing/jmockit/ExpectationsBlockRewriter.java rename to src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java index ae2dce1ee..147bcdd50 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/ExpectationsBlockRewriter.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java @@ -15,6 +15,9 @@ */ package org.openrewrite.java.testing.jmockit; +import lombok.AccessLevel; +import lombok.Data; +import lombok.Setter; import org.openrewrite.Cursor; import org.openrewrite.ExecutionContext; import org.openrewrite.internal.lang.Nullable; @@ -26,13 +29,16 @@ import java.util.ArrayList; import java.util.List; -class ExpectationsBlockRewriter { +import static org.openrewrite.java.testing.jmockit.JMockitBlockType.Verifications; + +class JMockitBlockRewriter { private static final String WHEN_TEMPLATE_PREFIX = "when(#{any()})."; 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 String getObjectTemplateField(String fqn) { return "#{any(" + fqn + ")}"; @@ -41,167 +47,145 @@ private static String getObjectTemplateField(String fqn) { private final JavaVisitor visitor; private final ExecutionContext ctx; private final J.NewClass newExpectations; + private final JMockitBlockType blockType; // index of the Expectations block in the method body private final int bodyStatementIndex; private J.Block methodBody; private JavaCoordinates nextStatementCoordinates; - private boolean expectationsRewriteFailed = false; + private boolean rewriteFailed = false; - boolean isExpectationsRewriteFailed() { - return expectationsRewriteFailed; + 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; - ExpectationsBlockRewriter(JavaVisitor visitor, ExecutionContext ctx, J.Block methodBody, - J.NewClass newExpectations, int bodyStatementIndex) { + JMockitBlockRewriter(JavaVisitor visitor, ExecutionContext ctx, J.Block methodBody, + J.NewClass newExpectations, int bodyStatementIndex, JMockitBlockType blockType) { this.visitor = visitor; this.ctx = ctx; this.methodBody = methodBody; this.newExpectations = newExpectations; this.bodyStatementIndex = bodyStatementIndex; + this.blockType = blockType; nextStatementCoordinates = newExpectations.getCoordinates().replace(); } J.Block rewriteMethodBody() { - visitor.maybeRemoveImport("mockit.Expectations"); + visitor.maybeRemoveImport(blockType.getFqn()); // eg mockit.Expectations assert newExpectations.getBody() != null; - J.Block expectationsBlock = (J.Block) newExpectations.getBody().getStatements().get(0); - if (expectationsBlock.getStatements().isEmpty()) { + J.Block jmockitBlock = (J.Block) newExpectations.getBody().getStatements().get(0); + if (jmockitBlock.getStatements().isEmpty()) { // empty Expectations block, remove it - removeExpectationsStatement(); + removeBlock(); return methodBody; } // rewrite the argument matchers in the expectations block - ArgumentMatchersRewriter amr = new ArgumentMatchersRewriter(visitor, ctx, expectationsBlock); - expectationsBlock = amr.rewriteExpectationsBlock(); - - // iterate over the expectations statements and rebuild the method body - List expectationStatements = new ArrayList<>(); - for (Statement expectationStatement : expectationsBlock.getStatements()) { - if (expectationStatement instanceof J.MethodInvocation) { - // handle returns statements - J.MethodInvocation invocation = (J.MethodInvocation) expectationStatement; - if (invocation.getSelect() == null && invocation.getName().getSimpleName().equals("returns")) { - expectationStatements.add(expectationStatement); - continue; + 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<>(); + int methodInvocationIdx = -1; + for (Statement jmockitBlockStatement : jmockitBlock.getStatements()) { + if (jmockitBlockStatement instanceof J.MethodInvocation) { + // ensure it's not a returns statement, we add that later to related statements + J.MethodInvocation invocation = (J.MethodInvocation) jmockitBlockStatement; + if (invocation.getSelect() != null && !invocation.getName().getSimpleName().equals("returns")) { + methodInvocationIdx++; + methodInvocationsToRewrite.add(new ArrayList<>()); } - // if a new method invocation is found, apply the template to the previous statements - if (!expectationStatements.isEmpty()) { - // apply template to build new method body - rewriteMethodBody(expectationStatements); + } - // reset statements for next expectation - expectationStatements = new ArrayList<>(); - } + if (methodInvocationIdx != -1) { + methodInvocationsToRewrite.get(methodInvocationIdx).add(jmockitBlockStatement); } - expectationStatements.add(expectationStatement); } - // handle the last statement - if (!expectationStatements.isEmpty()) { - rewriteMethodBody(expectationStatements); + // remove the jmockit block + if (nextStatementCoordinates.isReplacement()) { + removeBlock(); } + // now rewrite + methodInvocationsToRewrite.forEach(this::rewriteMethodInvocation); return methodBody; } - private void rewriteMethodBody(List expectationStatements) { - final MockInvocationResults mockInvocationResults = buildMockInvocationResults(expectationStatements); - if (mockInvocationResults == null || !(expectationStatements.get(0) instanceof J.MethodInvocation)) { - // invalid Expectations block, cannot rewrite - expectationsRewriteFailed = true; + private void rewriteMethodInvocation(List statementsToRewrite) { + final MockInvocationResults mockInvocationResults = buildMockInvocationResults(statementsToRewrite); + if (mockInvocationResults == null) { + // invalid block, cannot rewrite + rewriteFailed = true; return; } - J.MethodInvocation invocation = (J.MethodInvocation) expectationStatements.get(0); - boolean hasExpectationsResults = !mockInvocationResults.getResults().isEmpty(); - if (hasExpectationsResults) { - // rewrite the statement to mockito if there are results - rewriteExpectationResult(mockInvocationResults.getResults(), invocation); - } else if (nextStatementCoordinates.isReplacement()) { - // if there are no results and the Expectations block is not yet replaced, remove it - removeExpectationsStatement(); + + J.MethodInvocation invocation = (J.MethodInvocation) statementsToRewrite.get(0); + boolean hasResults = !mockInvocationResults.getResults().isEmpty(); + if (hasResults) { + rewriteResult(invocation, mockInvocationResults.getResults()); } boolean hasTimes = false; if (mockInvocationResults.getTimes() != null) { hasTimes = true; - writeMethodVerification(invocation, mockInvocationResults.getTimes(), "times"); + rewriteVerify(invocation, mockInvocationResults.getTimes(), "times"); } if (mockInvocationResults.getMinTimes() != null) { hasTimes = true; - writeMethodVerification(invocation, mockInvocationResults.getMinTimes(), "atLeast"); + rewriteVerify(invocation, mockInvocationResults.getMinTimes(), "atLeast"); } if (mockInvocationResults.getMaxTimes() != null) { hasTimes = true; - writeMethodVerification(invocation, mockInvocationResults.getMaxTimes(), "atMost"); + rewriteVerify(invocation, mockInvocationResults.getMaxTimes(), "atMost"); } - if (!hasExpectationsResults && !hasTimes) { - writeMethodVerification(invocation, null, null); + if (!hasResults && !hasTimes) { + rewriteVerify(invocation, null, null); + } + } + + private void removeBlock() { + methodBody = JavaTemplate.builder("") + .javaParser(JavaParser.fromJavaVersion()) + .build() + .apply( + new Cursor(visitor.getCursor(), methodBody), + nextStatementCoordinates + ); + if (bodyStatementIndex == 0) { + nextStatementCoordinates = methodBody.getCoordinates().firstStatement(); + } else { + setNextCoordinatesAfterLastStatementAdded(0); } } - private void rewriteExpectationResult(List results, J.MethodInvocation invocation) { - String template = getMockitoStatementTemplate(results); + private void rewriteResult(J.MethodInvocation invocation, List results) { + String template = getWhenTemplate(results); if (template == null) { // invalid template, cannot rewrite - expectationsRewriteFailed = true; + rewriteFailed = true; return; } - visitor.maybeAddImport("org.mockito.Mockito", "when"); + visitor.maybeAddImport(MOCKITO_IMPORT_FQN_PREFX, "when"); List templateParams = new ArrayList<>(); templateParams.add(invocation); templateParams.addAll(results); - methodBody = JavaTemplate.builder(template) - .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "mockito-core-3.12")) - .staticImports("org.mockito.Mockito.*") - .build() - .apply( - new Cursor(visitor.getCursor(), methodBody), - nextStatementCoordinates, - templateParams.toArray() - ); - if (!nextStatementCoordinates.isReplacement()) { - numStatementsAdded += 1; - } - - // the next statement coordinates are directly after the most recently written statement - nextStatementCoordinates = methodBody.getStatements().get(bodyStatementIndex + numStatementsAdded) - .getCoordinates().after(); + methodBody = rewriteTemplate(template, templateParams, nextStatementCoordinates); + setNextCoordinatesAfterLastStatementAdded(++numStatementsAdded); } - private void removeExpectationsStatement() { - methodBody = JavaTemplate.builder("") - .javaParser(JavaParser.fromJavaVersion()) - .build() - .apply( - new Cursor(visitor.getCursor(), methodBody), - nextStatementCoordinates - ); - - // the next statement coordinates are directly after the most recently added statement, or the first statement - // of the test method body if the Expectations block was the first statement - nextStatementCoordinates = bodyStatementIndex == 0 ? methodBody.getCoordinates().firstStatement() : - methodBody.getStatements().get(bodyStatementIndex + numStatementsAdded).getCoordinates().after(); - } - - private void writeMethodVerification(J.MethodInvocation invocation, @Nullable Expression times, @Nullable String verificationMode) { - String fqn = getInvocationSelectFullyQualifiedClassName(invocation); - if (fqn == null) { + private void rewriteVerify(J.MethodInvocation invocation, @Nullable Expression times, @Nullable String verificationMode) { + if (invocation.getSelect() == null) { // cannot write a verification statement for an invocation without a select field return; } - visitor.maybeAddImport("org.mockito.Mockito", "verify"); - if (verificationMode != null) { - visitor.maybeAddImport("org.mockito.Mockito", verificationMode); - } List templateParams = new ArrayList<>(); templateParams.add(invocation.getSelect()); @@ -209,21 +193,56 @@ private void writeMethodVerification(J.MethodInvocation invocation, @Nullable Ex templateParams.add(times); } templateParams.add(invocation.getName().getSimpleName()); + String verifyTemplate = getVerifyTemplate(invocation.getArguments(), verificationMode, templateParams); - String verifyTemplate = getVerifyTemplate(invocation.getArguments(), fqn, verificationMode, templateParams); - methodBody = JavaTemplate.builder(verifyTemplate) + JavaCoordinates verifyCoordinates; + if (this.blockType == Verifications) { + // for Verifications, replace the Verifications block + verifyCoordinates = nextStatementCoordinates; + } else { + // for Expectations put the verify at the end of the method + verifyCoordinates = methodBody.getCoordinates().lastStatement(); + } + + methodBody = rewriteTemplate(verifyTemplate, templateParams, verifyCoordinates); + if (this.blockType == Verifications) { + setNextCoordinatesAfterLastStatementAdded(++numStatementsAdded); + } + + // do this last making sure rewrite worked and specify hasReference=false because in verify case it cannot find + // the static reference in AddImport class, and getSelect() returns not null + visitor.maybeAddImport(MOCKITO_IMPORT_FQN_PREFX, "verify", false); + if (verificationMode != null) { + visitor.maybeAddImport(MOCKITO_IMPORT_FQN_PREFX, verificationMode); + } + } + + private void setNextCoordinatesAfterLastStatementAdded(int numStatementsAdded) { + // the next statement coordinates are directly after the most recently written statement, calculated by + // subtracting the removed jmockit block + int nextStatementIdx = bodyStatementIndex + numStatementsAdded - 1; + if (nextStatementIdx >= this.methodBody.getStatements().size()) { + rewriteFailed = true; + } else { + this.nextStatementCoordinates = this.methodBody.getStatements().get(nextStatementIdx).getCoordinates().after(); + } + } + + private J.Block rewriteTemplate(String verifyTemplate, List templateParams, JavaCoordinates + rewriteCoords) { + JavaTemplate.Builder builder = JavaTemplate.builder(verifyTemplate) .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "mockito-core-3.12")) - .staticImports("org.mockito.Mockito.*") - .imports(fqn) + .staticImports("org.mockito.Mockito.*"); + return builder .build() .apply( new Cursor(visitor.getCursor(), methodBody), - methodBody.getCoordinates().lastStatement(), + rewriteCoords, templateParams.toArray() ); } - private static String getMockitoStatementTemplate(List results) { + private static @Nullable String getWhenTemplate(List results) { boolean buildingResults = false; final StringBuilder templateBuilder = new StringBuilder(WHEN_TEMPLATE_PREFIX); for (Expression result : results) { @@ -265,26 +284,27 @@ private static void appendToTemplate(StringBuilder templateBuilder, boolean buil templateBuilder.append(templateField); } - private static String getVerifyTemplate(List arguments, String fqn, @Nullable String verificationMode, List templateParams) { - StringBuilder templateBuilder = new StringBuilder("verify(#{any(" + fqn + ")}"); // verify(object + private static String getVerifyTemplate(List arguments, @Nullable String + verificationMode, List templateParams) { + StringBuilder templateBuilder = new StringBuilder("verify(#{any()}"); // eg verify(object if (verificationMode != null) { - templateBuilder.append(", ").append(verificationMode).append("(#{any(int)})"); // verify(object, times(2) + templateBuilder.append(", ").append(verificationMode).append("(#{any(int)})"); // eg verify(object, times(2) } - templateBuilder.append(").#{}("); // verify(object, times(2)).method( + templateBuilder.append(").#{}("); // eg verify(object, times(2)).method( if (arguments.isEmpty()) { - templateBuilder.append(");"); // verify(object, times(2)).method(); + templateBuilder.append(");"); // eg verify(object, times(2)).method(); <- no args return templateBuilder.toString(); } boolean hasArgument = false; - for (Expression argument : arguments) { // verify(object, times(2).method(anyLong(), any Int() + for (Expression argument : arguments) { // eg verify(object, times(2).method(anyLong(), anyInt() if (argument instanceof J.Empty) { continue; } else if (argument instanceof J.Literal) { templateBuilder.append(((J.Literal) argument).getValueSource()); } else { - templateBuilder.append("#{any()}"); + templateBuilder.append(ANY_TEMPLATE_FIELD); templateParams.add(argument); } hasArgument = true; @@ -293,11 +313,11 @@ private static String getVerifyTemplate(List arguments, String fqn, if (hasArgument) { templateBuilder.delete(templateBuilder.length() - 2, templateBuilder.length()); } - templateBuilder.append(");"); // verify(object, times(2).method(anyLong(), any Int()); + templateBuilder.append(");"); // eg verify(object, times(2).method(anyLong(), anyInt()); return templateBuilder.toString(); } - private static MockInvocationResults buildMockInvocationResults(List expectationStatements) { + private static @Nullable MockInvocationResults buildMockInvocationResults(List expectationStatements) { final MockInvocationResults resultWrapper = new MockInvocationResults(); for (int i = 1; i < expectationStatements.size(); i++) { Statement expectationStatement = expectationStatements.get(i); @@ -333,20 +353,19 @@ private static MockInvocationResults buildMockInvocationResults(List return resultWrapper; } - private static String getVariableNameFromAssignment(J.Assignment assignment) { - String name = null; + private static @Nullable String getVariableNameFromAssignment(J.Assignment assignment) { if (assignment.getVariable() instanceof J.Identifier) { - name = ((J.Identifier) assignment.getVariable()).getSimpleName(); + return ((J.Identifier) assignment.getVariable()).getSimpleName(); } else if (assignment.getVariable() instanceof J.FieldAccess) { J.FieldAccess fieldAccess = (J.FieldAccess) assignment.getVariable(); if (fieldAccess.getTarget() instanceof J.Identifier) { - name = fieldAccess.getSimpleName(); + return fieldAccess.getSimpleName(); } } - return name; + return null; } - private static String getPrimitiveTemplateField(JavaType.Primitive primitiveType) { + private static @Nullable String getPrimitiveTemplateField(JavaType.Primitive primitiveType) { switch (primitiveType) { case Boolean: return "#{any(boolean)}"; @@ -373,54 +392,16 @@ private static String getPrimitiveTemplateField(JavaType.Primitive primitiveType } } - private static String getInvocationSelectFullyQualifiedClassName(J.MethodInvocation invocation) { - Expression select = invocation.getSelect(); - if (select == null || select.getType() == null) { - return null; - } - String fqn = null; - if (select.getType() instanceof JavaType.FullyQualified) { - fqn = ((JavaType.FullyQualified) select.getType()).getFullyQualifiedName(); - } - return fqn; - } - + @Data private static class MockInvocationResults { + @Setter(AccessLevel.NONE) private final List results = new ArrayList<>(); private Expression times; private Expression minTimes; private Expression maxTimes; - private List getResults() { - return results; - } - private void addResult(Expression result) { results.add(result); } - - private Expression getTimes() { - return times; - } - - private void setTimes(Expression times) { - this.times = times; - } - - private Expression getMinTimes() { - return minTimes; - } - - private void setMinTimes(Expression minTimes) { - this.minTimes = minTimes; - } - - private Expression getMaxTimes() { - return maxTimes; - } - - private void setMaxTimes(Expression maxTimes) { - this.maxTimes = maxTimes; - } } } diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitExpectationsToMockito.java b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockToMockito.java similarity index 62% rename from src/main/java/org/openrewrite/java/testing/jmockit/JMockitExpectationsToMockito.java rename to src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockToMockito.java index e841aa033..4283eedf5 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitExpectationsToMockito.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockToMockito.java @@ -27,27 +27,31 @@ import org.openrewrite.java.tree.Statement; import java.util.List; +import java.util.Optional; @Value @EqualsAndHashCode(callSuper = false) -public class JMockitExpectationsToMockito extends Recipe { +public class JMockitBlockToMockito extends Recipe { + @Override public String getDisplayName() { - return "Rewrite JMockit Expectations"; + return "Rewrite JMockit Expectations and Verifications"; } @Override public String getDescription() { - return "Rewrites JMockit `Expectations` blocks to Mockito statements."; + return "Rewrites JMockit `Expectations and Verifications` blocks to Mockito statements."; } @Override public TreeVisitor getVisitor() { - return Preconditions.check(new UsesType<>("mockit.Expectations", false), - new RewriteExpectationsVisitor()); + return Preconditions.check(Preconditions.or( + new UsesType<>(JMockitBlockType.Expectations.getFqn(), false), + new UsesType<>(JMockitBlockType.Verifications.getFqn(), false) + ), new RewriteJMockitBlockVisitor()); } - private static class RewriteExpectationsVisitor extends JavaIsoVisitor { + private static class RewriteJMockitBlockVisitor extends JavaIsoVisitor { @Override public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration methodDeclaration, ExecutionContext ctx) { @@ -63,17 +67,19 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration methodDecl int bodyStatementIndex = 0; // iterate over each statement in the method body, find Expectations blocks and rewrite them while (bodyStatementIndex < statements.size()) { - if (!JMockitUtils.isValidExpectationsNewClassStatement(statements.get(bodyStatementIndex))) { - bodyStatementIndex += 1; - continue; - } - ExpectationsBlockRewriter ebr = new ExpectationsBlockRewriter(this, ctx, methodBody, - ((J.NewClass) statements.get(bodyStatementIndex)), bodyStatementIndex); - methodBody = ebr.rewriteMethodBody(); - statements = methodBody.getStatements(); - // if the expectations rewrite failed, skip the next statement - if (ebr.isExpectationsRewriteFailed()) { - bodyStatementIndex += 1; + Statement s = statements.get(bodyStatementIndex); + Optional blockType = JMockitUtils.getJMockitBlock(s); + if (blockType.isPresent()) { + JMockitBlockRewriter blockRewriter = new JMockitBlockRewriter(this, ctx, methodBody, + ((J.NewClass) s), bodyStatementIndex, blockType.get()); + methodBody = blockRewriter.rewriteMethodBody(); + statements = methodBody.getStatements(); + // if the expectations rewrite failed, skip the next statement + if (blockRewriter.isRewriteFailed()) { + bodyStatementIndex++; + } + } else { + bodyStatementIndex++; } } return md.withBody(methodBody); diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java new file mode 100644 index 000000000..e649448a0 --- /dev/null +++ b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java @@ -0,0 +1,29 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +enum JMockitBlockType { + + Expectations("mockit.Expectations"), + Verifications("mockit.Verifications"); // Add NonStrictExpectations later + + private final String fqn; +} diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitUtils.java b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitUtils.java index 79d21e91c..a11b5246b 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitUtils.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitUtils.java @@ -19,20 +19,32 @@ import org.openrewrite.java.tree.Statement; import org.openrewrite.java.tree.TypeUtils; +import java.util.Optional; + +import static java.util.Optional.empty; + class JMockitUtils { - static boolean isValidExpectationsNewClassStatement(Statement s) { + + static Optional getJMockitBlock(Statement s) { if (!(s instanceof J.NewClass)) { - return false; + return empty(); } J.NewClass nc = (J.NewClass) s; if (!(nc.getClazz() instanceof J.Identifier)) { - return false; + return empty(); } J.Identifier clazz = (J.Identifier) nc.getClazz(); - if (!TypeUtils.isAssignableTo("mockit.Expectations", clazz.getType())) { - return false; + + // JMockit block should be composed of a block within another block + if (nc.getBody() == null || nc.getBody().getStatements().size() != 1) { + return empty(); + } + + for (JMockitBlockType blockType : JMockitBlockType.values()) { + if (TypeUtils.isAssignableTo(blockType.getFqn(), clazz.getType())) { + return Optional.of(blockType); + } } - // Expectations block should be composed of a block within another block - return nc.getBody() != null && nc.getBody().getStatements().size() == 1; + return empty(); } } diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/SetupStatementsRewriter.java b/src/main/java/org/openrewrite/java/testing/jmockit/SetupStatementsRewriter.java index 4fd9a54f2..fbbc1add3 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/SetupStatementsRewriter.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/SetupStatementsRewriter.java @@ -36,9 +36,9 @@ class SetupStatementsRewriter { J.Block rewriteMethodBody() { List statements = methodBody.getStatements(); - // iterate over each statement in the method body, find Expectations blocks and rewrite them + // iterate over each statement in the method body, find JMockit blocks and rewrite them for (Statement s : statements) { - if (!JMockitUtils.isValidExpectationsNewClassStatement(s)) { + if (!JMockitUtils.getJMockitBlock(s).isPresent()) { continue; } J.NewClass nc = (J.NewClass) s; diff --git a/src/main/resources/META-INF/rewrite/jmockit.yml b/src/main/resources/META-INF/rewrite/jmockit.yml index 1b4651ae2..4178ebcd4 100644 --- a/src/main/resources/META-INF/rewrite/jmockit.yml +++ b/src/main/resources/META-INF/rewrite/jmockit.yml @@ -22,7 +22,7 @@ tags: - testing - jmockit recipeList: - - org.openrewrite.java.testing.jmockit.JMockitExpectationsToMockito + - org.openrewrite.java.testing.jmockit.JMockitBlockToMockito - org.openrewrite.java.testing.jmockit.JMockitAnnotatedArgumentToMockito - org.openrewrite.java.ChangeType: oldFullyQualifiedTypeName: mockit.Mocked diff --git a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitExpectationsToMockitoTest.java b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitExpectationsToMockitoTest.java index 69f4627fe..54d26e64c 100644 --- a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitExpectationsToMockitoTest.java +++ b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitExpectationsToMockitoTest.java @@ -71,7 +71,7 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) @@ -118,7 +118,7 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.mockito.Mockito.verify; @ExtendWith(MockitoExtension.class) @@ -155,7 +155,7 @@ public String getSomeField() { import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + import static org.junit.jupiter.api.Assertions.assertNull; @ExtendWith(JMockitExtension.class) @@ -176,7 +176,7 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.Mockito.when; @@ -214,14 +214,14 @@ public int getSomeField() { import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + import static org.junit.jupiter.api.Assertions.assertEquals; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked MyObject myObject; - + void test() { new Expectations() {{ myObject.getSomeField(); @@ -240,7 +240,7 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.when; @@ -280,14 +280,14 @@ public String getSomeField(String s) { import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + import static org.junit.jupiter.api.Assertions.assertEquals; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked MyObject myObject; - + void test() { new Expectations() {{ myObject.getSomeField(anyString); @@ -301,7 +301,7 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.when; @@ -340,16 +340,16 @@ public String getSomeField() { import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + import static org.junit.jupiter.api.Assertions.assertEquals; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked MyObject myObject; - + String expected = "expected"; - + void test() { new Expectations() {{ myObject.getSomeField(); @@ -363,17 +363,17 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.when; - + @ExtendWith(MockitoExtension.class) class MyTest { @Mock MyObject myObject; - + String expected = "expected"; - + void test() { when(myObject.getSomeField()).thenReturn(expected); assertEquals(expected, myObject.getSomeField()); @@ -403,14 +403,14 @@ public Object getSomeField() { import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + import static org.junit.jupiter.api.Assertions.assertNotNull; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked MyObject myObject; - + void test() { new Expectations() {{ myObject.getSomeField(); @@ -424,7 +424,7 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.Mockito.when; @@ -518,7 +518,7 @@ public String getSomeField() { import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + import static org.junit.jupiter.api.Assertions.assertEquals; @ExtendWith(JMockitExtension.class) @@ -567,7 +567,7 @@ void whenClassArgumentMatcher() { java( """ import java.util.List; - + class MyObject { public String getSomeField(List input) { return "X"; @@ -582,19 +582,19 @@ public String getSomeOtherField(Object input) { """ import java.util.ArrayList; import java.util.List; - + import mockit.Expectations; import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + import static org.junit.jupiter.api.Assertions.assertNull; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked MyObject myObject; - + void test() { new Expectations() {{ myObject.getSomeField((List) any); @@ -610,19 +610,19 @@ void test() { """ import java.util.ArrayList; import java.util.List; - + import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.Mockito.*; - + @ExtendWith(MockitoExtension.class) class MyTest { @Mock MyObject myObject; - + void test() { when(myObject.getSomeField(anyList())).thenReturn(null); when(myObject.getSomeOtherField(any(Object.class))).thenReturn(null); @@ -642,7 +642,7 @@ void whenNoArguments() { java( """ import java.util.List; - + class MyObject { public String getSomeField() { return "X"; @@ -654,19 +654,19 @@ public String getSomeField() { """ import java.util.ArrayList; import java.util.List; - + import mockit.Expectations; import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + import static org.junit.jupiter.api.Assertions.assertNull; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked MyObject myObject; - + void test() { new Expectations() {{ myObject.getSomeField(); @@ -679,19 +679,19 @@ void test() { """ import java.util.ArrayList; import java.util.List; - + import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.Mockito.when; - + @ExtendWith(MockitoExtension.class) class MyTest { @Mock MyObject myObject; - + void test() { when(myObject.getSomeField()).thenReturn(null); assertNull(myObject.getSomeField()); @@ -709,7 +709,7 @@ void whenMixedArgumentMatcher() { java( """ import java.util.List; - + class MyObject { public String getSomeField(String s, String s2, String s3, long l1) { return "X"; @@ -721,19 +721,19 @@ public String getSomeField(String s, String s2, String s3, long l1) { """ import java.util.ArrayList; import java.util.List; - + import mockit.Expectations; import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + import static org.junit.jupiter.api.Assertions.assertNull; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked MyObject myObject; - + void test() { String bazz = "bazz"; new Expectations() {{ @@ -747,19 +747,19 @@ void test() { """ import java.util.ArrayList; import java.util.List; - + import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.Mockito.*; - + @ExtendWith(MockitoExtension.class) class MyTest { @Mock MyObject myObject; - + void test() { String bazz = "bazz"; when(myObject.getSomeField(eq("foo"), anyString(), eq(bazz), eq(10L))).thenReturn(null); @@ -778,7 +778,7 @@ void whenSetupStatements() { java( """ class MyObject { - + public String getSomeField(String s) { return "X"; } @@ -794,26 +794,26 @@ public String getString() { import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + import static org.junit.jupiter.api.Assertions.assertEquals; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked MyObject myObject; - + void test() { String a = "a"; String s = "s"; - + new Expectations() {{ myObject.getSomeField(anyString); result = s; - + myObject.getString(); result = a; }}; - + assertEquals("s", myObject.getSomeField("foo")); assertEquals("a", myObject.getString()); } @@ -823,7 +823,7 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.when; @@ -836,11 +836,9 @@ class MyTest { void test() { String a = "a"; String s = "s"; - when(myObject.getSomeField(anyString())).thenReturn(s); - when(myObject.getString()).thenReturn(a); - + assertEquals("s", myObject.getSomeField("foo")); assertEquals("a", myObject.getString()); } @@ -869,14 +867,14 @@ public String getSomeField(String s) { import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + import static org.junit.jupiter.api.Assertions.assertEquals; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked MyObject myObject; - + void test() { String a = "a"; new Expectations() {{ @@ -885,7 +883,7 @@ void test() { String b = "b"; result = s; }}; - + assertEquals("s", myObject.getSomeField("foo")); } } @@ -894,7 +892,7 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.when; @@ -909,7 +907,7 @@ void test() { String s = "s"; String b = "b"; when(myObject.getSomeField(anyString())).thenReturn(s); - + assertEquals("s", myObject.getSomeField("foo")); } } @@ -928,19 +926,20 @@ void whenTimes() { import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked Object myObject; - + void test() { new Expectations() {{ myObject.wait(anyLong, anyInt); - times = 2; + times = 3; }}; myObject.wait(10L, 10); myObject.wait(10L, 10); + myObject.wait(10L, 10); } } """, @@ -948,18 +947,19 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.mockito.Mockito.*; - + @ExtendWith(MockitoExtension.class) class MyTest { @Mock Object myObject; - + void test() { myObject.wait(10L, 10); myObject.wait(10L, 10); - verify(myObject, times(2)).wait(anyLong(), anyInt()); + myObject.wait(10L, 10); + verify(myObject, times(3)).wait(anyLong(), anyInt()); } } """ @@ -972,12 +972,12 @@ void whenMinTimes() { //language=java rewriteRun( java( - """ + """ import mockit.Expectations; import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked @@ -996,9 +996,9 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.mockito.Mockito.*; - + @ExtendWith(MockitoExtension.class) class MyTest { @Mock @@ -1019,12 +1019,12 @@ void whenMaxTimes() { //language=java rewriteRun( java( - """ + """ import mockit.Expectations; import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked @@ -1043,9 +1043,9 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.mockito.Mockito.*; - + @ExtendWith(MockitoExtension.class) class MyTest { @Mock @@ -1066,12 +1066,12 @@ void whenMinTimesMaxTimes() { //language=java rewriteRun( java( - """ + """ import mockit.Expectations; import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked @@ -1091,9 +1091,9 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.mockito.Mockito.*; - + @ExtendWith(MockitoExtension.class) class MyTest { @Mock @@ -1129,14 +1129,14 @@ public String getSomeField() { import mockit.Tested; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + import static org.junit.jupiter.api.Assertions.assertEquals; - + @ExtendWith(JMockitExtension.class) class MyTest { @Tested MyObject myObject; - + void test() { new Expectations(myObject) {{ myObject.getSomeField(); @@ -1150,15 +1150,15 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.when; - + @ExtendWith(MockitoExtension.class) class MyTest { @InjectMocks MyObject myObject; - + void test() { when(myObject.getSomeField()).thenReturn("foo"); assertEquals("foo", myObject.getSomeField()); @@ -1195,18 +1195,18 @@ public void doSomething() {} import mockit.Mocked; import mockit.integration.junit5.JMockitExtension; import org.junit.jupiter.api.extension.ExtendWith; - + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; - + @ExtendWith(JMockitExtension.class) class MyTest { @Mocked Object myObject; - + @Mocked MyObject myOtherObject; - + void test() { new Expectations() {{ myObject.hashCode(); @@ -1256,4 +1256,130 @@ void test() { ) ); } + + @Test + void whenMultipleExpectations() { + //language=java + rewriteRun( + java( + """ + class MyObject { + public String getSomeStringField() { + return "X"; + } + } + """ + ), + java( + """ + import mockit.Expectations; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + import static org.junit.jupiter.api.Assertions.assertEquals; + import static org.junit.jupiter.api.Assertions.assertNull; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + MyObject myObject; + + void test() { + new Expectations() {{ + myObject.getSomeStringField(); + result = "a"; + }}; + assertEquals("a", myObject.getSomeStringField()); + new Expectations() {{ + myObject.getSomeStringField(); + result = "b"; + }}; + assertEquals("b", myObject.getSomeStringField()); + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.junit.jupiter.api.Assertions.assertEquals; + import static org.junit.jupiter.api.Assertions.assertNull; + import static org.mockito.Mockito.when; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + MyObject myObject; + + void test() { + when(myObject.getSomeStringField()).thenReturn("a"); + assertEquals("a", myObject.getSomeStringField()); + when(myObject.getSomeStringField()).thenReturn("b"); + assertEquals("b", myObject.getSomeStringField()); + } + } + """ + ) + ); + } + + @Test + void whenMultipleExpectationsNoResults() { + //language=java + rewriteRun( + java( + """ + import mockit.Expectations; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + import static org.junit.jupiter.api.Assertions.assertEquals; + import static org.junit.jupiter.api.Assertions.assertNull; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + new Expectations() {{ + myObject.wait(anyLong); + }}; + myObject.wait(1L); + new Expectations() {{ + myObject.wait(); + }}; + myObject.wait(); + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.junit.jupiter.api.Assertions.assertEquals; + import static org.junit.jupiter.api.Assertions.assertNull; + import static org.mockito.Mockito.anyLong; + import static org.mockito.Mockito.verify; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + myObject.wait(1L); + myObject.wait(); + verify(myObject).wait(anyLong()); + verify(myObject).wait(); + } + } + """ + ) + ); + } } diff --git a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitVerificationsToMockitoTest.java b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitVerificationsToMockitoTest.java new file mode 100644 index 000000000..23022dcb5 --- /dev/null +++ b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitVerificationsToMockitoTest.java @@ -0,0 +1,740 @@ +/* + * Copyright 2023 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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 org.junit.jupiter.api.Test; +import org.openrewrite.DocumentExample; +import org.openrewrite.InMemoryExecutionContext; +import org.openrewrite.java.JavaParser; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; +import org.openrewrite.test.TypeValidation; + +import static org.openrewrite.java.Assertions.java; + +class JMockitVerificationsToMockitoTest implements RewriteTest { + @Override + public void defaults(RecipeSpec spec) { + spec + .parser(JavaParser.fromJavaVersion() + .logCompilationWarningsAndErrors(true) + .classpathFromResources(new InMemoryExecutionContext(), + "junit-jupiter-api-5.9", + "jmockit-1.49", + "mockito-core-3.12", + "mockito-junit-jupiter-3.12" + )) + .recipeFromResource( + "/META-INF/rewrite/jmockit.yml", + "org.openrewrite.java.testing.jmockit.JMockitToMockito" + ); + } + + @DocumentExample + @Test + void whenNoTimes() { + //language=java + rewriteRun( + java( + """ + import mockit.Verifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + myObject.wait(10L, 10); + new Verifications() {{ + myObject.wait(anyLong, anyInt); + }}; + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.*; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + myObject.wait(10L, 10); + verify(myObject).wait(anyLong(), anyInt()); + } + } + """ + ) + ); + } + + @DocumentExample + @Test + void whenNoTimesNoArgs() { + //language=java + rewriteRun( + java( + """ + import mockit.Verifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + myObject.wait(10L, 10); + new Verifications() {{ + myObject.wait(); + }}; + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.verify; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + myObject.wait(10L, 10); + verify(myObject).wait(); + } + } + """ + ) + ); + } + + + @Test + void whenTimesNoArgs() { + //language=java + rewriteRun( + java( + """ + import java.util.ArrayList; + import java.util.List; + + import mockit.Verifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + myObject.wait(); + myObject.wait(); + new Verifications() {{ + myObject.wait(); + times = 2; + }}; + } + } + """, + """ + import java.util.ArrayList; + import java.util.List; + + import static org.mockito.Mockito.times; + import static org.mockito.Mockito.verify; + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + myObject.wait(); + myObject.wait(); + verify(myObject, times(2)).wait(); + } + } + """ + ) + ); + } + + @Test + void whenClassArgumentMatcher() { + //language=java + rewriteRun( + spec -> spec.afterTypeValidationOptions(TypeValidation.builder().methodInvocations(false).build()), + java( + """ + import java.util.List; + + class MyObject { + public String getSomeField(List input) { + return "X"; + } + public String getSomeOtherField(Object input) { + return "Y"; + } + } + """ + ), + java( + """ + import java.util.ArrayList; + import java.util.List; + + import mockit.Mocked; + import mockit.Verifications; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + MyObject myObject; + + void test() { + myObject.getSomeField(new ArrayList<>()); + myObject.getSomeOtherField(new Object()); + new Verifications() {{ + myObject.getSomeField((List) any); + myObject.getSomeOtherField((Object) any); + }}; + } + } + """, + """ + import java.util.ArrayList; + import java.util.List; + + import static org.mockito.Mockito.*; + + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + MyObject myObject; + + void test() { + myObject.getSomeField(new ArrayList<>()); + myObject.getSomeOtherField(new Object()); + verify(myObject).getSomeField(anyList()); + verify(myObject).getSomeOtherField(any(Object.class)); + } + } + """ + ) + ); + } + + + @Test + void whenMixedArgumentMatcher() { + //language=java + rewriteRun( + java( + """ + import java.util.ArrayList; + import java.util.List; + + import mockit.Verifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + myObject.wait(10L, 10); + new Verifications() {{ + myObject.wait(anyLong, 10); + }}; + } + } + """, + """ + import java.util.ArrayList; + import java.util.List; + + import static org.mockito.Mockito.*; + + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + myObject.wait(10L, 10); + verify(myObject).wait(anyLong(), eq(10)); + } + } + """ + ) + ); + } + + @Test + void whenSetupStatements() { + //language=java + rewriteRun( + java( + """ + import mockit.Verifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + String a = "a"; + String s = "s"; + myObject.wait(1L); + myObject.wait(); + new Verifications() {{ + myObject.wait(anyLong); + myObject.wait(); + }}; + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.anyLong; + import static org.mockito.Mockito.verify; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + String a = "a"; + String s = "s"; + myObject.wait(1L); + myObject.wait(); + verify(myObject).wait(anyLong()); + verify(myObject).wait(); + } + } + """ + ) + ); + } + + @Test + void whenSetupStatements2() { + //language=java + rewriteRun( + java( + """ + import mockit.Verifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + String a = "a"; + myObject.wait(1L); + new Verifications() {{ + myObject.wait(anyLong); + }}; + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.anyLong; + import static org.mockito.Mockito.verify; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + String a = "a"; + myObject.wait(1L); + verify(myObject).wait(anyLong()); + } + } + """ + ) + ); + } + + @Test + void whenTimes() { + //language=java + rewriteRun( + java( + """ + import mockit.Verifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + myObject.wait(10L, 10); + myObject.wait(10L, 10); + myObject.wait(10L, 10); + new Verifications() {{ + myObject.wait(anyLong, anyInt); + times = 3; + }}; + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.*; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + myObject.wait(10L, 10); + myObject.wait(10L, 10); + myObject.wait(10L, 10); + verify(myObject, times(3)).wait(anyLong(), anyInt()); + } + } + """ + ) + ); + } + + @Test + void whenMinTimes() { + //language=java + rewriteRun( + java( + """ + import mockit.Verifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + myObject.wait(10L, 10); + new Verifications() {{ + myObject.wait(anyLong, anyInt); + minTimes = 2; + }}; + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.*; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + myObject.wait(10L, 10); + verify(myObject, atLeast(2)).wait(anyLong(), anyInt()); + } + } + """ + ) + ); + } + + @Test + void whenMaxTimes() { + //language=java + rewriteRun( + java( + """ + import mockit.Verifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + myObject.wait(10L, 10); + new Verifications() {{ + myObject.wait(anyLong, anyInt); + maxTimes = 5; + }}; + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.*; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + myObject.wait(10L, 10); + verify(myObject, atMost(5)).wait(anyLong(), anyInt()); + } + } + """ + ) + ); + } + + @Test + void whenMinTimesMaxTimes() { + //language=java + rewriteRun( + java( + """ + import mockit.Verifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + myObject.wait(10L, 10); + new Verifications() {{ + myObject.wait(anyLong, anyInt); + minTimes = 1; + maxTimes = 3; + }}; + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.*; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + myObject.wait(10L, 10); + verify(myObject, atLeast(1)).wait(anyLong(), anyInt()); + verify(myObject, atMost(3)).wait(anyLong(), anyInt()); + } + } + """ + ) + ); + } + + @Test + void whenMultipleStatements() { + //language=java + rewriteRun( + java( + """ + import mockit.Verifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + @Mocked + Object myOtherObject; + + void test() { + myObject.hashCode(); + myOtherObject.wait(); + myObject.wait(10L, 10); + myOtherObject.wait(10L); + new Verifications() {{ + myObject.hashCode(); + myOtherObject.wait(); + myObject.wait(anyLong, anyInt); + myOtherObject.wait(anyLong); + }}; + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.*; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + @Mock + Object myOtherObject; + + void test() { + myObject.hashCode(); + myOtherObject.wait(); + myObject.wait(10L, 10); + myOtherObject.wait(10L); + verify(myObject).hashCode(); + verify(myOtherObject).wait(); + verify(myObject).wait(anyLong(), anyInt()); + verify(myOtherObject).wait(anyLong()); + } + } + """ + ) + ); + } + + @Test + void whenMultipleVerificationsAndMultipleStatements() { + //language=java + rewriteRun( + java( + """ + import mockit.Verifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + myObject.wait(); + new Verifications() {{ + + myObject.wait(); + + myObject.wait(anyLong, anyInt); + }}; + myObject.wait(1L); + myObject.wait(2L); + new Verifications() {{ + myObject.wait(anyLong); + times = 2; + }}; + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.*; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + myObject.wait(); + verify(myObject).wait(); + verify(myObject).wait(anyLong(), anyInt()); + myObject.wait(1L); + myObject.wait(2L); + verify(myObject, times(2)).wait(anyLong()); + } + } + """ + ) + ); + } +}