Skip to content

Commit 6e9cdeb

Browse files
authored
Changed AnyToNullable from declarative to imperative so that it can have a precondition on the project using mockito 1.x (#378)
closes #377
1 parent d409434 commit 6e9cdeb

File tree

4 files changed

+134
-39
lines changed

4 files changed

+134
-39
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.openrewrite.java.testing.mockito;
17+
18+
import org.openrewrite.*;
19+
import org.openrewrite.internal.lang.Nullable;
20+
import org.openrewrite.java.ChangeMethodName;
21+
import org.openrewrite.java.ChangeMethodTargetToStatic;
22+
import org.openrewrite.java.tree.J;
23+
import org.openrewrite.xml.tree.Xml;
24+
25+
import java.util.concurrent.atomic.AtomicBoolean;
26+
27+
public class AnyToNullable extends ScanningRecipe<AtomicBoolean> {
28+
@Override
29+
public String getDisplayName() {
30+
return "Replace Mockito 1.x `anyString()`/`any()` with `nullable(Class)`";
31+
}
32+
33+
@Override
34+
public String getDescription() {
35+
return "Since Mockito 2.10 `anyString()` and `any()` no longer matches null values. Use `nullable(Class)` instead.";
36+
}
37+
38+
@Override
39+
public AtomicBoolean getInitialValue(ExecutionContext ctx) {
40+
return new AtomicBoolean();
41+
}
42+
43+
@Override
44+
public TreeVisitor<?, ExecutionContext> getScanner(AtomicBoolean acc) {
45+
org.openrewrite.maven.search.FindDependency mavenFindDependency =
46+
new org.openrewrite.maven.search.FindDependency("org.mockito", "mockito-all");
47+
org.openrewrite.gradle.search.FindDependency gradleFindDependency =
48+
new org.openrewrite.gradle.search.FindDependency("org.mockito", "mockito-all", null);
49+
return new TreeVisitor<Tree, ExecutionContext>() {
50+
@Override
51+
public @Nullable Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
52+
if (!acc.get()) {
53+
if (tree instanceof Xml.Document && tree != mavenFindDependency.getVisitor().visit(tree, ctx)) {
54+
acc.set(true);
55+
} else if (tree instanceof J && tree != gradleFindDependency.getVisitor().visit(tree, ctx)) {
56+
acc.set(true);
57+
}
58+
}
59+
return tree;
60+
}
61+
};
62+
}
63+
64+
@Override
65+
public TreeVisitor<?, ExecutionContext> getVisitor(AtomicBoolean acc) {
66+
ChangeMethodName changeMethodName = new ChangeMethodName(
67+
"org.mockito.Mockito any(java.lang.Class)", "nullable", null, null);
68+
ChangeMethodTargetToStatic changeMethodTargetToStatic = new ChangeMethodTargetToStatic(
69+
"org.mockito.Mockito nullable(java.lang.Class)", "org.mockito.ArgumentMatchers", null, null);
70+
AnyStringToNullable anyStringToNullable = new AnyStringToNullable();
71+
return Preconditions.check(acc.get(), new TreeVisitor<Tree, ExecutionContext>() {
72+
@Override
73+
public @Nullable Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
74+
if (tree instanceof J) {
75+
doAfterVisit(changeMethodName.getVisitor());
76+
doAfterVisit(changeMethodTargetToStatic.getVisitor());
77+
doAfterVisit(anyStringToNullable.getVisitor());
78+
}
79+
return super.visit(tree, ctx);
80+
}
81+
});
82+
}
83+
}

