mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
testng: extract strategy
This commit is contained in:
+6
-336
@@ -20,40 +20,31 @@
|
||||
*/
|
||||
package com.theoryinpractice.testng.configuration;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.execution.CantRunException;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.testframework.SearchForTestsTask;
|
||||
import com.intellij.execution.testframework.TestSearchScope;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PackageScope;
|
||||
import com.intellij.psi.search.searches.AnnotatedMembersSearch;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.util.ClassUtil;
|
||||
import com.theoryinpractice.testng.model.IDEARemoteTestRunnerClient;
|
||||
import com.theoryinpractice.testng.model.TestClassFilter;
|
||||
import com.theoryinpractice.testng.model.TestData;
|
||||
import com.theoryinpractice.testng.model.TestNGTestObject;
|
||||
import com.theoryinpractice.testng.model.TestType;
|
||||
import com.theoryinpractice.testng.util.TestNGUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.testng.xml.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
public class SearchingForTestsTask extends SearchForTestsTask {
|
||||
private static final Logger LOG = Logger.getInstance("#" + SearchingForTestsTask.class.getName());
|
||||
@@ -280,182 +271,9 @@ public class SearchingForTestsTask extends SearchForTestsTask {
|
||||
|
||||
protected void fillTestObjects(final Map<PsiClass, Map<PsiMethod, List<String>>> classes)
|
||||
throws CantRunException {
|
||||
final TestData data = myConfig.getPersistantData();
|
||||
final PsiManager psiManager = PsiManager.getInstance(myProject);
|
||||
if (data.TEST_OBJECT.equals(TestType.PACKAGE.getType())) {
|
||||
final String packageName = data.getPackageName();
|
||||
PsiPackage psiPackage = ApplicationManager.getApplication().runReadAction(
|
||||
new Computable<PsiPackage>() {
|
||||
@Nullable
|
||||
public PsiPackage compute() {
|
||||
return JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(packageName);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (psiPackage == null) {
|
||||
throw CantRunException.packageNotFound(packageName);
|
||||
}
|
||||
else {
|
||||
TestSearchScope scope = myConfig.getPersistantData().getScope();
|
||||
//TODO we should narrow this down by module really, if that's what's specified
|
||||
TestClassFilter projectFilter =
|
||||
new TestClassFilter(scope.getSourceScope(myConfig).getGlobalSearchScope(), myProject, true, true);
|
||||
TestClassFilter filter = projectFilter.intersectionWith(PackageScope.packageScope(psiPackage, true));
|
||||
calculateDependencies(null, classes, TestNGUtil.getAllTestClasses(filter, false));
|
||||
if (classes.size() == 0) {
|
||||
throw new CantRunException("No tests found in the package \"" + packageName + '\"');
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data.TEST_OBJECT.equals(TestType.CLASS.getType())) {
|
||||
//it's a class
|
||||
final PsiClass psiClass = ApplicationManager.getApplication().runReadAction(
|
||||
new Computable<PsiClass>() {
|
||||
@Nullable
|
||||
public PsiClass compute() {
|
||||
return ClassUtil.findPsiClass(psiManager, data.getMainClassName().replace('/', '.'), null, true, getSearchScope());
|
||||
}
|
||||
}
|
||||
);
|
||||
if (psiClass == null) {
|
||||
throw new CantRunException("No tests found in the class \"" + data.getMainClassName() + '\"');
|
||||
}
|
||||
if (null == ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Nullable
|
||||
public String compute() {
|
||||
return psiClass.getQualifiedName();
|
||||
}
|
||||
})) {
|
||||
throw new CantRunException("Cannot test anonymous or local class \"" + data.getMainClassName() + '\"');
|
||||
}
|
||||
calculateDependencies(null, classes, psiClass);
|
||||
}
|
||||
else if (data.TEST_OBJECT.equals(TestType.METHOD.getType())) {
|
||||
//it's a method
|
||||
final PsiClass psiClass = ApplicationManager.getApplication().runReadAction(
|
||||
new Computable<PsiClass>() {
|
||||
@Nullable
|
||||
public PsiClass compute() {
|
||||
return ClassUtil.findPsiClass(psiManager, data.getMainClassName().replace('/', '.'), null, true, getSearchScope());
|
||||
}
|
||||
}
|
||||
);
|
||||
if (psiClass == null) {
|
||||
throw new CantRunException("No tests found in the class \"" + data.getMainClassName() + '\"');
|
||||
}
|
||||
if (null == ApplicationManager.getApplication().runReadAction(
|
||||
new Computable<String>() {
|
||||
@Nullable
|
||||
public String compute() {
|
||||
return psiClass.getQualifiedName();
|
||||
}
|
||||
}
|
||||
)) {
|
||||
throw new CantRunException("Cannot test anonymous or local class \"" + data.getMainClassName() + '\"');
|
||||
}
|
||||
collectTestMethods(classes, psiClass, data.getMethodName());
|
||||
}
|
||||
else if (data.TEST_OBJECT.equals(TestType.GROUP.getType())) {
|
||||
//for a group, we include all classes
|
||||
PsiClass[] testClasses = TestNGUtil
|
||||
.getAllTestClasses(new TestClassFilter(data.getScope().getSourceScope(myConfig).getGlobalSearchScope(), myProject, true, true), false);
|
||||
if (testClasses != null) {
|
||||
for (PsiClass c : testClasses) {
|
||||
classes.put(c, new LinkedHashMap<PsiMethod, List<String>>());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data.TEST_OBJECT.equals(TestType.PATTERN.getType())) {
|
||||
for (final String pattern : data.getPatterns()) {
|
||||
final String className;
|
||||
final String methodName;
|
||||
if (pattern.contains(",")) {
|
||||
methodName = StringUtil.getShortName(pattern, ',');
|
||||
className = StringUtil.getPackageName(pattern, ',');
|
||||
} else {
|
||||
className = pattern;
|
||||
methodName = null;
|
||||
}
|
||||
|
||||
final PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiClass compute() {
|
||||
return ClassUtil.findPsiClass(psiManager, className.replace('/', '.'), null, true, getSearchScope());
|
||||
}
|
||||
});
|
||||
if (psiClass != null) {
|
||||
final Boolean hasTest = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
return TestNGUtil.hasTest(psiClass);
|
||||
}
|
||||
});
|
||||
if (hasTest) {
|
||||
if (StringUtil.isEmpty(methodName)) {
|
||||
calculateDependencies(null, classes, psiClass);
|
||||
}
|
||||
else {
|
||||
collectTestMethods(classes, psiClass, methodName);
|
||||
}
|
||||
} else {
|
||||
throw new CantRunException("No tests found in class " + className);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (classes.size() != data.getPatterns().size()) {
|
||||
TestSearchScope scope = myConfig.getPersistantData().getScope();
|
||||
final List<Pattern> compilePatterns = new ArrayList<Pattern>();
|
||||
for (String p : data.getPatterns()) {
|
||||
final Pattern compilePattern;
|
||||
try {
|
||||
compilePattern = Pattern.compile(p);
|
||||
}
|
||||
catch (PatternSyntaxException e) {
|
||||
continue;
|
||||
}
|
||||
if (compilePattern != null) {
|
||||
compilePatterns.add(compilePattern);
|
||||
}
|
||||
}
|
||||
TestClassFilter projectFilter =
|
||||
new TestClassFilter(scope.getSourceScope(myConfig).getGlobalSearchScope(), myProject, true, true){
|
||||
@Override
|
||||
public boolean isAccepted(PsiClass psiClass) {
|
||||
if (super.isAccepted(psiClass)) {
|
||||
final String qualifiedName = psiClass.getQualifiedName();
|
||||
LOG.assertTrue(qualifiedName != null);
|
||||
for (Pattern pattern : compilePatterns) {
|
||||
if (pattern.matcher(qualifiedName).matches()) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
calculateDependencies(null, classes, TestNGUtil.getAllTestClasses(projectFilter, false));
|
||||
if (classes.size() == 0) {
|
||||
throw new CantRunException("No tests found in for patterns \"" + StringUtil.join(data.getPatterns(), " || ") + '\"');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void collectTestMethods(Map<PsiClass, Map<PsiMethod, List<String>>> 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);
|
||||
Map<PsiMethod, List<String>> psiMethods = classes.get(psiClass);
|
||||
if (psiMethods == null) {
|
||||
psiMethods = new LinkedHashMap<PsiMethod, List<String>>();
|
||||
classes.put(psiClass, psiMethods);
|
||||
}
|
||||
for (PsiMethod method : methods) {
|
||||
psiMethods.put(method, Collections.<String>emptyList());
|
||||
final TestNGTestObject testObject = TestNGTestObject.fromConfig(myConfig);
|
||||
if (testObject != null) {
|
||||
testObject.fillTestObjects(classes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,152 +310,4 @@ public class SearchingForTestsTask extends SearchForTestsTask {
|
||||
return params;
|
||||
}
|
||||
|
||||
private void calculateDependencies(PsiMethod[] methods,
|
||||
final Map<PsiClass, Map<PsiMethod, List<String>>> results,
|
||||
@Nullable final PsiClass... classes) {
|
||||
calculateDependencies(methods, results, new LinkedHashSet<PsiMember>(), classes);
|
||||
}
|
||||
|
||||
private void calculateDependencies(final PsiMethod[] methods,
|
||||
final Map<PsiClass, Map<PsiMethod, List<String>>> results,
|
||||
final Set<PsiMember> alreadyMarkedToBeChecked,
|
||||
@Nullable final PsiClass... classes) {
|
||||
if (classes != null && classes.length > 0) {
|
||||
final Set<String> groupDependencies = new LinkedHashSet<String>();
|
||||
TestNGUtil.collectAnnotationValues(groupDependencies, "dependsOnGroups", methods, classes);
|
||||
final Set<PsiMember> membersToCheckNow = new LinkedHashSet<PsiMember>();
|
||||
if (!groupDependencies.isEmpty()) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
final Project project = classes[0].getProject();
|
||||
final PsiClass testAnnotation =
|
||||
JavaPsiFacade.getInstance(project).findClass(TestNGUtil.TEST_ANNOTATION_FQN, GlobalSearchScope.allScope(project));
|
||||
LOG.assertTrue(testAnnotation != null);
|
||||
for (PsiMember psiMember : AnnotatedMembersSearch.search(testAnnotation, getSearchScope())) {
|
||||
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(psiMember, TestNGUtil.TEST_ANNOTATION_FQN);
|
||||
if (TestNGUtil.isAnnotatedWithParameter(annotation, "groups", groupDependencies)) {
|
||||
if (appendMember(psiMember, alreadyMarkedToBeChecked, results)) {
|
||||
membersToCheckNow.add(psiMember);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
collectDependsOnMethods(results, alreadyMarkedToBeChecked, membersToCheckNow, methods, classes);
|
||||
|
||||
if (methods == null) {
|
||||
for (PsiClass c : classes) {
|
||||
results.put(c, new LinkedHashMap<PsiMethod, List<String>>());
|
||||
}
|
||||
} else {
|
||||
for (PsiMember psiMember : membersToCheckNow) {
|
||||
PsiClass psiClass;
|
||||
PsiMethod[] meths = null;
|
||||
if (psiMember instanceof PsiMethod) {
|
||||
psiClass = psiMember.getContainingClass();
|
||||
meths = new PsiMethod[] {(PsiMethod)psiMember};
|
||||
} else {
|
||||
psiClass = (PsiClass)psiMember;
|
||||
}
|
||||
calculateDependencies(meths, results, alreadyMarkedToBeChecked, psiClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void collectDependsOnMethods(final Map<PsiClass, Map<PsiMethod, List<String>>> results,
|
||||
final Set<PsiMember> alreadyMarkedToBeChecked,
|
||||
final Set<PsiMember> membersToCheckNow,
|
||||
final PsiMethod[] methods,
|
||||
final PsiClass... classes) {
|
||||
final PsiClass[] psiClasses;
|
||||
if (methods != null && methods.length > 0) {
|
||||
final Set<PsiClass> containingClasses = new LinkedHashSet<PsiClass>();
|
||||
for (final PsiMethod method : methods) {
|
||||
containingClasses.add(ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
|
||||
@Override
|
||||
public PsiClass compute() {
|
||||
return method.getContainingClass();
|
||||
}
|
||||
}));
|
||||
}
|
||||
psiClasses = containingClasses.toArray(new PsiClass[containingClasses.size()]);
|
||||
} else {
|
||||
psiClasses = classes;
|
||||
}
|
||||
for (final PsiClass containingClass : psiClasses) {
|
||||
final Set<String> testMethodDependencies = new LinkedHashSet<String>();
|
||||
TestNGUtil.collectAnnotationValues(testMethodDependencies, "dependsOnMethods", methods, containingClass);
|
||||
if (!testMethodDependencies.isEmpty()) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
final Project project = containingClass.getProject();
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
|
||||
for (String dependency : testMethodDependencies) {
|
||||
final String className = StringUtil.getPackageName(dependency);
|
||||
final String methodName = StringUtil.getShortName(dependency);
|
||||
if (StringUtil.isEmpty(className)) {
|
||||
checkClassMethods(methodName, containingClass, alreadyMarkedToBeChecked, membersToCheckNow, results);
|
||||
}
|
||||
else {
|
||||
final PsiClass aClass = psiFacade.findClass(className, containingClass.getResolveScope());
|
||||
if (aClass != null) {
|
||||
checkClassMethods(methodName, aClass, alreadyMarkedToBeChecked, membersToCheckNow, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkClassMethods(String methodName,
|
||||
PsiClass containingClass,
|
||||
Set<PsiMember> alreadyMarkedToBeChecked,
|
||||
Set<PsiMember> membersToCheckNow,
|
||||
Map<PsiClass, Map<PsiMethod, List<String>>> results) {
|
||||
final PsiMethod[] psiMethods = containingClass.findMethodsByName(methodName, true);
|
||||
for (PsiMethod method : psiMethods) {
|
||||
if (AnnotationUtil.isAnnotated(method, TestNGUtil.TEST_ANNOTATION_FQN, false) &&
|
||||
appendMember(method, alreadyMarkedToBeChecked, results)) {
|
||||
membersToCheckNow.add(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean appendMember(final PsiMember psiMember,
|
||||
final Set<PsiMember> underConsideration,
|
||||
final Map<PsiClass, Map<PsiMethod, List<String>>> results) {
|
||||
boolean result = false;
|
||||
final PsiClass psiClass = psiMember instanceof PsiClass ? ((PsiClass)psiMember) : psiMember.getContainingClass();
|
||||
Map<PsiMethod, List<String>> psiMethods = results.get(psiClass);
|
||||
if (psiMethods == null) {
|
||||
psiMethods = new LinkedHashMap<PsiMethod, List<String>>();
|
||||
results.put(psiClass, psiMethods);
|
||||
if (psiMember instanceof PsiClass) {
|
||||
result = underConsideration.add(psiMember);
|
||||
}
|
||||
}
|
||||
if (psiMember instanceof PsiMethod) {
|
||||
final boolean add = psiMethods.put((PsiMethod)psiMember, Collections.<String>emptyList()) != null;
|
||||
if (add) {
|
||||
return underConsideration.add(psiMember);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private GlobalSearchScope getSearchScope() {
|
||||
final TestData data = myConfig.getPersistantData();
|
||||
final Module module = myConfig.getConfigurationModule().getModule();
|
||||
return data.TEST_OBJECT.equals(TestType.PACKAGE.getType())
|
||||
? myConfig.getPersistantData().getScope().getSourceScope(myConfig).getGlobalSearchScope()
|
||||
: module != null ? GlobalSearchScope.moduleWithDependenciesScope(module) : GlobalSearchScope.projectScope(myConfig.getProject());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-64
@@ -29,7 +29,6 @@ import com.intellij.execution.configuration.EnvironmentVariablesComponent;
|
||||
import com.intellij.execution.configurations.*;
|
||||
import com.intellij.execution.junit.RefactoringListeners;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.execution.testframework.SourceScope;
|
||||
import com.intellij.execution.testframework.TestSearchScope;
|
||||
import com.intellij.execution.util.JavaParametersUtil;
|
||||
import com.intellij.execution.util.ProgramParametersUtil;
|
||||
@@ -47,12 +46,12 @@ import com.intellij.refactoring.listeners.RefactoringElementAdapter;
|
||||
import com.intellij.refactoring.listeners.RefactoringElementListener;
|
||||
import com.intellij.refactoring.listeners.UndoRefactoringElementListener;
|
||||
import com.theoryinpractice.testng.model.TestData;
|
||||
import com.theoryinpractice.testng.model.TestNGTestObject;
|
||||
import com.theoryinpractice.testng.model.TestType;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.testng.xml.Parser;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -68,7 +67,7 @@ public class TestNGConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
|
||||
public boolean ALTERNATIVE_JRE_PATH_ENABLED;
|
||||
public String ALTERNATIVE_JRE_PATH;
|
||||
|
||||
private static final Object PARSE_LOCK = new Object();
|
||||
|
||||
|
||||
public static final String DEFAULT_PACKAGE_NAME = ExecutionBundle.message("default.package.presentable.name");
|
||||
public static final String DEFAULT_PACKAGE_CONFIGURATION_NAME = ExecutionBundle.message("default.package.configuration.name");
|
||||
@@ -149,32 +148,14 @@ public class TestNGConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
|
||||
|
||||
@Override
|
||||
public String suggestedName() {
|
||||
return data.getGeneratedName(getConfigurationModule());
|
||||
final TestNGTestObject testObject = TestNGTestObject.fromConfig(this);
|
||||
return testObject != null ? testObject.getGeneratedName() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActionName() {
|
||||
if (TestType.CLASS.getType().equals(data.TEST_OBJECT)) {
|
||||
String shortName = JavaExecutionUtil.getShortClassName(data.MAIN_CLASS_NAME);
|
||||
return ProgramRunnerUtil.shortenName(shortName, 0);
|
||||
}
|
||||
if (TestType.PACKAGE.getType().equals(data.TEST_OBJECT)) {
|
||||
String s = getName();
|
||||
if (!isGeneratedName()) return '\"' + s + '\"';
|
||||
if (data.getPackageName().trim().length() > 0) {
|
||||
return "Tests in \"" + data.getPackageName() + '\"';
|
||||
}
|
||||
else {
|
||||
return "All Tests";
|
||||
}
|
||||
}
|
||||
if (TestType.METHOD.getType().equals(data.TEST_OBJECT)) {
|
||||
return data.getMethodName() + "()";
|
||||
}
|
||||
if (TestType.SUITE.getType().equals(data.TEST_OBJECT)) {
|
||||
return data.getSuiteName();
|
||||
}
|
||||
return data.getGroupName();
|
||||
final TestNGTestObject testObject = TestNGTestObject.fromConfig(this);
|
||||
return testObject != null ? ProgramRunnerUtil.shortenName(testObject.getActionName(), 0) : null;
|
||||
}
|
||||
|
||||
public void setVMParameters(String value) {
|
||||
@@ -299,45 +280,9 @@ public class TestNGConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
|
||||
|
||||
@Override
|
||||
public void checkConfiguration() throws RuntimeConfigurationException {
|
||||
if (data.TEST_OBJECT.equals(TestType.CLASS.getType()) || data.TEST_OBJECT.equals(TestType.METHOD.getType())) {
|
||||
final SourceScope scope = data.getScope().getSourceScope(this);
|
||||
if (scope == null) {
|
||||
throw new RuntimeConfigurationException("Invalid scope specified");
|
||||
}
|
||||
PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(data.getMainClassName(), scope.getGlobalSearchScope());
|
||||
if (psiClass == null) throw new RuntimeConfigurationException("Class '" + data.getMainClassName() + "' not found");
|
||||
if (data.TEST_OBJECT.equals(TestType.METHOD.getType())) {
|
||||
PsiMethod[] methods = psiClass.findMethodsByName(data.getMethodName(), true);
|
||||
if (methods.length == 0) {
|
||||
throw new RuntimeConfigurationException("Method '" + data.getMethodName() + "' not found");
|
||||
}
|
||||
for (PsiMethod method : methods) {
|
||||
if (!method.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
throw new RuntimeConfigurationException("Non public method '" + data.getMethodName() + "'specified");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data.TEST_OBJECT.equals(TestType.PACKAGE.getType())) {
|
||||
PsiPackage psiPackage = JavaPsiFacade.getInstance(project).findPackage(data.getPackageName());
|
||||
if (psiPackage == null) throw new RuntimeConfigurationException("Package '" + data.getPackageName() + "' not found");
|
||||
}
|
||||
else if (data.TEST_OBJECT.equals(TestType.SUITE.getType())) {
|
||||
try {
|
||||
final Parser parser = new Parser(data.getSuiteName());
|
||||
parser.setLoadClasses(false);
|
||||
synchronized (PARSE_LOCK) {
|
||||
parser.parse();//try to parse suite.xml
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeConfigurationException("Unable to parse '" + data.getSuiteName() + "' specified");
|
||||
}
|
||||
} else if (data.TEST_OBJECT.equals(TestType.PATTERN.getType())) {
|
||||
final Set<String> patterns = data.getPatterns();
|
||||
if (patterns.isEmpty()) {
|
||||
throw new RuntimeConfigurationWarning("No pattern selected");
|
||||
}
|
||||
final TestNGTestObject testObject = TestNGTestObject.fromConfig(this);
|
||||
if (testObject != null) {
|
||||
testObject.checkConfiguration();
|
||||
}
|
||||
JavaRunConfigurationExtensionManager.checkConfigurationIsValid(this);
|
||||
ProgramParametersUtil.checkWorkingDirectoryExist(this, getProject(), getConfigurationModule().getModule());
|
||||
|
||||
+2
-1
@@ -33,6 +33,7 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.theoryinpractice.testng.model.TestData;
|
||||
import com.theoryinpractice.testng.model.TestNGTestObject;
|
||||
import org.testng.IDEATestNGRemoteListener;
|
||||
|
||||
public abstract class TestNGConfigurationProducer extends JavaRunConfigurationProducerBase<TestNGConfiguration> implements Cloneable {
|
||||
@@ -58,7 +59,7 @@ public abstract class TestNGConfigurationProducer extends JavaRunConfigurationPr
|
||||
String paramSetName = contextLocation instanceof PsiMemberParameterizedLocation
|
||||
? getInvocationNumber(((PsiMemberParameterizedLocation)contextLocation).getParamSetName()) : null;
|
||||
if (paramSetName != null && !Comparing.strEqual(paramSetName, testNGConfiguration.getProgramParameters())) return false;
|
||||
TestData testobject = testNGConfiguration.getPersistantData();
|
||||
TestNGTestObject testobject = TestNGTestObject.fromConfig(testNGConfiguration);
|
||||
if (testobject != null) {
|
||||
if (testobject.isConfiguredByElement(element)) {
|
||||
final Module configurationModule = testNGConfiguration.getConfigurationModule().getModule();
|
||||
|
||||
+3
-1
@@ -33,6 +33,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.theoryinpractice.testng.model.TestData;
|
||||
import com.theoryinpractice.testng.model.TestNGTestObject;
|
||||
import icons.TestngIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -72,7 +73,8 @@ public class TestNGConfigurationType implements ConfigurationType
|
||||
return false;
|
||||
else {
|
||||
final PsiElement element = location.getPsiElement();
|
||||
if (testobject.isConfiguredByElement(element)) {
|
||||
final TestNGTestObject testNGTestObject = TestNGTestObject.fromConfig(config);
|
||||
if (testNGTestObject != null && testNGTestObject.isConfiguredByElement(element)) {
|
||||
final Module configurationModule = config.getConfigurationModule().getModule();
|
||||
if (Comparing.equal(location.getModule(), configurationModule)) return true;
|
||||
|
||||
|
||||
@@ -18,16 +18,15 @@ package com.theoryinpractice.testng.model;
|
||||
import com.intellij.execution.ExternalizablePath;
|
||||
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;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiPackage;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -174,26 +173,6 @@ public class TestData implements Cloneable
|
||||
return data;
|
||||
}
|
||||
|
||||
public String getGeneratedName(JavaRunConfigurationModule runconfigurationmodule) {
|
||||
if (TestType.PACKAGE.getType().equals(TEST_OBJECT)) if (getPackageName().length() == 0) return "<default>";
|
||||
else return getPackageName();
|
||||
String name = JavaExecutionUtil.getPresentableClassName(getMainClassName());
|
||||
if (TestType.METHOD.getType().equals(TEST_OBJECT)) {
|
||||
return name + '.' + getMethodName();
|
||||
}
|
||||
else if (TestType.SUITE.getType().equals(TEST_OBJECT)) {
|
||||
return getSuiteName();
|
||||
}
|
||||
else {
|
||||
if (TestType.PATTERN.getType().equals(TEST_OBJECT)) {
|
||||
final int size = myPatterns.size();
|
||||
if (size == 0) return "Temp suite";
|
||||
return StringUtil.getShortName(myPatterns.iterator().next()) + (size > 1 ? " and " + (size - 1) + " more" : "");
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public String getMainClassName() {
|
||||
return MAIN_CLASS_NAME == null ? "" : MAIN_CLASS_NAME;
|
||||
}
|
||||
@@ -217,28 +196,6 @@ public class TestData implements Cloneable
|
||||
return JavaExecutionUtil.findModule(psiclass);
|
||||
}
|
||||
|
||||
public boolean isConfiguredByElement(PsiElement element) {
|
||||
if (TEST_OBJECT.equals(TestType.PACKAGE.getType())) {
|
||||
if (element instanceof PsiPackage) {
|
||||
return Comparing.strEqual(PACKAGE_NAME, ((PsiPackage) element).getQualifiedName());
|
||||
} else if (element instanceof PsiDirectory) {
|
||||
final PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage(((PsiDirectory)element));
|
||||
return psiPackage != null && Comparing.strEqual(PACKAGE_NAME, psiPackage.getQualifiedName());
|
||||
}
|
||||
}
|
||||
|
||||
element = PsiTreeUtil.getParentOfType(element, PsiModifierListOwner.class, false);
|
||||
if (element instanceof PsiMethod && TEST_OBJECT.equals(TestType.METHOD.getType())) {
|
||||
final PsiClass aClass = ((PsiMethod) element).getContainingClass();
|
||||
return aClass != null &&
|
||||
Comparing.strEqual(MAIN_CLASS_NAME, JavaExecutionUtil.getRuntimeQualifiedName(aClass)) &&
|
||||
Comparing.strEqual(METHOD_NAME, ((PsiMethod) element).getName());
|
||||
} else if (element instanceof PsiClass && TEST_OBJECT.equals(TestType.CLASS.getType())) {
|
||||
return Comparing.strEqual(MAIN_CLASS_NAME, JavaExecutionUtil.getRuntimeQualifiedName((PsiClass) element));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Map<String, String> getEnvs() {
|
||||
return ENVS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.theoryinpractice.testng.model;
|
||||
|
||||
import com.intellij.execution.CantRunException;
|
||||
import com.intellij.execution.JavaExecutionUtil;
|
||||
import com.intellij.execution.configurations.RuntimeConfigurationException;
|
||||
import com.intellij.execution.testframework.SourceScope;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.ClassUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.theoryinpractice.testng.configuration.TestNGConfiguration;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TestNGTestClass extends TestNGTestObject {
|
||||
public TestNGTestClass(TestNGConfiguration config) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillTestObjects(Map<PsiClass, Map<PsiMethod, List<String>>> classes)
|
||||
throws CantRunException {
|
||||
final TestData data = myConfig.getPersistantData();
|
||||
//it's a class
|
||||
final PsiClass psiClass = ApplicationManager.getApplication().runReadAction(
|
||||
new Computable<PsiClass>() {
|
||||
@Nullable
|
||||
public PsiClass compute() {
|
||||
return ClassUtil.findPsiClass(PsiManager.getInstance(myConfig.getProject()), data.getMainClassName().replace('/', '.'), null, true, getSearchScope());
|
||||
}
|
||||
}
|
||||
);
|
||||
if (psiClass == null) {
|
||||
throw new CantRunException("No tests found in the class \"" + data.getMainClassName() + '\"');
|
||||
}
|
||||
if (null == ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Nullable
|
||||
public String compute() {
|
||||
return psiClass.getQualifiedName();
|
||||
}
|
||||
})) {
|
||||
throw new CantRunException("Cannot test anonymous or local class \"" + data.getMainClassName() + '\"');
|
||||
}
|
||||
calculateDependencies(null, classes, psiClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGeneratedName() {
|
||||
return JavaExecutionUtil.getPresentableClassName(myConfig.getPersistantData().getMainClassName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActionName() {
|
||||
return JavaExecutionUtil.getShortClassName(myConfig.getPersistantData().MAIN_CLASS_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkConfiguration() throws RuntimeConfigurationException {
|
||||
final TestData data = myConfig.getPersistantData();
|
||||
final SourceScope scope = data.getScope().getSourceScope(myConfig);
|
||||
if (scope == null) {
|
||||
throw new RuntimeConfigurationException("Invalid scope specified");
|
||||
}
|
||||
PsiClass psiClass = JavaPsiFacade.getInstance(myConfig.getProject()).findClass(data.getMainClassName(), scope.getGlobalSearchScope());
|
||||
if (psiClass == null) throw new RuntimeConfigurationException("Class '" + data.getMainClassName() + "' not found");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfiguredByElement(PsiElement element) {
|
||||
element = PsiTreeUtil.getParentOfType(element, PsiModifierListOwner.class, false);
|
||||
if (element instanceof PsiClass) {
|
||||
return Comparing.strEqual(myConfig.getPersistantData().getMethodName(), JavaExecutionUtil.getRuntimeQualifiedName((PsiClass) element));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.theoryinpractice.testng.model;
|
||||
|
||||
import com.intellij.execution.CantRunException;
|
||||
import com.intellij.execution.configurations.RuntimeConfigurationException;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.theoryinpractice.testng.configuration.TestNGConfiguration;
|
||||
import com.theoryinpractice.testng.util.TestNGUtil;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TestNGTestGroup extends TestNGTestObject {
|
||||
public TestNGTestGroup(TestNGConfiguration config) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillTestObjects(Map<PsiClass, Map<PsiMethod, List<String>>> classes)
|
||||
throws CantRunException {
|
||||
final TestData data = myConfig.getPersistantData();
|
||||
//for a group, we include all classes
|
||||
final TestClassFilter classFilter =
|
||||
new TestClassFilter(data.getScope().getSourceScope(myConfig).getGlobalSearchScope(), myConfig.getProject(), true, true);
|
||||
PsiClass[] testClasses = TestNGUtil.getAllTestClasses(classFilter, false);
|
||||
if (testClasses != null) {
|
||||
for (PsiClass c : testClasses) {
|
||||
classes.put(c, new LinkedHashMap<PsiMethod, List<String>>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGeneratedName() {
|
||||
return myConfig.getPersistantData().getGroupName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActionName() {
|
||||
return myConfig.getPersistantData().getGroupName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkConfiguration() throws RuntimeConfigurationException {
|
||||
//check group exist?
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.theoryinpractice.testng.model;
|
||||
|
||||
import com.intellij.execution.CantRunException;
|
||||
import com.intellij.execution.JavaExecutionUtil;
|
||||
import com.intellij.execution.configurations.RuntimeConfigurationException;
|
||||
import com.intellij.execution.testframework.SourceScope;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.ClassUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.theoryinpractice.testng.configuration.TestNGConfiguration;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TestNGTestMethod extends TestNGTestObject {
|
||||
public TestNGTestMethod(TestNGConfiguration config) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillTestObjects(Map<PsiClass, Map<PsiMethod, List<String>>> classes)
|
||||
throws CantRunException {
|
||||
final TestData data = myConfig.getPersistantData();
|
||||
final PsiClass psiClass = ApplicationManager.getApplication().runReadAction(
|
||||
new Computable<PsiClass>() {
|
||||
@Nullable
|
||||
public PsiClass compute() {
|
||||
return ClassUtil.findPsiClass(PsiManager.getInstance(myConfig.getProject()), data.getMainClassName().replace('/', '.'), null, true, getSearchScope());
|
||||
}
|
||||
}
|
||||
);
|
||||
if (psiClass == null) {
|
||||
throw new CantRunException("No tests found in the class \"" + data.getMainClassName() + '\"');
|
||||
}
|
||||
if (null == ApplicationManager.getApplication().runReadAction(
|
||||
new Computable<String>() {
|
||||
@Nullable
|
||||
public String compute() {
|
||||
return psiClass.getQualifiedName();
|
||||
}
|
||||
}
|
||||
)) {
|
||||
throw new CantRunException("Cannot test anonymous or local class \"" + data.getMainClassName() + '\"');
|
||||
}
|
||||
collectTestMethods(classes, psiClass, data.getMethodName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGeneratedName() {
|
||||
final TestData data = myConfig.getPersistantData();
|
||||
return JavaExecutionUtil.getPresentableClassName(data.getMainClassName()) + '.' + data.getMethodName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActionName() {
|
||||
return myConfig.getPersistantData().getMethodName() + "()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkConfiguration() throws RuntimeConfigurationException {
|
||||
final TestData data = myConfig.getPersistantData();
|
||||
final SourceScope scope = data.getScope().getSourceScope(myConfig);
|
||||
if (scope == null) {
|
||||
throw new RuntimeConfigurationException("Invalid scope specified");
|
||||
}
|
||||
PsiClass psiClass = JavaPsiFacade.getInstance(myConfig.getProject()).findClass(data.getMainClassName(), scope.getGlobalSearchScope());
|
||||
if (psiClass == null) throw new RuntimeConfigurationException("Class '" + data.getMainClassName() + "' not found");
|
||||
PsiMethod[] methods = psiClass.findMethodsByName(data.getMethodName(), true);
|
||||
if (methods.length == 0) {
|
||||
throw new RuntimeConfigurationException("Method '" + data.getMethodName() + "' not found");
|
||||
}
|
||||
for (PsiMethod method : methods) {
|
||||
if (!method.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
throw new RuntimeConfigurationException("Non public method '" + data.getMethodName() + "'specified");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfiguredByElement(PsiElement element) {
|
||||
element = PsiTreeUtil.getParentOfType(element, PsiModifierListOwner.class, false);
|
||||
if (element instanceof PsiMethod) {
|
||||
final PsiClass aClass = ((PsiMethod) element).getContainingClass();
|
||||
final TestData data = myConfig.getPersistantData();
|
||||
return aClass != null &&
|
||||
Comparing.strEqual(data.MAIN_CLASS_NAME, JavaExecutionUtil.getRuntimeQualifiedName(aClass)) &&
|
||||
Comparing.strEqual(data.METHOD_NAME, ((PsiMethod) element).getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.theoryinpractice.testng.model;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.execution.CantRunException;
|
||||
import com.intellij.execution.configurations.RuntimeConfigurationException;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.AnnotatedMembersSearch;
|
||||
import com.theoryinpractice.testng.configuration.TestNGConfiguration;
|
||||
import com.theoryinpractice.testng.util.TestNGUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class TestNGTestObject {
|
||||
private static final Logger LOG = Logger.getInstance("#" + TestNGTestObject.class.getName());
|
||||
protected final TestNGConfiguration myConfig;
|
||||
|
||||
public TestNGTestObject(TestNGConfiguration config) {
|
||||
myConfig = config;
|
||||
}
|
||||
|
||||
public static TestNGTestObject fromConfig(TestNGConfiguration config) {
|
||||
final TestData data = config.getPersistantData();
|
||||
if (data.TEST_OBJECT.equals(TestType.PACKAGE.getType())) {
|
||||
return new TestNGTestPackage(config);
|
||||
}
|
||||
if (data.TEST_OBJECT.equals(TestType.CLASS.getType())) {
|
||||
return new TestNGTestClass(config);
|
||||
}
|
||||
if (data.TEST_OBJECT.equals(TestType.METHOD.getType())) {
|
||||
return new TestNGTestMethod(config);
|
||||
}
|
||||
|
||||
if (data.TEST_OBJECT.equals(TestType.GROUP.getType())) {
|
||||
return new TestNGTestGroup(config);
|
||||
}
|
||||
|
||||
if (data.TEST_OBJECT.equals(TestType.PATTERN.getType())) {
|
||||
return new TestNGTestPattern(config);
|
||||
}
|
||||
|
||||
if (data.TEST_OBJECT.equals(TestType.SUITE.getType())){
|
||||
return new TestNGTestSuite(config);
|
||||
}
|
||||
assert false : data.TEST_OBJECT;
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract void fillTestObjects(final Map<PsiClass, Map<PsiMethod, List<String>>> classes) throws CantRunException;
|
||||
public abstract String getGeneratedName();
|
||||
public abstract String getActionName();
|
||||
public abstract void checkConfiguration() throws RuntimeConfigurationException;
|
||||
|
||||
public boolean isConfiguredByElement(PsiElement element) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void calculateDependencies(PsiMethod[] methods,
|
||||
final Map<PsiClass, Map<PsiMethod, List<String>>> results,
|
||||
@Nullable final PsiClass... classes) {
|
||||
calculateDependencies(methods, results, new LinkedHashSet<PsiMember>(), classes);
|
||||
}
|
||||
|
||||
private void calculateDependencies(final PsiMethod[] methods,
|
||||
final Map<PsiClass, Map<PsiMethod, List<String>>> results,
|
||||
final Set<PsiMember> alreadyMarkedToBeChecked,
|
||||
@Nullable final PsiClass... classes) {
|
||||
if (classes != null && classes.length > 0) {
|
||||
final Set<String> groupDependencies = new LinkedHashSet<String>();
|
||||
TestNGUtil.collectAnnotationValues(groupDependencies, "dependsOnGroups", methods, classes);
|
||||
final Set<PsiMember> membersToCheckNow = new LinkedHashSet<PsiMember>();
|
||||
if (!groupDependencies.isEmpty()) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
final Project project = classes[0].getProject();
|
||||
final PsiClass testAnnotation =
|
||||
JavaPsiFacade.getInstance(project).findClass(TestNGUtil.TEST_ANNOTATION_FQN, GlobalSearchScope.allScope(project));
|
||||
LOG.assertTrue(testAnnotation != null);
|
||||
for (PsiMember psiMember : AnnotatedMembersSearch.search(testAnnotation, getSearchScope())) {
|
||||
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(psiMember, TestNGUtil.TEST_ANNOTATION_FQN);
|
||||
if (TestNGUtil.isAnnotatedWithParameter(annotation, "groups", groupDependencies)) {
|
||||
if (appendMember(psiMember, alreadyMarkedToBeChecked, results)) {
|
||||
membersToCheckNow.add(psiMember);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
collectDependsOnMethods(results, alreadyMarkedToBeChecked, membersToCheckNow, methods, classes);
|
||||
|
||||
if (methods == null) {
|
||||
for (PsiClass c : classes) {
|
||||
results.put(c, new LinkedHashMap<PsiMethod, List<String>>());
|
||||
}
|
||||
} else {
|
||||
for (PsiMember psiMember : membersToCheckNow) {
|
||||
PsiClass psiClass;
|
||||
PsiMethod[] meths = null;
|
||||
if (psiMember instanceof PsiMethod) {
|
||||
psiClass = psiMember.getContainingClass();
|
||||
meths = new PsiMethod[] {(PsiMethod)psiMember};
|
||||
} else {
|
||||
psiClass = (PsiClass)psiMember;
|
||||
}
|
||||
calculateDependencies(meths, results, alreadyMarkedToBeChecked, psiClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void collectDependsOnMethods(final Map<PsiClass, Map<PsiMethod, List<String>>> results,
|
||||
final Set<PsiMember> alreadyMarkedToBeChecked,
|
||||
final Set<PsiMember> membersToCheckNow,
|
||||
final PsiMethod[] methods,
|
||||
final PsiClass... classes) {
|
||||
final PsiClass[] psiClasses;
|
||||
if (methods != null && methods.length > 0) {
|
||||
final Set<PsiClass> containingClasses = new LinkedHashSet<PsiClass>();
|
||||
for (final PsiMethod method : methods) {
|
||||
containingClasses.add(ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
|
||||
@Override
|
||||
public PsiClass compute() {
|
||||
return method.getContainingClass();
|
||||
}
|
||||
}));
|
||||
}
|
||||
psiClasses = containingClasses.toArray(new PsiClass[containingClasses.size()]);
|
||||
} else {
|
||||
psiClasses = classes;
|
||||
}
|
||||
for (final PsiClass containingClass : psiClasses) {
|
||||
final Set<String> testMethodDependencies = new LinkedHashSet<String>();
|
||||
TestNGUtil.collectAnnotationValues(testMethodDependencies, "dependsOnMethods", methods, containingClass);
|
||||
if (!testMethodDependencies.isEmpty()) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
final Project project = containingClass.getProject();
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
|
||||
for (String dependency : testMethodDependencies) {
|
||||
final String className = StringUtil.getPackageName(dependency);
|
||||
final String methodName = StringUtil.getShortName(dependency);
|
||||
if (StringUtil.isEmpty(className)) {
|
||||
checkClassMethods(methodName, containingClass, alreadyMarkedToBeChecked, membersToCheckNow, results);
|
||||
}
|
||||
else {
|
||||
final PsiClass aClass = psiFacade.findClass(className, containingClass.getResolveScope());
|
||||
if (aClass != null) {
|
||||
checkClassMethods(methodName, aClass, alreadyMarkedToBeChecked, membersToCheckNow, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkClassMethods(String methodName,
|
||||
PsiClass containingClass,
|
||||
Set<PsiMember> alreadyMarkedToBeChecked,
|
||||
Set<PsiMember> membersToCheckNow,
|
||||
Map<PsiClass, Map<PsiMethod, List<String>>> results) {
|
||||
final PsiMethod[] psiMethods = containingClass.findMethodsByName(methodName, true);
|
||||
for (PsiMethod method : psiMethods) {
|
||||
if (AnnotationUtil.isAnnotated(method, TestNGUtil.TEST_ANNOTATION_FQN, false) &&
|
||||
appendMember(method, alreadyMarkedToBeChecked, results)) {
|
||||
membersToCheckNow.add(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean appendMember(final PsiMember psiMember,
|
||||
final Set<PsiMember> underConsideration,
|
||||
final Map<PsiClass, Map<PsiMethod, List<String>>> results) {
|
||||
boolean result = false;
|
||||
final PsiClass psiClass = psiMember instanceof PsiClass ? ((PsiClass)psiMember) : psiMember.getContainingClass();
|
||||
Map<PsiMethod, List<String>> psiMethods = results.get(psiClass);
|
||||
if (psiMethods == null) {
|
||||
psiMethods = new LinkedHashMap<PsiMethod, List<String>>();
|
||||
results.put(psiClass, psiMethods);
|
||||
if (psiMember instanceof PsiClass) {
|
||||
result = underConsideration.add(psiMember);
|
||||
}
|
||||
}
|
||||
if (psiMember instanceof PsiMethod) {
|
||||
final boolean add = psiMethods.put((PsiMethod)psiMember, Collections.<String>emptyList()) != null;
|
||||
if (add) {
|
||||
return underConsideration.add(psiMember);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected GlobalSearchScope getSearchScope() {
|
||||
final TestData data = myConfig.getPersistantData();
|
||||
final Module module = myConfig.getConfigurationModule().getModule();
|
||||
return data.TEST_OBJECT.equals(TestType.PACKAGE.getType())
|
||||
? myConfig.getPersistantData().getScope().getSourceScope(myConfig).getGlobalSearchScope()
|
||||
: module != null ? GlobalSearchScope.moduleWithDependenciesScope(module) : GlobalSearchScope.projectScope(myConfig.getProject());
|
||||
}
|
||||
|
||||
protected void collectTestMethods(Map<PsiClass, Map<PsiMethod, List<String>>> 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);
|
||||
Map<PsiMethod, List<String>> psiMethods = classes.get(psiClass);
|
||||
if (psiMethods == null) {
|
||||
psiMethods = new LinkedHashMap<PsiMethod, List<String>>();
|
||||
classes.put(psiClass, psiMethods);
|
||||
}
|
||||
for (PsiMethod method : methods) {
|
||||
psiMethods.put(method, Collections.<String>emptyList());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.theoryinpractice.testng.model;
|
||||
|
||||
import com.intellij.execution.CantRunException;
|
||||
import com.intellij.execution.JavaExecutionUtil;
|
||||
import com.intellij.execution.configurations.RuntimeConfigurationException;
|
||||
import com.intellij.execution.testframework.TestSearchScope;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.PackageScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.theoryinpractice.testng.configuration.TestNGConfiguration;
|
||||
import com.theoryinpractice.testng.util.TestNGUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TestNGTestPackage extends TestNGTestObject {
|
||||
public TestNGTestPackage(TestNGConfiguration configuration) {
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillTestObjects(Map<PsiClass, Map<PsiMethod, List<String>>> classes) throws CantRunException {
|
||||
final String packageName = myConfig.getPersistantData().getPackageName();
|
||||
PsiPackage psiPackage = ApplicationManager.getApplication().runReadAction(
|
||||
new Computable<PsiPackage>() {
|
||||
@Nullable
|
||||
public PsiPackage compute() {
|
||||
return JavaPsiFacade.getInstance(myConfig.getProject()).findPackage(packageName);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (psiPackage == null) {
|
||||
throw CantRunException.packageNotFound(packageName);
|
||||
}
|
||||
else {
|
||||
TestSearchScope scope = myConfig.getPersistantData().getScope();
|
||||
//TODO we should narrow this down by module really, if that's what's specified
|
||||
TestClassFilter projectFilter =
|
||||
new TestClassFilter(scope.getSourceScope(myConfig).getGlobalSearchScope(), myConfig.getProject(), true, true);
|
||||
TestClassFilter filter = projectFilter.intersectionWith(PackageScope.packageScope(psiPackage, true));
|
||||
calculateDependencies(null, classes, TestNGUtil.getAllTestClasses(filter, false));
|
||||
if (classes.size() == 0) {
|
||||
throw new CantRunException("No tests found in the package \"" + packageName + '\"');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGeneratedName() {
|
||||
final String packageName = myConfig.getPersistantData().getPackageName();
|
||||
return packageName.length() == 0 ? "<default>" : packageName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActionName() {
|
||||
String s = myConfig.getName();
|
||||
if (!myConfig.isGeneratedName()) return '\"' + s + '\"';
|
||||
if (myConfig.getPersistantData().getPackageName().trim().length() > 0) {
|
||||
return "Tests in \"" + myConfig.getPersistantData().getPackageName() + '\"';
|
||||
}
|
||||
else {
|
||||
return "All Tests";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkConfiguration() throws RuntimeConfigurationException {
|
||||
final TestData data = myConfig.getPersistantData();
|
||||
PsiPackage psiPackage = JavaPsiFacade.getInstance(myConfig.getProject()).findPackage(data.getPackageName());
|
||||
if (psiPackage == null) throw new RuntimeConfigurationException("Package '" + data.getPackageName() + "' not found");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfiguredByElement(PsiElement element) {
|
||||
final String packageName = myConfig.getPersistantData().getPackageName();
|
||||
if (element instanceof PsiPackage) {
|
||||
return Comparing.strEqual(packageName, ((PsiPackage)element).getQualifiedName());
|
||||
} else if (element instanceof PsiDirectory) {
|
||||
final PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage(((PsiDirectory)element));
|
||||
return psiPackage != null && Comparing.strEqual(packageName, psiPackage.getQualifiedName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.theoryinpractice.testng.model;
|
||||
|
||||
import com.intellij.execution.CantRunException;
|
||||
import com.intellij.execution.configurations.RuntimeConfigurationException;
|
||||
import com.intellij.execution.configurations.RuntimeConfigurationWarning;
|
||||
import com.intellij.execution.testframework.TestSearchScope;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.util.ClassUtil;
|
||||
import com.theoryinpractice.testng.configuration.TestNGConfiguration;
|
||||
import com.theoryinpractice.testng.util.TestNGUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
public class TestNGTestPattern extends TestNGTestObject {
|
||||
private static final Logger LOG = Logger.getInstance("#" + TestNGTestPattern.class.getName());
|
||||
|
||||
public TestNGTestPattern(TestNGConfiguration config) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillTestObjects(Map<PsiClass, Map<PsiMethod, List<String>>> classes)
|
||||
throws CantRunException {
|
||||
final TestData data = myConfig.getPersistantData();
|
||||
for (final String pattern : data.getPatterns()) {
|
||||
final String className;
|
||||
final String methodName;
|
||||
if (pattern.contains(",")) {
|
||||
methodName = StringUtil.getShortName(pattern, ',');
|
||||
className = StringUtil.getPackageName(pattern, ',');
|
||||
} else {
|
||||
className = pattern;
|
||||
methodName = null;
|
||||
}
|
||||
|
||||
final PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiClass compute() {
|
||||
return ClassUtil.findPsiClass(PsiManager.getInstance(myConfig.getProject()), className.replace('/', '.'), null, true, getSearchScope());
|
||||
}
|
||||
});
|
||||
if (psiClass != null) {
|
||||
final Boolean hasTest = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
return TestNGUtil.hasTest(psiClass);
|
||||
}
|
||||
});
|
||||
if (hasTest) {
|
||||
if (StringUtil.isEmpty(methodName)) {
|
||||
calculateDependencies(null, classes, psiClass);
|
||||
}
|
||||
else {
|
||||
collectTestMethods(classes, psiClass, methodName);
|
||||
}
|
||||
} else {
|
||||
throw new CantRunException("No tests found in class " + className);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (classes.size() != data.getPatterns().size()) {
|
||||
TestSearchScope scope = myConfig.getPersistantData().getScope();
|
||||
final List<Pattern> compilePatterns = new ArrayList<Pattern>();
|
||||
for (String p : data.getPatterns()) {
|
||||
final Pattern compilePattern;
|
||||
try {
|
||||
compilePattern = Pattern.compile(p);
|
||||
}
|
||||
catch (PatternSyntaxException e) {
|
||||
continue;
|
||||
}
|
||||
if (compilePattern != null) {
|
||||
compilePatterns.add(compilePattern);
|
||||
}
|
||||
}
|
||||
TestClassFilter projectFilter =
|
||||
new TestClassFilter(scope.getSourceScope(myConfig).getGlobalSearchScope(), myConfig.getProject(), true, true){
|
||||
@Override
|
||||
public boolean isAccepted(PsiClass psiClass) {
|
||||
if (super.isAccepted(psiClass)) {
|
||||
final String qualifiedName = psiClass.getQualifiedName();
|
||||
LOG.assertTrue(qualifiedName != null);
|
||||
for (Pattern pattern : compilePatterns) {
|
||||
if (pattern.matcher(qualifiedName).matches()) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
calculateDependencies(null, classes, TestNGUtil.getAllTestClasses(projectFilter, false));
|
||||
if (classes.size() == 0) {
|
||||
throw new CantRunException("No tests found in for patterns \"" + StringUtil.join(data.getPatterns(), " || ") + '\"');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGeneratedName() {
|
||||
final Set<String> patterns = myConfig.getPersistantData().getPatterns();
|
||||
final int size = patterns.size();
|
||||
if (size == 0) return "Temp suite";
|
||||
return StringUtil.getShortName(patterns.iterator().next()) + (size > 1 ? " and " + (size - 1) + " more" : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActionName() {
|
||||
return getGeneratedName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkConfiguration() throws RuntimeConfigurationException {
|
||||
final Set<String> patterns = myConfig.getPersistantData().getPatterns();
|
||||
if (patterns.isEmpty()) {
|
||||
throw new RuntimeConfigurationWarning("No pattern selected");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.theoryinpractice.testng.model;
|
||||
|
||||
import com.intellij.execution.CantRunException;
|
||||
import com.intellij.execution.configurations.RuntimeConfigurationException;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.theoryinpractice.testng.configuration.TestNGConfiguration;
|
||||
import org.testng.xml.Parser;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TestNGTestSuite extends TestNGTestObject {
|
||||
private static final Object PARSE_LOCK = new Object();
|
||||
public TestNGTestSuite(TestNGConfiguration config) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillTestObjects(Map<PsiClass, Map<PsiMethod, List<String>>> classes) throws CantRunException {}
|
||||
|
||||
@Override
|
||||
public String getGeneratedName() {
|
||||
return myConfig.getPersistantData().getSuiteName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActionName() {
|
||||
return myConfig.getPersistantData().getSuiteName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkConfiguration() throws RuntimeConfigurationException {
|
||||
final TestData data = myConfig.getPersistantData();
|
||||
try {
|
||||
final Parser parser = new Parser(data.getSuiteName());
|
||||
parser.setLoadClasses(false);
|
||||
synchronized (PARSE_LOCK) {
|
||||
parser.parse();//try to parse suite.xml
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeConfigurationException("Unable to parse '" + data.getSuiteName() + "' specified");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user