testng: run test method of an abstract class in inheritors (IDEA-53111)
authoranna <Anna.Kozlova@jetbrains.com>
Tue, 17 Jan 2012 15:39:10 +0000 (16:39 +0100)
committeranna <Anna.Kozlova@jetbrains.com>
Tue, 17 Jan 2012 15:41:53 +0000 (16:41 +0100)
plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java
plugins/testng/src/com/theoryinpractice/testng/configuration/SearchingForTestsTask.java
plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfiguration.java
plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGInClassConfigurationProducer.java
plugins/testng/src/com/theoryinpractice/testng/model/TestData.java

index 8fbc94bbf542fb3591d67af1aeee153bb2dd941c..082bc604d7d7d51226ff32a03e19a47d67bbf946 100644 (file)
@@ -370,6 +370,7 @@ public class JUnitConfiguration extends ModuleBasedConfiguration<JavaRunConfigur
     myData.setPatterns(patterns);
     myData.METHOD_NAME = method.getName();
     myData.TEST_OBJECT = TEST_PATTERN;
+    setGeneratedName();
   }
 
   public static class Data implements Cloneable {
index 0be68346398ac87caade3112a927a6f7a46daa2c..a4869e91ec199264da46cacef1e6606b839488c9 100644 (file)
@@ -346,20 +346,7 @@ public class SearchingForTestsTask extends Task.Backgroundable {
       )) {
         throw new CantRunException("Cannot test anonymous or local class \"" + data.getMainClassName() + '\"');
       }
-      final PsiMethod[] methods = ApplicationManager.getApplication().runReadAction(
-        new Computable<PsiMethod[]>() {
-          public PsiMethod[] compute() {
-            return psiClass.findMethodsByName(data.getMethodName(), true);
-          }
-        }
-      );
-      calculateDependencies(methods, classes, psiClass);
-      Collection<PsiMethod> psiMethods = classes.get(psiClass);
-      if (psiMethods == null) {
-        psiMethods = new LinkedHashSet<PsiMethod>();
-        classes.put(psiClass, psiMethods);
-      }
-      ContainerUtil.addAll(psiMethods, methods);
+      collectTestMethods(classes, psiClass, data.getMethodName());
     }
     else if (data.TEST_OBJECT.equals(TestType.GROUP.getType())) {
       //for a group, we include all classes
@@ -372,6 +359,7 @@ public class SearchingForTestsTask extends Task.Backgroundable {
       }
     }
     else if (data.TEST_OBJECT.equals(TestType.PATTERN.getType())) {
+      final String methodName = data.getMethodName();
       for (final String className : data.getPatterns()) {
         final PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
           @Nullable
@@ -389,7 +377,12 @@ public class SearchingForTestsTask extends Task.Backgroundable {
             return TestNGUtil.hasTest(psiClass);
           }
         })) {
-          calculateDependencies(null, classes, psiClass);
+          if (StringUtil.isEmpty(methodName)) {
+            calculateDependencies(null, classes, psiClass);
+          }
+          else {
+            collectTestMethods(classes, psiClass, methodName);
+          }
         } else {
           throw new CantRunException("No tests found in class " + className);
         }
@@ -397,6 +390,23 @@ public class SearchingForTestsTask extends Task.Backgroundable {
     }
   }
 
+  private void collectTestMethods(Map<PsiClass, Collection<PsiMethod>> classes, final PsiClass psiClass, final String methodName) {
+    final PsiMethod[] methods = ApplicationManager.getApplication().runReadAction(
+      new Computable<PsiMethod[]>() {
+        public PsiMethod[] compute() {
+          return psiClass.findMethodsByName(methodName, true);
+        }
+      }
+    );
+    calculateDependencies(methods, classes, psiClass);
+    Collection<PsiMethod> psiMethods = classes.get(psiClass);
+    if (psiMethods == null) {
+      psiMethods = new LinkedHashSet<PsiMethod>();
+      classes.put(psiClass, psiMethods);
+    }
+    ContainerUtil.addAll(psiMethods, methods);
+  }
+
   private Map<String, String> buildTestParameters() {
     Map<String, String> testParams = new HashMap<String, String>();
 
index 324b23f9d7769857459d4f07d791e076c0ce3732..4564aa0b66a3ad9ea177dd3ce5f30fcafbb4ddc0 100644 (file)
@@ -256,6 +256,18 @@ public class TestNGConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
     setModule(data.setTestMethod(location));
     setGeneratedName();
   }
