Skip to content

Commit e8622af

Browse files
committed
Port TestUtils enhancements from MiniMaven
MiniMaven already used a fork of SciJava common's TestUtils class, and even enhanced the naming of the temporary directories. Let's benefit from those improvements everywhere. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent faf334f commit e8622af

File tree

1 file changed

+50
-5
lines changed

1 file changed

+50
-5
lines changed

src/main/java/org/scijava/test/TestUtils.java

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import java.io.File;
3535
import java.io.IOException;
3636
import java.net.URL;
37+
import java.util.AbstractMap;
38+
import java.util.Map;
3739

3840
import org.scijava.util.ClassUtils;
3941
import org.scijava.util.FileUtils;
@@ -58,7 +60,8 @@ public class TestUtils {
5860
* @throws IOException
5961
*/
6062
public static File createTemporaryDirectory(final String prefix) throws IOException {
61-
return createTemporaryDirectory(prefix, getCallingClass(null));
63+
final Map.Entry<Class<?>, String> calling = getCallingCodeLocation(null);
64+
return createTemporaryDirectory(prefix, calling.getKey(), calling.getValue());
6265
}
6366

6467
/**
@@ -77,18 +80,41 @@ public static File createTemporaryDirectory(final String prefix) throws IOExcept
7780
*/
7881
public static File createTemporaryDirectory(final String prefix,
7982
final Class<?> forClass) throws IOException
83+
{
84+
return createTemporaryDirectory(prefix, forClass, "");
85+
}
86+
87+
/**
88+
* Makes a temporary directory for use with unit tests.
89+
* <p>
90+
* When the unit test runs in a Maven context, the temporary directory will be
91+
* created in the corresponding <i>target/</i> directory instead of
92+
* <i>/tmp/</i>.
93+
* </p>
94+
*
95+
* @param prefix the prefix for the directory's name
96+
* @param forClass the class for context (to determine whether there's a
97+
* <i>target/<i> directory)
98+
* @param suffix the suffix for the directory's name
99+
* @return the reference to the newly-created temporary directory
100+
* @throws IOException
101+
*/
102+
public static File createTemporaryDirectory(final String prefix,
103+
final Class<?> forClass, final String suffix) throws IOException
80104
{
81105
final URL directory = ClassUtils.getLocation(forClass);
82106
if (directory != null && "file".equals(directory.getProtocol())) {
83107
final String path = directory.getPath();
84108
if (path != null && path.endsWith("/target/test-classes/")) {
85109
final File baseDirectory =
86110
new File(path.substring(0, path.length() - 13));
87-
final File file = File.createTempFile(prefix, "", baseDirectory);
88-
if (file.delete() && file.mkdir()) return file;
111+
final File file = new File(baseDirectory, prefix + suffix);
112+
if (file.exists()) FileUtils.deleteRecursively(file);
113+
if (!file.mkdir()) throw new IOException("Could not make directory " + file);
114+
return file;
89115
}
90116
}
91-
return FileUtils.createTemporaryDirectory(prefix, "");
117+
return FileUtils.createTemporaryDirectory(prefix, suffix);
92118
}
93119

94120
/**
@@ -104,6 +130,22 @@ public static File createTemporaryDirectory(final String prefix,
104130
* @return the class of the caller
105131
*/
106132
public static Class<?> getCallingClass(final Class<?> excluding) {
133+
return getCallingCodeLocation(excluding).getKey();
134+
}
135+
136+
/**
137+
* Returns the class and the method/line number of the caller (excluding the specified class).
138+
* <p>
139+
* Sometimes it is convenient to determine the caller's context, e.g. to
140+
* determine whether running in a maven-surefire-plugin context (in which case
141+
* the location of the caller's class would end in
142+
* <i>target/test-classes/</i>).
143+
* </p>
144+
*
145+
* @param excluding the class to exclude (or null)
146+
* @return the class of the caller and the method and line number
147+
*/
148+
public static Map.Entry<Class<?>, String> getCallingCodeLocation(final Class<?> excluding) {
107149
final String thisClassName = TestUtils.class.getName();
108150
final String thisClassName2 = excluding == null ? null : excluding.getName();
109151
final Thread currentThread = Thread.currentThread();
@@ -115,14 +157,17 @@ public static Class<?> getCallingClass(final Class<?> excluding) {
115157
continue;
116158
}
117159
final ClassLoader loader = currentThread.getContextClassLoader();
160+
final Class<?> clazz;
118161
try {
119-
return loader.loadClass(element.getClassName());
162+
clazz = loader.loadClass(element.getClassName());
120163
}
121164
catch (ClassNotFoundException e) {
122165
throw new UnsupportedOperationException("Could not load " +
123166
element.getClassName() + " with the current context class loader (" +
124167
loader + ")!");
125168
}
169+
final String suffix = element.getMethodName() + "-L" + element.getLineNumber();
170+
return new AbstractMap.SimpleEntry<Class<?>, String>(clazz, suffix);
126171
}
127172
throw new UnsupportedOperationException("No calling class outside " + thisClassName + " found!");
128173
}

0 commit comments

Comments
 (0)