testng: run multiple tests at once

This commit is contained in:
anna
2012-01-17 16:41:52 +01:00
parent 336d419236
commit 2db974bbc9
10 changed files with 349 additions and 34 deletions
+1
View File
@@ -8,6 +8,7 @@
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
<deadCode implementation="com.theoryinpractice.testng.inspection.TestNGEntryPoint"/>
<cantBeStatic implementation="com.theoryinpractice.testng.inspection.TestNGCanBeStaticExtension" />
<configurationProducer implementation="com.theoryinpractice.testng.configuration.TestNGPatternConfigurationProducer"/>
<configurationProducer implementation="com.theoryinpractice.testng.configuration.TestNGInClassConfigurationProducer"/>
<configurationProducer implementation="com.theoryinpractice.testng.configuration.TestNGPackageConfigurationProducer"/>
<configurationProducer implementation="com.theoryinpractice.testng.configuration.TestNGSuiteConfigurationProducer"/>
@@ -371,6 +371,30 @@ public class SearchingForTestsTask extends Task.Backgroundable {
}
}
}
else if (data.TEST_OBJECT.equals(TestType.PATTERN.getType())) {
for (final String className : data.getPatterns()) {
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) {
throw new CantRunException("Class " + className + " not found");
}
if (ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
return TestNGUtil.hasTest(psiClass);
}
})) {
calculateDependencies(null, classes, psiClass);
} else {
throw new CantRunException("No tests found in class " + className);
}
}
}
}
private Map<String, String> buildTestParameters() {
@@ -44,17 +44,21 @@ import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.listeners.UndoRefactoringElementListener;
import com.theoryinpractice.testng.model.TestData;
import com.theoryinpractice.testng.model.TestType;
import com.theoryinpractice.testng.util.TestNGUtil;
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.Collection;
import java.util.List;
import java.util.Map;
import java.util.*;
public class TestNGConfiguration extends ModuleBasedConfiguration<JavaRunConfigurationModule>
implements CommonJavaRunConfigurationParameters, RefactoringListenerProvider {
@NonNls private static final String PATTERNS_EL_NAME = "patterns";
@NonNls private static final String PATTERN_EL_NAME = "pattern";
@NonNls private static final String TEST_CLASS_ATT_NAME = "testClass";
//private TestNGResultsContainer resultsContainer;
protected TestData data;
protected transient Project project;
@@ -305,6 +309,21 @@ public class TestNGConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
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 GlobalSearchScope searchScope = GlobalSearchScope.allScope(getProject());
for (String pattern : patterns) {
final PsiClass psiClass = JavaExecutionUtil.findMainClass(getProject(), pattern, searchScope);
if (psiClass == null) {
throw new RuntimeConfigurationWarning("Class " + pattern + " not found");
}
if (!TestNGUtil.hasTest(psiClass)) {
throw new RuntimeConfigurationWarning("Class " + pattern + " not a test");
}
}
}
JavaRunConfigurationExtensionManager.checkConfigurationIsValid(this);
//TODO add various checks here
@@ -339,6 +358,15 @@ public class TestNGConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
listeners.add(listenerClassName.getAttributeValue("class"));
}
}
final Element patternsElement = element.getChild(PATTERNS_EL_NAME);
if (patternsElement != null) {
final Set<String> tests = new LinkedHashSet<String>();
for (Object o : patternsElement.getChildren(PATTERN_EL_NAME)) {
Element patternElement = (Element)o;
tests.add(patternElement.getAttributeValue(TEST_CLASS_ATT_NAME));
}
getPersistantData().setPatterns(tests);
}
}
@Override
@@ -377,6 +405,16 @@ public class TestNGConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
listenerElement.setAttribute("class", listener);
listenersElement.addContent(listenerElement);
}
final Set<String> patterns = getPersistantData().getPatterns();
if (!patterns.isEmpty()) {
final Element patternsElement = new Element(PATTERNS_EL_NAME);
for (String o : patterns) {
final Element patternElement = new Element(PATTERN_EL_NAME);
patternElement.setAttribute(TEST_CLASS_ATT_NAME, o);
patternsElement.addContent(patternElement);
}
element.addContent(patternsElement);
}
PathMacroManager.getInstance(getProject()).collapsePathsRecursively(element);
}
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.theoryinpractice.testng.configuration.TestNGConfigurationEditor">
<grid id="27dc6" binding="panel" layout-manager="GridLayoutManager" row-count="4" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="panel" layout-manager="GridLayoutManager" row-count="4" column-count="6" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="772" height="523"/>
@@ -32,10 +32,10 @@
<text value="&amp;Method"/>
</properties>
</component>
<grid id="b9bd" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="b9bd" layout-manager="GridLayoutManager" row-count="7" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="5" vsize-policy="3" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="6" vsize-policy="3" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<clientProperties>
@@ -71,7 +71,7 @@
<colspec value="left:4dlu:noGrow"/>
<colspec value="fill:max(d;4px):grow"/>
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -126,7 +126,7 @@
</component>
<component id="d1d3" class="com.intellij.openapi.ui.LabeledComponent" binding="outputDirectory">
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelLocation value="West"/>
@@ -142,11 +142,22 @@
<text value="&amp;Group"/>
</properties>
</component>
<component id="d64d9" class="com.intellij.openapi.ui.LabeledComponent" binding="myPattern">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<componentClass value="javax.swing.JPanel"/>
<labelLocation value="West"/>
<text value="Pattern"/>
<visible value="true"/>
</properties>
</component>
</children>
</grid>
<tabbedpane id="7ce0a" class="com.intellij.ui.components.JBTabbedPane" default-binding="true">
<constraints>
<grid row="2" column="0" row-span="1" col-span="5" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<grid row="2" column="0" row-span="1" col-span="6" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="200" height="200"/>
</grid>
</constraints>
@@ -390,15 +401,24 @@
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="99b4d" class="com.intellij.ui.components.JBRadioButton" binding="patternTest">
<constraints>
<grid row="0" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Pattern"/>
</properties>
</component>
</children>
</grid>
<buttonGroups>
<group name="testGroup">
<member id="dcd9c"/>
<member id="d8c06"/>
<member id="5eaf8"/>
<member id="61e8b"/>
<member id="2ab9d"/>
<member id="dcd9c"/>
<member id="d8c06"/>
<member id="99b4d"/>
</group>
</buttonGroups>
</form>
@@ -39,18 +39,18 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComponentWithBrowseButton;
import com.intellij.openapi.ui.LabeledComponent;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.ui.*;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaCodeFragment;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.PanelWithAnchor;
import com.intellij.ui.EditorTextFieldWithBrowseButton;
import com.intellij.ui.PanelWithAnchor;
import com.intellij.ui.table.TableView;
import com.intellij.util.PlatformIcons;
import com.intellij.util.TextFieldCompletionProvider;
import com.theoryinpractice.testng.MessageInfoException;
import com.theoryinpractice.testng.configuration.browser.*;
@@ -62,6 +62,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
import java.awt.*;
import java.awt.event.ActionEvent;
@@ -84,6 +85,7 @@ public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguratio
private JRadioButton classTest;
private JRadioButton methodTest;
private JRadioButton groupTest;
private JRadioButton patternTest;
private final TestNGConfigurationModel model;
private LabeledComponent<EditorTextFieldWithBrowseButton> methodField;
private LabeledComponent<EditorTextFieldWithBrowseButton> packageField;
@@ -105,6 +107,8 @@ public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguratio
private JList listenersTable;
private JButton removeListener;
private JCheckBox myUseDefaultReportersCheckBox;
private LabeledComponent<JPanel> myPattern;
TextFieldWithBrowseButton myPatternTextField;
private final CommonJavaParametersPanel commonJavaParameters = new CommonJavaParametersPanel();
private ArrayList<Map.Entry> propertiesList;
private TestNGListenersTableModel listenerModel;
@@ -114,7 +118,20 @@ public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguratio
public TestNGConfigurationEditor(Project project) {
this.project = project;
BrowseModuleValueActionListener[] browseListeners = new BrowseModuleValueActionListener[] {new PackageBrowser(project),
new TestClassBrowser(project, this), new MethodBrowser(project, this), new GroupBrowser(project, this), new SuiteBrowser(project)};
new TestClassBrowser(project, this), new MethodBrowser(project, this), new GroupBrowser(project, this), new SuiteBrowser(project),
new TestClassBrowser(project, this){
@Override
protected void onClassChoosen(PsiClass psiClass) {
final JTextField textField = myPatternTextField.getTextField();
final String text = textField.getText();
textField.setText(text + (text.length() > 0 ? "||" : "") + psiClass.getQualifiedName());
}
@Override
public void actionPerformed(ActionEvent e) {
showDialog();
}
}};
model = new TestNGConfigurationModel(project);
model.setListener(this);
createView();
@@ -125,7 +142,22 @@ public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguratio
commonJavaParameters.setModuleContext(moduleSelector.getModule());
}
});
registerListener(new JRadioButton[] {packageTest, classTest, methodTest, groupTest, suiteTest}, new ChangeListener()
final JPanel panel = myPattern.getComponent();
panel.setLayout(new BorderLayout());
myPatternTextField = new TextFieldWithBrowseButton();
myPatternTextField.setButtonIcon(PlatformIcons.ADD_ICON);
panel.add(myPatternTextField, BorderLayout.CENTER);
final FixedSizeButton editBtn = new FixedSizeButton();
editBtn.setIcon(IconLoader.getIcon("/actions/showViewer.png"));
editBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Messages.showTextAreaDialog(myPatternTextField.getTextField(), "Configure suite tests", "EditParametersPopupWindow");
}
});
panel.add(editBtn, BorderLayout.EAST);
registerListener(new JRadioButton[] {packageTest, classTest, methodTest, groupTest, suiteTest, patternTest}, new ChangeListener()
{
public void stateChanged(ChangeEvent e) {
ButtonModel buttonModel = (ButtonModel) e.getSource();
@@ -140,6 +172,8 @@ public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguratio
model.setType(TestType.GROUP);
} else if (buttonModel == suiteTest.getModel()) {
model.setType(TestType.SUITE);
} else if (buttonModel == patternTest.getModel()) {
model.setType(TestType.PATTERN);
}
redisplay();
}
@@ -153,17 +187,26 @@ public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguratio
}
});
LabeledComponent[] components = new LabeledComponent[] {packageField, classField, methodField, groupField, suiteField};
LabeledComponent[] components = new LabeledComponent[] {packageField, classField, methodField, groupField, suiteField, myPattern};
for (int i = 0; i < components.length; i++) {
ComponentWithBrowseButton field = (ComponentWithBrowseButton)components[i].getComponent();
JComponent field = components[i].getComponent();
Object document = model.getDocument(i);
if (field instanceof TextFieldWithBrowseButton) {
((TextFieldWithBrowseButton)field).getTextField().setDocument((PlainDocument)document);
} else {
final com.intellij.openapi.editor.Document componentDocument = ((EditorTextFieldWithBrowseButton)field).getChildComponent().getDocument();
}
else if (field instanceof EditorTextFieldWithBrowseButton) {
final com.intellij.openapi.editor.Document componentDocument =
((EditorTextFieldWithBrowseButton)field).getChildComponent().getDocument();
model.setDocument(i, componentDocument);
}
browseListeners[i].setField(field);
else {
field = myPatternTextField;
document = new PlainDocument();
((TextFieldWithBrowseButton)field).getTextField().setDocument((Document)document);
model.setDocument(i, document);
}
browseListeners[i].setField((ComponentWithBrowseButton)field);
}
model.setType(TestType.CLASS);
addListener.addActionListener(new AddTestListenerListener());
@@ -198,30 +241,42 @@ public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguratio
methodField.setVisible(false);
groupField.setVisible(false);
suiteField.setVisible(false);
myPattern.setVisible(false);
} else if (classTest.isSelected()) {
packagePanel.setVisible(false);
classField.setVisible(true);
methodField.setVisible(false);
groupField.setVisible(false);
suiteField.setVisible(false);
myPattern.setVisible(false);
} else if (methodTest.isSelected()) {
packagePanel.setVisible(false);
classField.setVisible(true);
methodField.setVisible(true);
groupField.setVisible(false);
suiteField.setVisible(false);
myPattern.setVisible(false);
} else if (groupTest.isSelected()) {
packagePanel.setVisible(false);
classField.setVisible(false);
methodField.setVisible(false);
groupField.setVisible(true);
suiteField.setVisible(false);
myPattern.setVisible(false);
} else if (suiteTest.isSelected()) {
packagePanel.setVisible(false);
classField.setVisible(false);
methodField.setVisible(false);
groupField.setVisible(false);
suiteField.setVisible(true);
myPattern.setVisible(false);
} else if (patternTest.isSelected()) {
packagePanel.setVisible(false);
classField.setVisible(false);
methodField.setVisible(false);
groupField.setVisible(false);
suiteField.setVisible(false);
myPattern.setVisible(true);
}
}
@@ -333,6 +388,8 @@ public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguratio
groupTest.setEnabled(true);
classTest.setSelected(false);
classTest.setEnabled(true);
patternTest.setSelected(false);
patternTest.setEnabled(true);
classField.setComponent(new EditorTextFieldWithBrowseButton(project, true, new JavaCodeFragment.VisibilityChecker() {
@Override
@@ -444,6 +501,7 @@ public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguratio
methodField.setEnabled(false);
groupField.setEnabled(false);
suiteField.setEnabled(false);
myPattern.setEnabled(false);
} else if (type == TestType.CLASS) {
classTest.setSelected(true);
packageField.setEnabled(false);
@@ -451,6 +509,7 @@ public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguratio
methodField.setEnabled(false);
groupField.setEnabled(false);
suiteField.setEnabled(false);
myPattern.setEnabled(false);
} else if (type == TestType.METHOD) {
methodTest.setSelected(true);
packageField.setEnabled(false);
@@ -458,6 +517,7 @@ public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguratio
methodField.setEnabled(true);
groupField.setEnabled(false);
suiteField.setEnabled(false);
myPattern.setEnabled(false);
} else if (type == TestType.GROUP) {
groupTest.setSelected(true);
groupField.setEnabled(true);
@@ -465,6 +525,7 @@ public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguratio
classField.setEnabled(false);
methodField.setEnabled(false);
suiteField.setEnabled(false);
myPattern.setEnabled(false);
} else if (type == TestType.SUITE) {
suiteTest.setSelected(true);
suiteField.setEnabled(true);
@@ -472,6 +533,15 @@ public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguratio
classField.setEnabled(false);
methodField.setEnabled(false);
groupField.setEnabled(false);
myPattern.setEnabled(false);
} else if (type == TestType.PATTERN) {
patternTest.setSelected(true);
myPattern.setEnabled(true);
suiteField.setEnabled(false);
packageField.setEnabled(false);
classField.setEnabled(false);
methodField.setEnabled(false);
groupField.setEnabled(false);
}
}
@@ -22,6 +22,7 @@ package com.theoryinpractice.testng.configuration;
import com.intellij.execution.*;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -39,6 +40,11 @@ public class TestNGInClassConfigurationProducer extends TestNGConfigurationProdu
@Nullable
protected RunnerAndConfigurationSettings createConfigurationByElement(Location location, ConfigurationContext context) {
final PsiElement[] elements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(context.getDataContext());
if (elements != null && TestNGPatternConfigurationProducer.collectTestClasses(elements).size() > 1) {
return null;
}
PsiClass psiClass = null;
PsiElement element = location.getPsiElement();
while (element != null) {
@@ -0,0 +1,129 @@
/*
* Copyright 2000-2012 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.
*/
/*
* User: anna
* Date: 23-May-2007
*/
package com.theoryinpractice.testng.configuration;
import com.intellij.execution.JavaRunConfigurationExtensionManager;
import com.intellij.execution.Location;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.execution.junit.JUnitUtil;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassOwner;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.theoryinpractice.testng.model.TestData;
import com.theoryinpractice.testng.model.TestType;
import com.theoryinpractice.testng.util.TestNGUtil;
import org.jetbrains.annotations.NotNull;
import java.util.LinkedHashSet;
import java.util.Set;
public class TestNGPatternConfigurationProducer extends TestNGConfigurationProducer{
private PsiElement[] myElements;
public int compareTo(Object o) {
return PREFERED;
}
protected RunnerAndConfigurationSettings createConfigurationByElement(final Location location, final ConfigurationContext context) {
final Project project = location.getProject();
final LinkedHashSet<String> classes = new LinkedHashSet<String>();
myElements = collectPatternElements(context, classes);
if (classes.size() <= 1) return null;
RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(project, context);
final TestNGConfiguration configuration = (TestNGConfiguration)settings.getConfiguration();
final TestData data = configuration.getPersistantData();
data.getPatterns().addAll(classes);
data.TEST_OBJECT = TestType.PATTERN.getType();
data.setScope(setupPackageConfiguration(context, project, configuration, data.getScope()));
configuration.setGeneratedName();
JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location);
return settings;
}
static Set<PsiClass> collectTestClasses(PsiElement[] psiElements) {
final Set<PsiClass> foundClasses = new LinkedHashSet<PsiClass>();
for (PsiElement psiElement : psiElements) {
if (psiElement instanceof PsiClassOwner) {
final PsiClass[] classes = ((PsiClassOwner)psiElement).getClasses();
for (PsiClass aClass : classes) {
if (JUnitUtil.isTestClass(aClass)) {
foundClasses.add(aClass);
}
}
} else if (psiElement instanceof PsiClass) {
if (TestNGUtil.hasTest((PsiClass)psiElement)) {
foundClasses.add((PsiClass)psiElement);
}
}
}
return foundClasses;
}
private static PsiElement[] collectPatternElements(ConfigurationContext context, LinkedHashSet<String> classes) {
final DataContext dataContext = context.getDataContext();
PsiElement[] elements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext);
if (elements != null) {
for (PsiClass psiClass : collectTestClasses(elements)) {
classes.add(psiClass.getQualifiedName());
}
return elements;
} else {
final PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext);
if (file instanceof PsiClassOwner) {
for (PsiClass psiClass : collectTestClasses(((PsiClassOwner)file).getClasses())) {
classes.add(psiClass.getQualifiedName());
}
return new PsiElement[]{file};
}
}
return null;
}
public PsiElement getSourceElement() {
return myElements[0];
}
@Override
protected RunnerAndConfigurationSettings findExistingByElement(@NotNull Location location,
@NotNull RunnerAndConfigurationSettings[] existingConfigurations,
ConfigurationContext context) {
final LinkedHashSet<String> classes = new LinkedHashSet<String>();
collectPatternElements(context, classes);
for (RunnerAndConfigurationSettings existingConfiguration : existingConfigurations) {
final TestNGConfiguration unitConfiguration = (TestNGConfiguration)existingConfiguration.getConfiguration();
final String type = unitConfiguration.getPersistantData().TEST_OBJECT;
if (Comparing.equal(type, TestType.PATTERN.getType())) {
if (Comparing.equal(classes, unitConfiguration.getPersistantData().getPatterns())) {
return existingConfiguration;
}
}
}
return null;
}
}
@@ -24,6 +24,7 @@ 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;
@@ -55,6 +56,7 @@ public class TestData implements Cloneable
public List<String> TEST_LISTENERS = new ArrayList<String>();
public boolean USE_DEFAULT_REPORTERS = false;
public String PROPERTIES_FILE;
private Set<String> myPatterns = new HashSet<String>();
public TestData() {
TEST_OBJECT = TestType.CLASS.getType();
@@ -132,6 +134,7 @@ public class TestData implements Cloneable
&& Comparing.equal(OUTPUT_DIRECTORY, data.OUTPUT_DIRECTORY)
&& Comparing.equal(VM_PARAMETERS, data.VM_PARAMETERS)
&& Comparing.equal(PARAMETERS, data.PARAMETERS)
&& Comparing.equal(myPatterns, data.myPatterns)
&& USE_DEFAULT_REPORTERS == data.USE_DEFAULT_REPORTERS;
}
}
@@ -147,7 +150,8 @@ public class TestData implements Cloneable
Comparing.hashcode(OUTPUT_DIRECTORY) ^
Comparing.hashcode(VM_PARAMETERS) ^
Comparing.hashcode(PARAMETERS) ^
Comparing.hashcode(USE_DEFAULT_REPORTERS);
Comparing.hashcode(USE_DEFAULT_REPORTERS) ^
Comparing.hashcode(myPatterns);
}
@Override
@@ -163,6 +167,8 @@ public class TestData implements Cloneable
data.USE_DEFAULT_REPORTERS = USE_DEFAULT_REPORTERS;
data.ENVS = new LinkedHashMap<String, String>(ENVS);
data.myPatterns = new HashSet<String>();
data.myPatterns.addAll(myPatterns);
data.setScope(getScope());
return data;
}
@@ -187,6 +193,11 @@ public class TestData implements Cloneable
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;
}
}
@@ -242,4 +253,12 @@ public class TestData implements Cloneable
public void setEnvs(final Map<String, String> envs) {
ENVS = envs;
}
public Set<String> getPatterns() {
return myPatterns;
}
public void setPatterns(Set<String> set) {
myPatterns = set;
}
}
@@ -17,26 +17,19 @@ package com.theoryinpractice.testng.model;
import com.intellij.execution.JavaExecutionUtil;
import com.intellij.execution.junit.JUnitUtil;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.editor.markup.MarkupModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiClass;
import com.theoryinpractice.testng.configuration.TestNGConfiguration;
import com.theoryinpractice.testng.configuration.TestNGConfigurationEditor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
import java.beans.PropertyChangeListener;
import java.util.LinkedHashSet;
/**
* @author Hani Suleiman Date: Jul 21, 2005 Time: 1:20:14 PM
@@ -47,7 +40,7 @@ public class TestNGConfigurationModel
private TestNGConfigurationEditor editor;
private TestType type;
private final Object[] typeDocuments = new Object[5];
private final Object[] typeDocuments = new Object[6];
private final Document propertiesFileDocument = new PlainDocument();
private final Document outputDirectoryDocument = new PlainDocument();
private final Project project;
@@ -60,7 +53,7 @@ public class TestNGConfigurationModel
this.project = project;
}
public void setDocument(int type, com.intellij.openapi.editor.Document doc) {
public void setDocument(int type, Object doc) {
typeDocuments[type] = doc;
}
@@ -138,6 +131,16 @@ public class TestNGConfigurationModel
data.MAIN_CLASS_NAME = "";
data.METHOD_NAME = "";
}
else if (TestType.PATTERN == type) {
final LinkedHashSet<String> set = new LinkedHashSet<String>();
final String[] patterns = getText(TestType.PATTERN).split("\\|\\|");
for (String pattern : patterns) {
if (pattern.length() > 0) {
set.add(pattern);
}
}
data.setPatterns(set);
}
try {
data.PROPERTIES_FILE = propertiesFileDocument.getText(0, propertiesFileDocument.getLength());
@@ -177,6 +180,7 @@ public class TestNGConfigurationModel
setTypeValue(TestType.METHOD, data.getMethodName());
setTypeValue(TestType.GROUP, data.getGroupName());
setTypeValue(TestType.SUITE, data.getSuiteName());
setTypeValue(TestType.PATTERN, StringUtil.join(data.getPatterns(), "||"));
setDocumentText(propertiesFileDocument, data.getPropertiesFile());
setDocumentText(outputDirectoryDocument, data.getOutputDirectory());
@@ -30,6 +30,7 @@ public class TestType
public static final TestType METHOD = new TestType("METHOD", 2);
public static final TestType GROUP = new TestType("GROUP", 3);
public static final TestType SUITE = new TestType("SUITE", 4);
public static final TestType PATTERN = new TestType("PATTERN", 5);
public final String type;
public final int value;
@@ -73,6 +74,9 @@ public class TestType
{
return SUITE;
}
if (PATTERN.type.equals(type)) {
return PATTERN;
}
throw new IllegalArgumentException("Invalid type requested " + type);
}
}