+  
+  
+  public void bePatternConfiguration(List<PsiClass> classes, PsiMethod method) {
+    Set<String> patterns = new HashSet<String>();
+    for (PsiClass pattern : classes) {
+      patterns.add(pattern.getQualifiedName());
+    }
+    data.setPatterns(patterns);
+    data.METHOD_NAME = method.getName();
+    data.TEST_OBJECT = TestType.PATTERN.getType();
+    setGeneratedName();
+  }
 
   public void setGeneratedName() {
     setName(getGeneratedName());
index 8a8c991d374d35429b2cb795f74077b38474e018..67035b795bd6e35676facd60092a4dd8c2d29f9d 100644 (file)
@@ -22,6 +22,8 @@ package com.theoryinpractice.testng.configuration;
 
 import com.intellij.execution.*;
 import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.junit.InheritorChooser;
+import com.intellij.execution.junit2.info.MethodLocation;
 import com.intellij.openapi.actionSystem.LangDataKeys;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
@@ -31,6 +33,8 @@ import com.intellij.psi.util.PsiTreeUtil;
 import com.theoryinpractice.testng.util.TestNGUtil;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.List;
+
 public class TestNGInClassConfigurationProducer extends TestNGConfigurationProducer{
   private PsiElement myPsiElement = null;
 
@@ -65,7 +69,7 @@ public class TestNGInClassConfigurationProducer extends TestNGConfigurationProdu
       }
       element = element.getParent();
     }
-    if (psiClass == null || !PsiClassUtil.isRunnableClass(psiClass, true) || !TestNGUtil.hasTest(psiClass)) return null;
+    if (psiClass == null || !PsiClassUtil.isRunnableClass(psiClass, true, false) || !TestNGUtil.hasTest(psiClass)) return null;
 
     myPsiElement = psiClass;
     final Project project = location.getProject();
@@ -90,4 +94,32 @@ public class TestNGInClassConfigurationProducer extends TestNGConfigurationProdu
   public int compareTo(Object o) {
     return PREFERED;
   }
+
+  @Override
+  public void perform(final ConfigurationContext context, final Runnable performRunnable) {
+    if (myPsiElement instanceof PsiMethod) {
+      final PsiMethod psiMethod = (PsiMethod)myPsiElement;
+      final PsiClass containingClass = psiMethod.getContainingClass();
+      final InheritorChooser inheritorChooser = new InheritorChooser() {
+        @Override
+        protected void runForClasses(List<PsiClass> classes, PsiMethod method, ConfigurationContext context, Runnable performRunnable) {
+          ((TestNGConfiguration)context.getConfiguration().getConfiguration()).bePatternConfiguration(classes, method);
+          super.runForClasses(classes, method, context, performRunnable);
+        }
+
+        @Override
+        protected void runForClass(PsiClass aClass,
+                                   PsiMethod psiMethod,
+                                   ConfigurationContext context,
+                                   Runnable performRunnable) {
+          final Project project = psiMethod.getProject();
+          final MethodLocation methodLocation = new MethodLocation(project, psiMethod, PsiLocation.fromPsiElement(aClass));
+          ((TestNGConfiguration)context.getConfiguration().getConfiguration()).setMethodConfiguration(methodLocation);
+          super.runForClass(aClass, psiMethod, context, performRunnable);
+        }
+      };
+      if (inheritorChooser.runMethodInAbstractClass(context, performRunnable, psiMethod, containingClass)) return;
+    }
+    super.perform(context, performRunnable);
+  }
 }
\ No newline at end of file
index 00394391257e477dbd3fa20ee52ce4140f5f9ef1..9a50e135ac70e1d9fb2f7f82c798bfd23f83a0d9 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.execution.JavaExecutionUtil;
 import com.intellij.execution.Location;
 import com.intellij.execution.configurations.JavaRunConfigurationModule;
 import com.intellij.execution.junit.JUnitUtil;
+import com.intellij.execution.junit2.info.MethodLocation;
 import com.intellij.execution.testframework.TestSearchScope;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
@@ -210,7 +211,7 @@ public class TestData implements Cloneable
     final PsiMethod method = location.getPsiElement();
     METHOD_NAME = method.getName();
     TEST_OBJECT = TestType.METHOD.getType();
-    return setMainClass(method.getContainingClass());
+    return setMainClass(location instanceof MethodLocation ? ((MethodLocation)location).getContainingClass() : method.getContainingClass());
   }
 
   public Module setPackage(PsiPackage pkg) {