src/main/resources/META-INF/rewrite/mockito.yml

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -123,37 +123,6 @@ recipeList:
123123
newVersion: 3.x
124124
---
125125
type: specs.openrewrite.org/v1beta/recipe
126-
name: org.openrewrite.java.testing.mockito.UsesMockitoAll
127-
displayName: Uses Mockito all from v1.x
128-
description: Finds projects that depend on `mockito-all` through Maven or Gradle.
129-
tags:
130-
- testing
131-
- mockito
132-
recipeList:
133-
- org.openrewrite.maven.search.FindDependency:
134-
groupId: org.mockito
135-
artifactId: mockito-all
136-
- org.openrewrite.gradle.search.FindDependency:
137-
groupId: org.mockito
138-
artifactId: mockito-all
139-
---
140-
type: specs.openrewrite.org/v1beta/recipe
141-
name: org.openrewrite.java.testing.mockito.AnyToNullable
142-
displayName: Replace Mockito 1.x `any(Class)` and `anyString()` with `nullable(Class)`
143-
description: Since Mockito 2.10 `any(Class)` and `anyString()` no longer match null values. Use `nullable(Class)` instead.
144-
tags:
145-
- testing
146-
- mockito
147-
recipeList:
148-
- org.openrewrite.java.ChangeMethodName:
149-
methodPattern: org.mockito.Mockito any(java.lang.Class)
150-
newMethodName: nullable
151-
- org.openrewrite.java.ChangeMethodTargetToStatic:
152-
methodPattern: org.mockito.Mockito nullable(java.lang.Class)
153-
fullyQualifiedTargetTypeName: org.mockito.ArgumentMatchers
154-
- org.openrewrite.java.testing.mockito.AnyStringToNullable
155-
---
156-
type: specs.openrewrite.org/v1beta/recipe
157126
name: org.openrewrite.java.testing.mockito.ReplacePowerMockito
158127
displayName: Replace PowerMock with raw Mockito
159128
description: Replace PowerMock with raw Mockito.

src/test/java/org/openrewrite/java/testing/mockito/AnyStringToNullableTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ String greet(String name) {
5050
import static org.mockito.Mockito.anyString;
5151
import static org.mockito.Mockito.mock;
5252
import static org.mockito.Mockito.when;
53-
53+
5454
class MyTest {
5555
void test() {
5656
Example example = mock(Example.class);
@@ -62,7 +62,7 @@ void test() {
6262
import static org.mockito.ArgumentMatchers.nullable;
6363
import static org.mockito.Mockito.mock;
6464
import static org.mockito.Mockito.when;
65-
65+
6666
class MyTest {
6767
void test() {
6868
Example example = mock(Example.class);
@@ -90,7 +90,7 @@ String greet(int value) {
9090
import static org.mockito.Mockito.mock;
9191
import static org.mockito.Mockito.when;
9292
import static org.mockito.Mockito.anyInt;
93-
93+
9494
class MyTest {
9595
void test() {
9696
Example example = mock(Example.class);

src/test/java/org/openrewrite/java/testing/mockito/AnyToNullableTest.java

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,7 @@ public void defaults(RecipeSpec spec) {
3333
.parser(JavaParser.fromJavaVersion()
3434
.classpathFromResources(new InMemoryExecutionContext(), "mockito-core-3.12")
3535
.logCompilationWarningsAndErrors(true))
36-
.recipe(Environment.builder()
37-
.scanRuntimeClasspath("org.openrewrite.java.testing.mockito")
38-
.build()
39-
.activateRecipes("org.openrewrite.java.testing.mockito.AnyToNullable"));
36+
.recipe(new AnyToNullable());
4037
}
4138

4239
@Test
@@ -73,7 +70,7 @@ String greet(Object obj) {
7370
import static org.mockito.Mockito.mock;
7471
import static org.mockito.Mockito.when;
7572
import static org.mockito.Mockito.any;
76-
73+
7774
class MyTest {
7875
void test() {
7976
Example example = mock(Example.class);
@@ -97,6 +94,52 @@ void test() {
9794
);
9895
}
9996

97+
@Test
98+
void doesNotTouchIfMockitoTwoPlus() {
99+
//language=java
100+
rewriteRun(
101+
//language=xml
102+
pomXml("""
103+
<project>
104+
<modelVersion>4.0.0</modelVersion>
105+
<groupId>com.example</groupId>
106+
<artifactId>foo</artifactId>
107+
<version>1.0.0</version>
108+
<dependencies>
109+
<dependency>
110+
<groupId>org.mockito</groupId>
111+
<artifactId>mockito-core</artifactId>
112+
<version>3.12.0</version>
113+
</dependency>
114+
</dependencies>
115+
</project>
116+
"""),
117+
//language=java
118+
java("""
119+
class Example {
120+
String greet(Object obj) {
121+
return "Hello " + obj;
122+
}
123+
}
124+
"""),
125+
//language=java
126+
java(
127+
"""
128+
import static org.mockito.Mockito.mock;
129+
import static org.mockito.Mockito.when;
130+
import static org.mockito.Mockito.any;
131+
132+
class MyTest {
133+
void test() {
134+
Example example = mock(Example.class);
135+
when(example.greet(any(Object.class))).thenReturn("Hello world");
136+
}
137+
}
138+
"""
139+
)
140+
);
141+
}
142+
100143
}
101144

102145

0 commit comments

Comments
 (0)