From 5f06751b5393738d4e44cedbe59cf9ba1fc9cc3a Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 10 Feb 2011 18:33:54 +0100 Subject: [PATCH] check if abstract test class has non abstract inheritor -> its test methods are used --- .../intellij/execution/junit/JUnitUtil.java | 38 +++++++++++++++++-- .../expected.xml | 2 + .../src/ChildTest.java | 1 + .../src/Test.java | 4 ++ .../expected.xml | 9 +++++ .../src/Test.java | 4 ++ .../codeInspection/UnusedDeclarationTest.java | 8 ++++ 7 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/inspection/deadCode/junitAbstractClassWithInheritor/expected.xml create mode 100644 java/java-tests/testData/inspection/deadCode/junitAbstractClassWithInheritor/src/ChildTest.java create mode 100644 java/java-tests/testData/inspection/deadCode/junitAbstractClassWithInheritor/src/Test.java create mode 100644 java/java-tests/testData/inspection/deadCode/junitAbstractClassWithoutInheritor/expected.xml create mode 100644 java/java-tests/testData/inspection/deadCode/junitAbstractClassWithoutInheritor/src/Test.java diff --git a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java index f2d11a1ad09a..680eeefac5ea 100644 --- a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java +++ b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java @@ -26,8 +26,10 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.searches.ClassInheritorsSearch; import com.intellij.psi.util.PsiClassUtil; import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.Processor; import com.intellij.util.containers.Convertor; import junit.runner.BaseTestRunner; import org.jetbrains.annotations.NonNls; @@ -69,9 +71,13 @@ public class JUnitUtil { } public static boolean isTestMethod(final Location location) { + return isTestMethod(location, true); + } + + public static boolean isTestMethod(final Location location, boolean checkAbstract) { final PsiMethod psiMethod = location.getPsiElement(); final PsiClass aClass = location instanceof MethodLocation ? ((MethodLocation)location).getContainingClass() : psiMethod.getContainingClass(); - if (aClass == null || !isTestClass(aClass)) return false; + if (aClass == null || !isTestClass(aClass, checkAbstract, true)) return false; if (isTestAnnotated(psiMethod)) return true; if (psiMethod.isConstructor()) return false; if (!psiMethod.hasModifierProperty(PsiModifier.PUBLIC)) return false; @@ -192,7 +198,28 @@ public class JUnitUtil { } public static boolean isTestMethodOrConfig(PsiMethod psiMethod) { - if (getTestMethod(psiMethod) != null) return true; + if (getTestMethod(psiMethod, false) != null) { + final PsiClass containingClass = psiMethod.getContainingClass(); + assert containingClass != null; + if (containingClass.hasModifierProperty(PsiModifier.ABSTRACT)) { + final boolean[] foundNonAbstractInheritor = new boolean[1]; + ClassInheritorsSearch.search(containingClass).forEach(new Processor() { + @Override + public boolean process(PsiClass psiClass) { + if (!psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) { + foundNonAbstractInheritor[0] = true; + return false; + } + return true; + } + }); + if (foundNonAbstractInheritor[0]) { + return true; + } + } else { + return true; + } + } final String name = psiMethod.getName(); if (psiMethod.hasModifierProperty(PsiModifier.PUBLIC) && !psiMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { if (SUITE_METHOD_NAME.equals(name) || "setUp".equals(name) || "tearDown".equals(name)) { @@ -260,13 +287,16 @@ public class JUnitUtil { } return null; } + public static PsiMethod getTestMethod(final PsiElement element) { + return getTestMethod(element, true); + } - public static PsiMethod getTestMethod(final PsiElement element) { + public static PsiMethod getTestMethod(final PsiElement element, boolean checkAbstract) { final PsiManager manager = element.getManager(); final Location location = PsiLocation.fromPsiElement(manager.getProject(), element); for (Iterator> iterator = location.getAncestors(PsiMethod.class, false); iterator.hasNext();) { final Location methodLocation = iterator.next(); - if (isTestMethod(methodLocation)) return methodLocation.getPsiElement(); + if (isTestMethod(methodLocation, checkAbstract)) return methodLocation.getPsiElement(); } return null; } diff --git a/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithInheritor/expected.xml b/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithInheritor/expected.xml new file mode 100644 index 000000000000..c63c9258595e --- /dev/null +++ b/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithInheritor/expected.xml @@ -0,0 +1,2 @@ + + diff --git a/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithInheritor/src/ChildTest.java b/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithInheritor/src/ChildTest.java new file mode 100644 index 000000000000..24841ad8b92d --- /dev/null +++ b/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithInheritor/src/ChildTest.java @@ -0,0 +1 @@ +public class ChildTest extends AbstractTest {} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithInheritor/src/Test.java b/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithInheritor/src/Test.java new file mode 100644 index 000000000000..10284a9b220d --- /dev/null +++ b/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithInheritor/src/Test.java @@ -0,0 +1,4 @@ +public abstract class AbstractTest { + @org.junit.Test + public void testSmth() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithoutInheritor/expected.xml b/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithoutInheritor/expected.xml new file mode 100644 index 000000000000..13075abae5df --- /dev/null +++ b/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithoutInheritor/expected.xml @@ -0,0 +1,9 @@ + + + + Test.java + 3 + + Method is never used. + + diff --git a/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithoutInheritor/src/Test.java b/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithoutInheritor/src/Test.java new file mode 100644 index 000000000000..10284a9b220d --- /dev/null +++ b/java/java-tests/testData/inspection/deadCode/junitAbstractClassWithoutInheritor/src/Test.java @@ -0,0 +1,4 @@ +public abstract class AbstractTest { + @org.junit.Test + public void testSmth() {} +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/UnusedDeclarationTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/UnusedDeclarationTest.java index 244146928cea..3f75188f768e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/UnusedDeclarationTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/UnusedDeclarationTest.java @@ -144,6 +144,14 @@ public class UnusedDeclarationTest extends InspectionTestCase { public void testjunitEntryPoint() throws Exception { doTest(); } + + public void testjunitAbstractClassWithInheritor() throws Exception { + doTest(); + } + + public void testjunitAbstractClassWithoutInheritor() throws Exception { + doTest(); + } public void testjunitEntryPointCustomRunWith() throws Exception { doTest();