Skip to content

Commit e56ff66

Browse files
committed
Working TemporaryFolderToTempDir
1 parent e3dcfe4 commit e56ff66

File tree

3 files changed

+270
-39
lines changed

3 files changed

+270
-39
lines changed

src/before/java/org/openrewrite/java/testing/junit5/ExampleJunitTestClass.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,14 @@
2020
import org.junit.Rule;
2121
import org.junit.Test;
2222
import org.junit.rules.TemporaryFolder;
23-
import org.junit.rules.Timeout;
2423

2524
import java.io.File;
2625
import java.io.IOException;
2726

2827
public class ExampleJunitTestClass {
2928

30-
@Rule
31-
public Timeout globalTimeout = new Timeout(500);
29+
// @Rule
30+
// public Timeout globalTimeout = new Timeout(500);
3231

3332
@Rule
3433
public TemporaryFolder folder = new TemporaryFolder();
@@ -53,4 +52,12 @@ public void foo() throws IOException {
5352

5453
@Test(timeout = 500)
5554
public void bar() { }
55+
56+
private File newFolder(File root, String ... folders) throws IOException {
57+
File result = new File(root, String.join("/", folders));
58+
if(!result.mkdirs()) {
59+
throw new IOException("Couldn't create folders " + root);
60+
}
61+
return result;
62+
}
5663
}

src/main/java/org/openrewrite/java/testing/junit5/TemporaryFolderToTempDir.java

Lines changed: 126 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
1+
/*
2+
* Copyright 2020 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+
*/
116
package org.openrewrite.java.testing.junit5;
217

18+
import org.openrewrite.AutoConfigure;
319
import org.openrewrite.Formatting;
4-
import org.openrewrite.Incubating;
520
import org.openrewrite.java.AutoFormat;
621
import org.openrewrite.java.JavaIsoRefactorVisitor;
22+
import org.openrewrite.java.JavaRefactorVisitor;
723
import org.openrewrite.java.tree.Expression;
824
import org.openrewrite.java.tree.J;
925
import org.openrewrite.java.tree.JavaType;
@@ -20,9 +36,7 @@
2036
/**
2137
* Translates JUnit4's org.junit.rules.TemporaryFolder into JUnit 5's org.junit.jupiter.api.io.TempDir
2238
*/
23-
@Incubating(since = "0.1.2")
24-
// Keeping this commented out until this class is finished
25-
//@AutoConfigure
39+
@AutoConfigure
2640
public class TemporaryFolderToTempDir extends JavaIsoRefactorVisitor {
2741

2842
private static final String RuleFqn = "org.junit.Rule";
@@ -31,6 +45,8 @@ public class TemporaryFolderToTempDir extends JavaIsoRefactorVisitor {
3145
private static final J.Ident TempDirIdent = J.Ident.build(randomId(), "TempDir", TempDirType, Formatting.EMPTY);
3246
private static final JavaType.Class FileType = JavaType.Class.build("java.io.File");
3347
private static final J.Ident FileIdent = J.Ident.build(randomId(), "File", FileType, Formatting.EMPTY);
48+
private static final JavaType.Class PathType = JavaType.Class.build("java.nio.file.Path");
49+
private static final JavaType.Class FilesType = JavaType.Class.build("java.nio.file.Files");
3450
private static final String IOExceptionFqn = "java.io.IOException";
3551
private static final JavaType.Class IOExceptionType = JavaType.Class.build(IOExceptionFqn);
3652
private static final JavaType.Class StringType = JavaType.Class.build("java.lang.String");
@@ -109,28 +125,25 @@ private J convertTempFolderField(J statement) {
109125
}
110126

111127
/**
112-
* This visitor replaces these methods from TemporaryFolder with a JUnit5-compatible alternative:
128+
* This visitor replaces these methods from TemporaryFolder with JUnit5-compatible alternatives:
113129
*
130+
* File getRoot()
114131
* File newFile()
115132
* File newFile(String fileName)
116-
*
117-
* When complete it will also replace these TemporaryFolder methods:
118-
* File getRoot()
119133
* File newFolder()
120134
* File newFolder(String... folderNames)
121135
* File newFolder(String folder)
122-
*
123136
*/
124-
private static class ReplaceTemporaryFolderMethods extends JavaIsoRefactorVisitor {
137+
private static class ReplaceTemporaryFolderMethods extends JavaRefactorVisitor {
125138
private final String fieldName;
126139
ReplaceTemporaryFolderMethods(String fieldName) {
127140
this.fieldName = fieldName;
128141
setCursoringOn();
129142
}
130143

131144
@Override
132-
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method) {
133-
J.MethodInvocation m = super.visitMethodInvocation(method);
145+
public J visitMethodInvocation(J.MethodInvocation method) {
146+
J.MethodInvocation m = refactor(method, super::visitMethodInvocation);
134147
if(!(m.getSelect() instanceof J.Ident)) {
135148
return m;
136149
}
@@ -142,32 +155,62 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method) {
142155
assert getCursor().getParent() != null;
143156
List<Expression> args = m.getArgs().getArgs();
144157
// handle TemporaryFolder.newFile() and TemporaryFolder.newFile(String)
145-
if(m.getName().getSimpleName().equals("newFile")) {
146-
if(args.size() == 1 && args.get(0) instanceof J.Empty) {
147-
m = treeBuilder.buildSnippet(
148-
getCursor().getParent(),
149-
"File.createTempFile(\"junit\", null, " + fieldName + ");",
150-
FileType
151-
).get(0).withFormatting(Formatting.format(" "));
152-
} else {
153-
andThen(new AddNewFileFunction());
154-
m = treeBuilder.buildSnippet(
155-
getCursor().getParent(),
156-
"newFile(" + fieldName + ", "+ args.get(0).printTrimmed() +")",
157-
FileType, args.get(0).getType()
158-
).get(0).withFormatting(Formatting.format(" "));
159-
}
158+
switch (m.getName().getSimpleName()) {
159+
case "newFile":
160+
if (args.size() == 1 && args.get(0) instanceof J.Empty) {
161+
m = treeBuilder.buildSnippet(
162+
getCursor().getParent(),
163+
"File.createTempFile(\"junit\", null, " + fieldName + ");",
164+
FileType
165+
).get(0).withFormatting(Formatting.format(" "));
166+
} else {
167+
andThen(new AddNewFileFunction());
168+
m = treeBuilder.buildSnippet(
169+
getCursor().getParent(),
170+
"newFile(" + fieldName + ", " + args.get(0).printTrimmed() + ");",
171+
FileType, args.get(0).getType()
172+
).get(0).withFormatting(Formatting.format(" "));
173+
}
174+
break;
175+
case "getRoot":
176+
return J.Ident.build(randomId(), fieldName, FileType, m.getFormatting());
177+
case "newFolder":
178+
if (args.size() == 1 && args.get(0) instanceof J.Empty) {
179+
m = treeBuilder.buildSnippet(
180+
getCursor().getParent(),
181+
"Files.createTempDirectory(" + fieldName + ".toPath(), \"junit\").toFile();",
182+
FileType, FilesType, PathType
183+
).get(0).withFormatting(Formatting.format(" "));
184+
maybeAddImport(FilesType);
185+
} else {
186+
andThen(new AddNewFolderFunction());
187+
String argsString = printArgs(m.getArgs().getArgs());
188+
m = treeBuilder.buildSnippet(
189+
getCursor().getParent(),
190+
"newFolder(" + fieldName + ", " + argsString + ");",
191+
FileType
192+
).get(0).withFormatting(Formatting.format(" "));
193+
}
194+
break;
160195
}
161196

162197
}
163198
return m;
164199
}
200+
201+
/**
202+
* As of rewrite 5.5.0, J.MethodInvocation.Arguments.print() returns an empty String
203+
* Roll our own good-enough print() method here
204+
*/
205+
private static String printArgs(List<Expression> args) {
206+
return args.stream().map(J::print).collect(Collectors.joining(","));
207+
}
165208
}
166209

167210
/**
168211
* Adds a method like this one to the target class:
169-
* private File newFile(File dir, String fileName) throws IOException {
170-
* File file = new File(getRoot(), fileName);
212+
* private File newFile(File root, String fileName) throws IOException {
213+
* File file = new File(root, fileName);
171214
* file.createNewFile();
172215
* return file;
173216
* }
@@ -176,8 +219,7 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method) {
176219
*/
177220
private static class AddNewFileFunction extends JavaIsoRefactorVisitor {
178221
@Override
179-
public J.ClassDecl visitClassDecl(J.ClassDecl classDecl) {
180-
J.ClassDecl cd = super.visitClassDecl(classDecl);
222+
public J.ClassDecl visitClassDecl(J.ClassDecl cd) {
181223
boolean methodAlreadyExists = cd.getMethods().stream()
182224
.filter(m -> {
183225
List<Statement> params = m.getParams().getParams();
@@ -192,18 +234,69 @@ public J.ClassDecl visitClassDecl(J.ClassDecl classDecl) {
192234
List<J> statements = new ArrayList<>(cd.getBody().getStatements());
193235
J.MethodDecl newFileMethod = treeBuilder.buildMethodDeclaration(
194236
cd,
195-
"private File newFile(File dir, String fileName) throws IOException {\n" +
196-
" File file = new File(getRoot(), fileName);\n" +
237+
"private static File newFile(File root, String fileName) throws IOException {\n" +
238+
" File file = new File(root, fileName);\n" +
197239
" file.createNewFile();\n" +
198240
" return file;\n" +
199241
"}\n",
200242
FileType,
201243
IOExceptionType);
202244
statements.add(newFileMethod);
245+
maybeAddImport(FileType);
246+
maybeAddImport(IOExceptionType);
203247
cd = cd.withBody(cd.getBody().withStatements(statements));
204248
andThen(new AutoFormat(newFileMethod));
205249
}
206250
return cd;
207251
}
208252
}
253+
254+
/**
255+
* Adds a method like this one to the target class:
256+
*
257+
* private static File newFolder(File root, String ... folders) throws IOException {
258+
* File result = new File(root, String.join("/", folders));
259+
* if(!result.mkdirs()) {
260+
* throw new IOException("Couldn't create folders " + root);
261+
* }
262+
* return result;
263+
* }
264+
*/
265+
private static class AddNewFolderFunction extends JavaIsoRefactorVisitor {
266+
@Override
267+
public J.ClassDecl visitClassDecl(J.ClassDecl cd) {
268+
boolean methodAlreadyExists = cd.getMethods().stream()
269+
.filter(m -> {
270+
List<Statement> params = m.getParams().getParams();
271+
272+
return m.getSimpleName().equals("newFolder")
273+
&& params.size() == 2
274+
&& params.get(0).hasClassType(FileType)
275+
&& params.get(1).hasClassType(StringType)
276+
&& params.get(1) instanceof J.VariableDecls
277+
&& ((J.VariableDecls) params.get(1)).getVarargs() != null;
278+
})
279+
.findAny().isPresent();
280+
if(!methodAlreadyExists) {
281+
List<J> statements = new ArrayList<>(cd.getBody().getStatements());
282+
J.MethodDecl newFolderMethod = treeBuilder.buildMethodDeclaration(
283+
cd,
284+
"private static File newFolder(File root, String ... folders) throws IOException {\n" +
285+
" File result = new File(root, String.join(\"/\", folders));\n" +
286+
" if(!result.mkdirs()) {\n" +
287+
" throw new IOException(\"Couldn't create folders \" + root);\n" +
288+
" }\n" +
289+
" return result;\n" +
290+
"}",
291+
FileType,
292+
IOExceptionType);
293+
statements.add(newFolderMethod);
294+
maybeAddImport(FileType);
295+
maybeAddImport(IOExceptionType);
296+
cd = cd.withBody(cd.getBody().withStatements(statements));
297+
andThen(new AutoFormat(newFolderMethod));
298+
}
299+
return cd;
300+
}
301+
}
209302
}

0 commit comments

Comments
 (0)