IDEA-70123 Test Assistant: Make it possible to work with test data for existing test classes that are not properly annotated

Avoid tests without test data (e.g. pure unit tests) and take special caret to tests with too generic names (like 'test1', 'test2' etc).
This commit is contained in:
Denis Zhdanov
2011-06-07 14:34:08 +04:00
parent f6eade87eb
commit 12c73e25cd
@@ -24,6 +24,7 @@ import com.intellij.util.text.Matcher;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.*;
import java.util.concurrent.TimeUnit;
@@ -39,6 +40,7 @@ public class TestDataGuessByExistingFilesUtil {
private static final long CACHE_ENTRY_TTL_MS = TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES);
private static final Map<String, Pair<TestDataDescriptor, Long>> CACHE = new ConcurrentHashMap<String, Pair<TestDataDescriptor, Long>>();
private static final Set<String> CLASSES_WITHOUT_TEST_DATA = new java.util.HashSet<String>();
private TestDataGuessByExistingFilesUtil() {
}
@@ -137,6 +139,9 @@ public class TestDataGuessByExistingFilesUtil {
}
final String qualifiedName = psiClass.getQualifiedName();
if (CLASSES_WITHOUT_TEST_DATA.contains(qualifiedName)) {
return null;
}
final Pair<TestDataDescriptor, Long> cached = CACHE.get(qualifiedName);
if (cached != null) {
if (cached.first.isComplete()) {
@@ -171,12 +176,66 @@ public class TestDataGuessByExistingFilesUtil {
}
testNames.add(name);
}
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(psiClass.getProject()).getFileIndex();
final TestDataDescriptor descriptor = buildDescriptor(gotoModel, fileIndex, testNames, psiClass);
if (isClassWithoutTestData(descriptor, testNames, psiClass)) {
CLASSES_WITHOUT_TEST_DATA.add(qualifiedName);
return null;
}
CACHE.put(qualifiedName, new Pair<TestDataDescriptor, Long>(descriptor, System.currentTimeMillis() + CACHE_ENTRY_TTL_MS));
return descriptor;
}
private static boolean isClassWithoutTestData(@NotNull TestDataDescriptor descriptor, @NotNull List<String> testNames,
@NotNull PsiClass psiClass) {
if (testNames.size() <= 1) {
// There is a possible case that the test class is just created.
return false;
}
if (!descriptor.isComplete()) {
return true;
}
boolean tooGenericNames = true;
genericNamesLoop:
for (String testName : testNames) {
for (int i = 0; i < testName.length(); i++) {
if (!Character.isDigit(testName.charAt(i))) {
tooGenericNames = false;
break genericNamesLoop;
}
}
}
final String simpleClassName = getSimpleClassName(psiClass);
if (tooGenericNames
&& (simpleClassName == null || !descriptor.myDescriptors.get(0).dir.toLowerCase().contains(simpleClassName.toLowerCase())))
{
return true;
}
// We assume that test has test data if max(2; half of tests) tests already have test data.
int toMatch = Math.max(2, testNames.size() / 2);
for (String testName : testNames) {
if (toMatch <= 0) {
return false;
}
final List<String> testDataFiles = descriptor.generate(testName);
for (String path : testDataFiles) {
if (new File(path).isFile()) {
// There is a possible case that particular test has only one test data file though the others have
// two (e.g. during testing caret position at virtual space).
toMatch--;
break;
}
}
}
return toMatch > 0;
}
//@NotNull
//private static Collection<VirtualFile> getMatchedFiles(@NotNull final Project project, @NotNull final String testName) {
// final List<VirtualFile> result = new ArrayList<VirtualFile>();
@@ -308,6 +367,22 @@ public class TestDataGuessByExistingFilesUtil {
return new TestDataDescriptor(descriptors);
}
@Nullable
private static String getSimpleClassName(@NotNull PsiClass psiClass) {
String result = psiClass.getQualifiedName();
if (result == null) {
return null;
}
if (result.endsWith("Test")) {
result = result.substring(0, result.length() - "Test".length());
}
int i = result.lastIndexOf('.');
if (i >= 0) {
result = result.substring(i + 1);
}
return result;
}
private static boolean moreRelevantPath(@NotNull TestLocationDescriptor candidate,
@NotNull Set<TestLocationDescriptor> currentDescriptors,
@NotNull PsiClass psiClass)
@@ -333,18 +408,14 @@ public class TestDataGuessByExistingFilesUtil {
}
// By class name.
String pattern = className.toLowerCase();
if (pattern.endsWith("test")) {
pattern = pattern.substring(0, pattern.length() - "Test".length());
}
i = pattern.lastIndexOf('.');
if (i >= 0) {
pattern = pattern.substring(i + 1);
}
candidateMatched = candidate.dir.toLowerCase().contains(pattern);
currentMatched = current.dir.toLowerCase().contains(pattern);
if (candidateMatched ^ currentMatched) {
return candidateMatched;
String simpleName = getSimpleClassName(psiClass);
if (simpleName != null) {
String pattern = simpleName.toLowerCase();
candidateMatched = candidate.dir.toLowerCase().contains(pattern);
currentMatched = current.dir.toLowerCase().contains(pattern);
if (candidateMatched ^ currentMatched) {
return candidateMatched;
}
}
return false;