<orderEntry type="module" module-name="java-indexing-api" />
<orderEntry type="module" module-name="smRunner" />
<orderEntry type="library" name="Coverage" level="project" />
+ <orderEntry type="library" name="JUnit3" level="project" />
</component>
<component name="copyright">
<Base>
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.execution.testDiscovery.JavaAutoRunManager;
import com.intellij.execution.testframework.*;
import com.intellij.execution.testframework.actions.AbstractRerunFailedTestsAction;
+import com.intellij.execution.testframework.autotest.AbstractAutoTestManager;
+import com.intellij.execution.testframework.autotest.ToggleAutoTestAction;
import com.intellij.execution.testframework.sm.SMTestRunnerConnectionUtil;
import com.intellij.execution.testframework.sm.runner.SMRunnerConsolePropertiesProvider;
import com.intellij.execution.testframework.sm.runner.SMTRunnerConsoleProperties;
rerunFailedTestsAction.setModelProvider(() -> viewer);
final DefaultExecutionResult result = new DefaultExecutionResult(consoleView, handler);
- result.setRestartActions(rerunFailedTestsAction);
+ result.setRestartActions(rerunFailedTestsAction, new ToggleAutoTestAction() {
+ @Override
+ public AbstractAutoTestManager getAutoTestManager(Project project) {
+ return JavaAutoRunManager.getInstance(project);
+ }
+ });
JavaRunConfigurationExtensionManager.getInstance().attachExtensionsToProcess(getConfiguration(), handler, runnerSettings);
return result;
--- /dev/null
+/*
+ * Copyright 2000-2016 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.intellij.execution.testDiscovery;
+
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.vfs.VirtualFile;
+
+public class ConfigureTestDiscoveryAction extends AnAction {
+ @Override
+ public void update(AnActionEvent e) {
+ e.getPresentation().setEnabledAndVisible(Registry.is("testDiscovery.enabled") && e.getProject() != null);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final FileChooserDescriptor folderDescriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
+ folderDescriptor.setTitle("Choose External Discovery Index Directory");
+ folderDescriptor.setDescription("Local directory with indices retrieved from CI \n" +
+ "to be replaced within TeamCity IDEA plugin");
+ final VirtualFile virtualFile = FileChooser.chooseFile(folderDescriptor, e.getProject(), null);
+ if (virtualFile != null) {
+ TestDiscoveryIndex.getInstance(e.getProject()).setRemoteTestRunDataPath(virtualFile.getPath());
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2016 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.intellij.execution.testDiscovery;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.util.Alarm;
+import com.intellij.util.ArrayUtil;
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestListener;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Used in TestAll to collect data in command line
+ */
+@SuppressWarnings("unused")
+public class InternalTestDiscoveryListener implements TestListener, Closeable {
+ private List<String> myCompletedMethodNames = new ArrayList<String>();
+ private String myTracesDirectory;
+ private final Alarm myProcessTracesAlarm;
+ private TestDiscoveryIndex myDiscoveryIndex;
+
+ public InternalTestDiscoveryListener() {
+ myProcessTracesAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, null);
+ myTracesDirectory = System.getProperty("org.jetbrains.instrumentation.trace.dir");
+ }
+
+ private TestDiscoveryIndex getIndex() {
+ if (myDiscoveryIndex == null) {
+ final Project project = ProjectManager.getInstance().getDefaultProject();
+ try {
+ myDiscoveryIndex = (TestDiscoveryIndex)Class.forName(TestDiscoveryIndex.class.getName())
+ .getConstructor(Project.class, String.class)
+ .newInstance(project, myTracesDirectory);
+ }
+ catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ return myDiscoveryIndex;
+ }
+
+ @Override
+ public void addError(Test test, Throwable t) {}
+
+ @Override
+ public void addFailure(Test test, AssertionFailedError t) {}
+
+ @Override
+ public void endTest(Test test) {
+ final String className = getClassName(test);
+ final String methodName = getMethodName(test);
+
+ try {
+ final Object data = getData();
+ Method testEnded = data.getClass().getMethod("testDiscoveryEnded", new Class[] {String.class});
+ testEnded.invoke(data, new Object[] {"j" + className + "-" + methodName});
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+
+ myCompletedMethodNames.add("j" + className + "." + methodName);
+
+ if (myCompletedMethodNames.size() > 50) {
+ flushCurrentTraces();
+ }
+ }
+
+ protected void flushCurrentTraces() {
+ final String[] fullTestNames = ArrayUtil.toStringArray(myCompletedMethodNames);
+ myCompletedMethodNames.clear();
+ myProcessTracesAlarm.addRequest(() -> {
+ TestDiscoveryExtension.processAvailableTraces(fullTestNames, myTracesDirectory, null, getIndex());
+ }, 100);
+ }
+
+ private static String getMethodName(Test test) {
+ final String toString = test.toString();
+ final int braceIdx = toString.indexOf("(");
+ return braceIdx > 0 ? toString.substring(0, braceIdx) : toString;
+ }
+
+ private static String getClassName(Test test) {
+ final String toString = test.toString();
+ final int braceIdx = toString.indexOf("(");
+ return braceIdx > 0 && toString.endsWith(")") ? toString.substring(braceIdx + 1, toString.length() - 1) : null;
+ }
+
+ @Override
+ public void startTest(Test test) {
+ try {
+ final Object data = getData();
+ Method testStarted = data.getClass().getMethod("testDiscoveryStarted", new Class[] {String.class});
+ testStarted.invoke(data, new Object[] {getClassName(test) + "-" + getMethodName(test)});
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ protected Object getData() throws Exception {
+ return Class.forName("com.intellij.rt.coverage.data.ProjectData")
+ .getMethod("getProjectData", new Class[0])
+ .invoke(null, new Object[0]);
+ }
+
+ @Override
+ public void close() throws IOException {
+ myProcessTracesAlarm.cancelAllRequests();
+ myProcessTracesAlarm.addRequest(() -> {
+ flushCurrentTraces();
+ Disposer.dispose(myProcessTracesAlarm);
+ }, 0);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2016 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.intellij.execution.testDiscovery;
+
+import com.intellij.execution.testframework.autotest.AbstractAutoTestManager;
+import com.intellij.execution.testframework.autotest.AutoTestWatcher;
+import com.intellij.openapi.compiler.CompilationStatusListener;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.components.State;
+import com.intellij.openapi.components.Storage;
+import com.intellij.openapi.components.StoragePathMacros;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+@State(
+ name = "JavaAutoRunManager",
+ storages = {@Storage(StoragePathMacros.WORKSPACE_FILE)}
+)
+public class JavaAutoRunManager extends AbstractAutoTestManager {
+ @NotNull
+ public static JavaAutoRunManager getInstance(Project project) {
+ return ServiceManager.getService(project, JavaAutoRunManager.class);
+ }
+
+ public JavaAutoRunManager(@NotNull Project project) {
+ super(project);
+ }
+
+ @NotNull
+ @Override
+ protected AutoTestWatcher createWatcher(Project project) {
+ return new AutoTestWatcher() {
+ private boolean myHasErrors = false;
+
+ private CompilationStatusListener myStatusListener;
+
+
+ @Override
+ public void activate() {
+ if (myStatusListener == null) {
+ myStatusListener = new CompilationStatusListener() {
+ @Override
+ public void compilationFinished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
+ if (errors == 0) {
+ restartAllAutoTests(0);
+ }
+ myHasErrors = errors == 0;
+ }
+
+ @Override
+ public void automakeCompilationFinished(int errors, int warnings, CompileContext compileContext) {
+ compilationFinished(false, errors, warnings, compileContext);
+ }
+
+ @Override
+ public void fileGenerated(String outputRoot, String relativePath) {
+ int a = 1;
+ }
+ };
+
+ CompilerManager.getInstance(project).addCompilationStatusListener(myStatusListener, project);
+ }
+ }
+
+ @Override
+ public void deactivate() {
+ if (myStatusListener != null) {
+ CompilerManager.getInstance(project).removeCompilationStatusListener(myStatusListener);
+ }
+ }
+
+ @Override
+ public boolean isUpToDate(int modificationStamp) {
+ return !myHasErrors;
+ }
+ };
+ }
+}
+++ /dev/null
-/*
- * Copyright 2000-2016 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.intellij.execution.testDiscovery;
-
-import com.intellij.application.options.ModulesComboBox;
-import com.intellij.execution.ExecutionBundle;
-import com.intellij.execution.MethodBrowser;
-import com.intellij.execution.ui.*;
-import com.intellij.ide.util.ClassFilter;
-import com.intellij.openapi.fileTypes.PlainTextLanguage;
-import com.intellij.openapi.options.SettingsEditor;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.ComboBox;
-import com.intellij.openapi.ui.LabeledComponent;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.vcs.changes.ChangeListManager;
-import com.intellij.openapi.vcs.changes.LocalChangeList;
-import com.intellij.psi.JavaCodeFragment;
-import com.intellij.psi.JavaPsiFacade;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.ui.EditorTextFieldWithBrowseButton;
-import com.intellij.ui.PanelWithAnchor;
-import com.intellij.util.ui.JBUI;
-import com.intellij.util.ui.UIUtil;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.List;
-
-import static java.awt.GridBagConstraints.*;
-
-
-public class TestDiscoveryConfigurable<T extends TestDiscoveryConfiguration> extends SettingsEditor<T> implements PanelWithAnchor {
- private final ConfigurationModuleSelector myModuleSelector;
- // Fields
- private JPanel myWholePanel = new JPanel(new BorderLayout());
- private LabeledComponent<ModulesComboBox> myModule = new LabeledComponent<ModulesComboBox>();
- private CommonJavaParametersPanel myCommonJavaParameters = new CommonJavaParametersPanel();
- private JrePathEditor myJrePathEditor;
- private LabeledComponent<EditorTextFieldWithBrowseButton> myClass = new LabeledComponent<EditorTextFieldWithBrowseButton>();
- private LabeledComponent<EditorTextFieldWithBrowseButton> myMethod = new LabeledComponent<EditorTextFieldWithBrowseButton>();
-
- private ComboBox myChangeLists = new ComboBox();
- private JRadioButton myPositionRb = new JRadioButton("Tests for method:");
- private JRadioButton myChangesRb = new JRadioButton("Tests for change list:");
- private JComponent anchor;
-
- public TestDiscoveryConfigurable(final Project project) {
- myModule.setText(ExecutionBundle.message("application.configuration.use.classpath.and.jdk.of.module.label"));
- myModule.setLabelLocation(BorderLayout.WEST);
- myModule.setComponent(new ModulesComboBox());
- myModuleSelector = new ConfigurationModuleSelector(project, getModulesComponent());
- myCommonJavaParameters.setModuleContext(myModuleSelector.getModule());
- myCommonJavaParameters.setHasModuleMacro();
- myModule.getComponent().addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- myCommonJavaParameters.setModuleContext(myModuleSelector.getModule());
- }
- });
- final JPanel panelWithSettings = new JPanel(new GridBagLayout());
- final GridBagConstraints gc = new GridBagConstraints(0, RELATIVE, 1, 1, 1, 0, NORTHWEST, HORIZONTAL, JBUI.emptyInsets(), 0, 0);
- panelWithSettings.add(myPositionRb, gc);
- myClass.setText("Class:");
- final ClassBrowser classBrowser = new ClassBrowser(project, "Choose Class") {
- @Override
- protected ClassFilter.ClassFilterWithScope getFilter() throws NoFilterException {
- return new ClassFilter.ClassFilterWithScope() {
- @Override
- public GlobalSearchScope getScope() {
- return GlobalSearchScope.allScope(project);
- }
-
- @Override
- public boolean isAccepted(PsiClass aClass) {
- return true;
- }
- };
- }
-
- @Override
- protected PsiClass findClass(String className) {
- return JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project));
- }
- };
- final EditorTextFieldWithBrowseButton classComponent = new EditorTextFieldWithBrowseButton(project, true);
- myClass.setComponent(classComponent);
- classBrowser.setField(classComponent);
- panelWithSettings.add(myClass, gc);
- myMethod.setText("Method:");
- final EditorTextFieldWithBrowseButton textFieldWithBrowseButton = new EditorTextFieldWithBrowseButton(project, true,
- JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE,
- PlainTextLanguage.INSTANCE.getAssociatedFileType());
- myMethod.setComponent(textFieldWithBrowseButton);
- final MethodBrowser methodBrowser = new MethodBrowser(project) {
- protected Condition<PsiMethod> getFilter(final PsiClass testClass) {
- return method -> method.getContainingClass() == testClass;
- }
-
- @Override
- protected String getClassName() {
- return myClass.getComponent().getText().trim();
- }
-
- @Override
- protected ConfigurationModuleSelector getModuleSelector() {
- return myModuleSelector;
- }
- };
- methodBrowser.setField(textFieldWithBrowseButton);
- methodBrowser.installCompletion(textFieldWithBrowseButton.getChildComponent());
-
- panelWithSettings.add(myMethod, gc);
- panelWithSettings.add(myChangesRb, gc);
- panelWithSettings.add(myChangeLists, gc);
-
- ButtonGroup gr = new ButtonGroup();
- gr.add(myPositionRb);
- gr.add(myChangesRb);
-
- final ActionListener l = new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- updateComponents();
- }
- };
- myPositionRb.addActionListener(l);
- myChangesRb.addActionListener(l);
-
-
- final List<LocalChangeList> changeLists = ChangeListManager.getInstance(project).getChangeLists();
- final DefaultComboBoxModel model = new DefaultComboBoxModel();
- model.addElement("All");
- for (LocalChangeList changeList : changeLists) {
- model.addElement(changeList.getName());
- }
- myChangeLists.setModel(model);
- ChangeListManager changeListManager = ChangeListManager.getInstance(project);
- if (changeListManager.getAffectedFiles().isEmpty()) {
- myChangesRb.setEnabled(false);
- }
-
- myWholePanel.add(panelWithSettings, BorderLayout.NORTH);
- myWholePanel.add(myCommonJavaParameters, BorderLayout.CENTER);
- final JPanel classpathPanel = new JPanel(new BorderLayout());
- myWholePanel.add(classpathPanel, BorderLayout.SOUTH);
-
- classpathPanel.add(myModule, BorderLayout.NORTH);
- myJrePathEditor = new JrePathEditor(DefaultJreSelector.fromModuleDependencies(getModulesComponent(), false));
- classpathPanel.add(myJrePathEditor, BorderLayout.CENTER);
- UIUtil.setEnabled(myCommonJavaParameters.getProgramParametersComponent(), false, true);
-
- setAnchor(myModule.getLabel());
- myJrePathEditor.setAnchor(myModule.getLabel());
- myCommonJavaParameters.setAnchor(myModule.getLabel());
- }
-
- private void updateComponents() {
- myClass.setEnabled(myPositionRb.isSelected());
- myMethod.setEnabled(myPositionRb.isSelected());
- myChangeLists.setEnabled(myChangesRb.isSelected());
- }
-
- public void applyEditorTo(final TestDiscoveryConfiguration configuration) {
- applyHelpersTo(configuration);
- configuration.setAlternativeJrePath(myJrePathEditor.getJrePathOrName());
- configuration.setAlternativeJrePathEnabled(myJrePathEditor.isAlternativeJreSelected());
- configuration.setPosition(myPositionRb.isSelected() ? Pair.create(myClass.getComponent().getText().trim(),
- myMethod.getComponent().getText().trim()) : null);
- if (myChangesRb.isSelected()) {
- final Object selectedItem = myChangeLists.getSelectedItem();
- configuration.setChangeList("All".equals(selectedItem) ? null : (String)selectedItem);
- }
- else {
- configuration.setChangeList(null);
- }
- myCommonJavaParameters.applyTo(configuration);
- }
-
- public void resetEditorFrom(final TestDiscoveryConfiguration configuration) {
- myCommonJavaParameters.reset(configuration);
- getModuleSelector().reset(configuration);
- myJrePathEditor
- .setPathOrName(configuration.getAlternativeJrePath(), configuration.isAlternativeJrePathEnabled());
- final Pair<String, String> position = configuration.getPosition();
- if (position != null) {
- myPositionRb.setSelected(true);
- myClass.getComponent().setText(position.first);
- myMethod.getComponent().setText(position.second);
- }
- else if (myChangesRb.isEnabled()) {
- myChangesRb.setSelected(true);
- }
- else {
- myPositionRb.setSelected(true);
- }
- final String changeList = configuration.getChangeList();
- if (changeList != null) {
- myChangeLists.setSelectedItem(changeList);
- }
- else if (myChangesRb.isEnabled()) {
- myChangeLists.setSelectedIndex(0);
- }
- updateComponents();
- }
-
- public ModulesComboBox getModulesComponent() {
- return myModule.getComponent();
- }
-
- public ConfigurationModuleSelector getModuleSelector() {
- return myModuleSelector;
- }
-
- @Override
- public JComponent getAnchor() {
- return anchor;
- }
-
- @Override
- public void setAnchor(JComponent anchor) {
- this.anchor = anchor;
- }
-
-
- @NotNull
- public JComponent createEditor() {
- return myWholePanel;
- }
-
- private void applyHelpersTo(final TestDiscoveryConfiguration currentState) {
- myCommonJavaParameters.applyTo(currentState);
- getModuleSelector().applyTo(currentState);
- }
-}
+++ /dev/null
-/*
- * 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.intellij.execution.testDiscovery;
-
-import com.intellij.diagnostic.logging.LogConfigurationPanel;
-import com.intellij.execution.ExecutionBundle;
-import com.intellij.execution.Executor;
-import com.intellij.execution.JavaRunConfigurationExtensionManager;
-import com.intellij.execution.JavaTestConfigurationBase;
-import com.intellij.execution.configurations.ConfigurationFactory;
-import com.intellij.execution.configurations.JavaRunConfigurationModule;
-import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.execution.configurations.RuntimeConfigurationException;
-import com.intellij.execution.testframework.sm.runner.SMTRunnerConsoleProperties;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.options.SettingsEditor;
-import com.intellij.openapi.options.SettingsEditorGroup;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.WriteExternalException;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vcs.changes.ChangeListManager;
-import org.jdom.Element;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Map;
-
-public abstract class TestDiscoveryConfiguration extends JavaTestConfigurationBase {
- private String myChangeList;
- private Pair<String, String> myPosition;
-
- protected JavaTestConfigurationBase myDelegate;
-
- public TestDiscoveryConfiguration(String name,
- @NotNull JavaRunConfigurationModule configurationModule,
- @NotNull ConfigurationFactory factory,
- JavaTestConfigurationBase delegate) {
- super(name, configurationModule, factory);
- myDelegate = delegate;
- }
-
- @Override
- public void setVMParameters(String value) {
- myDelegate.setVMParameters(value);
- }
-
- @Override
- public String getVMParameters() {
- return myDelegate.getVMParameters();
- }
-
- @Override
- public boolean isAlternativeJrePathEnabled() {
- return myDelegate.isAlternativeJrePathEnabled();
- }
-
- @Override
- public void setAlternativeJrePathEnabled(boolean enabled) {
- myDelegate.setAlternativeJrePathEnabled(enabled);
- }
-
- @Override
- @Nullable
- public String getAlternativeJrePath() {
- return myDelegate.getAlternativeJrePath();
- }
-
- @Override
- public void setAlternativeJrePath(String path) {
- myDelegate.setAlternativeJrePath(path);
- }
-
- @Override
- public void checkConfiguration() throws RuntimeConfigurationException {
- if (myPosition == null &&
- myChangeList != null && ChangeListManager.getInstance(getProject()).findChangeList(myChangeList) == null) {
- throw new RuntimeConfigurationException("Change list " + myChangeList + " doesn't exist");
- }
- if (myPosition != null) {
- if (StringUtil.isEmptyOrSpaces(myPosition.first)) {
- throw new RuntimeConfigurationException("No class specified");
- }
- if (StringUtil.isEmptyOrSpaces(myPosition.second)) {
- throw new RuntimeConfigurationException("No method specified");
- }
- }
- JavaRunConfigurationExtensionManager.checkConfigurationIsValid(this);
- }
-
- @Override
- public Collection<Module> getValidModules() {
- return Arrays.asList(ModuleManager.getInstance(getProject()).getModules());
- }
-
- @NotNull
- @Override
- public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
- SettingsEditorGroup<TestDiscoveryConfiguration> group = new SettingsEditorGroup<TestDiscoveryConfiguration>();
- group.addEditor(ExecutionBundle.message("run.configuration.configuration.tab.title"),
- new TestDiscoveryConfigurable<TestDiscoveryConfiguration>(getProject()));
- JavaRunConfigurationExtensionManager.getInstance().appendEditors(this, group);
- group.addEditor(ExecutionBundle.message("logs.tab.title"), new LogConfigurationPanel<TestDiscoveryConfiguration>());
- return group;
- }
-
- @Override
- public void readExternal(Element element) throws InvalidDataException {
- myDelegate.readExternal(element);
- super.readExternal(element);
- readModule(element);
-
- final String classQName = element.getAttributeValue("class");
- final String methodName = element.getAttributeValue("method");
- myPosition = classQName != null && methodName != null ? Pair.create(classQName, methodName) : null;
- myChangeList = element.getAttributeValue("changeList");
- if ("All".equals(myChangeList)) {
- myChangeList = null;
- }
- }
-
- @Override
- public void writeExternal(Element element) throws WriteExternalException {
- myDelegate.writeExternal(element);
- super.writeExternal(element);
-
- writeModule(element);
-
- if (myPosition != null) {
- element.setAttribute("class", myPosition.first);
- element.setAttribute("method", myPosition.second);
- }
- element.setAttribute("changeList", myChangeList == null ? "All" : myChangeList);
- }
-
-
- @Nullable
- @Override
- public String getRunClass() {
- return null;
- }
-
- @Nullable
- @Override
- public String getPackage() {
- return "";
- }
-
- @Override
- public void setProgramParameters(@Nullable String value) {
- myDelegate.setProgramParameters(value);
- }
-
- @Override
- @Nullable
- public String getProgramParameters() {
- return myDelegate.getProgramParameters();
- }
-
- @Override
- public void setWorkingDirectory(@Nullable String value) {
- myDelegate.setWorkingDirectory(value);
- }
-
- @Override
- @Nullable
- public String getWorkingDirectory() {
- return myDelegate.getWorkingDirectory();
- }
-
- @Override
- public void setEnvs(@NotNull Map<String, String> envs) {
- myDelegate.setEnvs(envs);
- }
-
- @Override
- @NotNull
- public Map<String, String> getEnvs() {
- return myDelegate.getEnvs();
- }
-
- @Override
- public void setPassParentEnvs(boolean passParentEnvs) {
- myDelegate.setPassParentEnvs(passParentEnvs);
- }
-
- @Override
- public boolean isPassParentEnvs() {
- return myDelegate.isPassParentEnvs();
- }
-
- @Override
- public SMTRunnerConsoleProperties createTestConsoleProperties(Executor executor) {
- return myDelegate.createTestConsoleProperties(executor);
- }
-
- public void setPosition(Pair<String, String> position) {
- myPosition = position;
- }
-
- public void setChangeList(String changeList) {
- myChangeList = changeList;
- }
-
- public Pair<String, String> getPosition() {
- return myPosition;
- }
-
- public String getChangeList() {
- return myChangeList;
- }
-}
package com.intellij.execution.testDiscovery;
import com.intellij.codeInsight.TestFrameworks;
-import com.intellij.execution.JavaExecutionUtil;
-import com.intellij.execution.Location;
+import com.intellij.execution.*;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.execution.configurations.ConfigurationType;
+import com.intellij.execution.configurations.ModuleBasedConfiguration;
import com.intellij.execution.junit.JavaRunConfigurationProducerBase;
-import com.intellij.execution.testframework.TestSearchScope;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testIntegration.TestFramework;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.HashSet;
import java.io.IOException;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.List;
+import java.util.Set;
-public abstract class TestDiscoveryConfigurationProducer extends JavaRunConfigurationProducerBase<TestDiscoveryConfiguration> {
+public abstract class TestDiscoveryConfigurationProducer extends JavaRunConfigurationProducerBase<JavaTestConfigurationBase> {
protected TestDiscoveryConfigurationProducer(ConfigurationType type) {
super(type);
}
+
+ protected abstract void setPosition(JavaTestConfigurationBase configuration, PsiLocation<PsiMethod> position);
+ protected abstract Pair<String, String> getPosition(JavaTestConfigurationBase configuration);
+
@Override
- protected boolean setupConfigurationFromContext(final TestDiscoveryConfiguration configuration,
+ protected boolean setupConfigurationFromContext(final JavaTestConfigurationBase configuration,
ConfigurationContext configurationContext,
Ref<PsiElement> ref) {
if (!Registry.is("testDiscovery.enabled")) {
assert contextLocation != null;
final Location location = JavaExecutionUtil.stepIntoSingleClass(contextLocation);
if (location == null) return false;
- final Pair<String, String> position = getPosition(location);
- if (position != null) {
+ final PsiMethod sourceMethod = getSourceMethod(location);
+ final Pair<String, String> position = getPosition(sourceMethod);
+ if (sourceMethod != null && position != null) {
try {
- final Collection<String> testsByMethodName = TestDiscoveryIndex
- .getInstance(configuration.getProject()).getTestsByMethodName(position.first, position.second);
- if (testsByMethodName == null || ContainerUtil.filter(testsByMethodName, s -> s.startsWith(configuration.getFrameworkPrefix())).isEmpty()) return false;
-
+ final Project project = configuration.getProject();
+ final TestDiscoveryIndex testDiscoveryIndex = TestDiscoveryIndex.getInstance(project);
+ final Collection<String> testsByMethodName = testDiscoveryIndex.getTestsByMethodName(position.first, position.second);
+ if (testsByMethodName == null ||
+ ContainerUtil.filter(testsByMethodName, s -> s.startsWith(configuration.getFrameworkPrefix())).isEmpty()) {
+ return false;
+ }
+ setPosition(configuration, new PsiLocation<PsiMethod>(sourceMethod));
+ configuration.setName("Tests for " + StringUtil.getShortName(position.first) + "." + position.second);
+
+ final RunnerAndConfigurationSettings template =
+ configurationContext.getRunManager().getConfigurationTemplate(getConfigurationFactory());
+ final Module predefinedModule = ((ModuleBasedConfiguration)template.getConfiguration()).getConfigurationModule().getModule();
+ if (predefinedModule != null) {
+ configuration.setModule(predefinedModule);
+ }
+
+ //potentially this set won't be big, it reflects modules from where user starts his tests
+ final Collection<String> modules = testDiscoveryIndex.getTestModulesByMethodName(position.first,
+ position.second,
+ configuration.getFrameworkPrefix());
+ if (modules.isEmpty()) return true;
+
+ final ModuleManager moduleManager = ModuleManager.getInstance(project);
+ final Set<Module> allModules = new HashSet<>(Arrays.asList(moduleManager.getModules()));
+ modules.stream()
+ .map(moduleManager::findModuleByName)
+ .filter(module -> module != null)
+ .forEach(module -> {
+ final List<Module> dependentModules = ModuleUtilCore.getAllDependentModules(module);
+ dependentModules.add(module);
+ allModules.retainAll(dependentModules);
+ });
+ if (!allModules.isEmpty()) {
+ configuration.setModule(allModules.iterator().next());
+ }
+
+ return true;
}
catch (IOException e) {
return false;
}
- configuration.setPosition(position);
- configuration.setName("Tests for " + StringUtil.getShortName(position.first) + "." + position.second);
- setupPackageConfiguration(configurationContext, configuration, TestSearchScope.MODULE_WITH_DEPENDENCIES);
- return true;
}
return false;
}
@Override
- protected Module findModule(TestDiscoveryConfiguration configuration, Module contextModule) {
+ protected Module findModule(JavaTestConfigurationBase configuration, Module contextModule) {
return null;
}
- private static Pair<String, String> getPosition(Location location) {
+ private static PsiMethod getSourceMethod(Location location) {
final PsiElement psiElement = location.getPsiElement();
final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(psiElement, PsiMethod.class);
if (psiMethod != null) {
if (testFramework != null) {
return null;
}
- final String qualifiedName = containingClass.getQualifiedName();
- if (qualifiedName != null) {
- return Pair.create(qualifiedName, psiMethod.getName());
- }
+ return psiMethod;
}
}
return null;
}
+ private static Pair<String, String> getPosition(PsiMethod method) {
+ if (method == null) {
+ return null;
+ }
+ final PsiClass containingClass = method.getContainingClass();
+ final String qualifiedName = containingClass.getQualifiedName();
+ if (qualifiedName != null) {
+ return Pair.create(qualifiedName, method.getName());
+ }
+ return null;
+ }
+
@Override
- public boolean isConfigurationFromContext(TestDiscoveryConfiguration configuration, ConfigurationContext configurationContext) {
- final Pair<String, String> position = getPosition(configurationContext.getLocation());
- return position != null && position.equals(configuration.getPosition());
+ public boolean isConfigurationFromContext(JavaTestConfigurationBase configuration, ConfigurationContext configurationContext) {
+ final Pair<String, String> position = getPosition(getSourceMethod(configurationContext.getLocation()));
+ return position != null && position.equals(getPosition(configuration));
}
}
import org.jetbrains.annotations.Nullable;
import java.io.File;
-import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
if (myCompletedMethodNames.size() > 50) {
final String[] fullTestNames = ArrayUtil.toStringArray(myCompletedMethodNames);
myCompletedMethodNames.clear();
- processTracesAlarm.addRequest(() -> processAvailableTraces(configuration, fullTestNames), 100);
+ processTracesAlarm.addRequest(() -> processAvailableTraces(fullTestNames,
+ getTracesDirectory(configuration), configuration,
+ TestDiscoveryIndex.getInstance(configuration.getProject())
+ ), 100);
}
}
}
if (testMethodTraces != null) {
for (File testMethodTrace : testMethodTraces) {
try {
- coverageIndex.updateFromTestTrace(testMethodTrace);
+ coverageIndex.updateFromTestTrace(testMethodTrace, (JavaTestConfigurationBase)configuration);
FileUtil.delete(testMethodTrace);
}
catch (IOException e) {
}
}
- private static void processAvailableTraces(RunConfigurationBase configuration, String[] fullTestNames) {
- final String tracesDirectory = getTracesDirectory(configuration);
- final TestDiscoveryIndex coverageIndex = TestDiscoveryIndex.getInstance(configuration.getProject());
+ public static void processAvailableTraces(final String[] fullTestNames,
+ final String tracesDirectory,
+ RunConfigurationBase configuration,
+ final TestDiscoveryIndex discoveryIndex) {
synchronized (ourTracesLock) {
for (String fullTestName : fullTestNames) {
final String className = StringUtil.getPackageName(fullTestName);
final File testMethodTrace = new File(tracesDirectory, className + "-" + methodName + ".tr");
if (testMethodTrace.exists()) {
try {
- coverageIndex.updateFromTestTrace(testMethodTrace);
+ discoveryIndex.updateFromTestTrace(testMethodTrace, (JavaTestConfigurationBase)configuration);
FileUtil.delete(testMethodTrace);
}
catch (IOException e) {
*/
package com.intellij.execution.testDiscovery;
+import com.intellij.execution.JavaTestConfigurationBase;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vfs.newvfs.persistent.FlushingDaemon;
-import com.intellij.util.io.*;
+import com.intellij.util.ThrowableConvertor;
+import com.intellij.util.io.DataInputOutputUtil;
+import com.intellij.util.io.IOUtil;
+import gnu.trove.THashSet;
import gnu.trove.TIntArrayList;
-import gnu.trove.TIntHashSet;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.*;
-import java.io.DataOutputStream;
-import java.util.*;
-import java.util.concurrent.ScheduledFuture;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
/**
* @author Maxim.Mossienko on 7/9/2015.
public class TestDiscoveryIndex implements ProjectComponent {
static final Logger LOG = Logger.getInstance(TestDiscoveryIndex.class);
- private static final int REMOVED_MARKER = -1;
- private final Object ourLock = new Object();
private final Project myProject;
- private volatile Holder myHolder;
+
+ //private volatile TestInfoHolder mySystemHolder;
+ private final TestDataController myLocalTestRunDataController;
+ private final TestDataController myRemoteTestRunDataController;
public TestDiscoveryIndex(Project project) {
+ this(project, TestDiscoveryExtension.baseTestDiscoveryPathForProject(project));
+ }
+
+ public TestDiscoveryIndex(final Project project, final String basePath) {
myProject = project;
- String path = TestDiscoveryExtension.baseTestDiscoveryPathForProject(myProject);
+ myLocalTestRunDataController = new TestDataController(basePath, false);
+ myRemoteTestRunDataController = new TestDataController(null, true);
- if (new File(path).exists()) {
+ if (new File(basePath).exists()) {
StartupManager.getInstance(project).registerPostStartupActivity(() -> ApplicationManager.getApplication().executeOnPooledThread(() -> {
- getHolder(); // proactively init with maybe io costly compact
+ myLocalTestRunDataController.getHolder(); // proactively init with maybe io costly compact
}));
}
+
+ //{
+ // setRemoteTestRunDataPath("C:\\ultimate\\system\\testDiscovery\\145.save");
+ //}
}
public boolean hasTestTrace(@NotNull String testName) throws IOException {
- synchronized (ourLock) {
- Holder holder = null;
- try {
- holder = getHolder();
- final int testNameId = holder.myTestNameEnumerator.tryEnumerate(testName);
- if (testNameId == 0) return false;
- return holder.myTestNameToUsedClassesAndMethodMap.get(testNameId) != null;
- } catch (Throwable throwable) {
- thingsWentWrongLetsReinitialize(holder, throwable);
- return false;
+ Boolean result = myLocalTestRunDataController.withTestDataHolder(localHolder -> { // todo: remote run data
+ final int testNameId = localHolder.myTestNameEnumerator.tryEnumerate(testName);
+ if (testNameId == 0) {
+ return myRemoteTestRunDataController.withTestDataHolder(remoteHolder -> {
+ final int testNameId1 = remoteHolder.myTestNameEnumerator.tryEnumerate(testName);
+ return testNameId1 != 0 && remoteHolder.myTestNameToUsedClassesAndMethodMap.get(testNameId1) != null;
+ }) != null;
}
- }
+ return localHolder.myTestNameToUsedClassesAndMethodMap.get(testNameId) != null;
+ });
+ return result == Boolean.TRUE;
}
public void removeTestTrace(@NotNull String testName) throws IOException {
- synchronized (ourLock) {
- Holder holder = null;
- try {
- holder = getHolder();
-
- final int testNameId = holder.myTestNameEnumerator.tryEnumerate(testName);
- if (testNameId == 0) return;
- doUpdateFromDiff(holder, testNameId, null, holder.myTestNameToUsedClassesAndMethodMap.get(testNameId));
- } catch (Throwable throwable) {
- thingsWentWrongLetsReinitialize(holder, throwable);
+ myLocalTestRunDataController.withTestDataHolder(new ThrowableConvertor<TestInfoHolder, Void, IOException>() {
+ @Override
+ public Void convert(TestInfoHolder localHolder) throws IOException {
+ final int testNameId = localHolder.myTestNameEnumerator.tryEnumerate(testName); // todo remove remote data isn't possible
+ if (testNameId != 0) {
+ localHolder.doUpdateFromDiff(testNameId, null,
+ localHolder.myTestNameToUsedClassesAndMethodMap.get(testNameId),
+ null);
+ }
+ return null;
}
+ });
+ }
+
+ public void setRemoteTestRunDataPath(String path) {
+ if(!TestInfoHolder.isValidPath(path)) {
+ path = null;
}
+ myRemoteTestRunDataController.init(path);
+ // todo: should we remove our local run data ?
}
public Collection<String> getTestsByMethodName(@NotNull String classFQName, @NotNull String methodName) throws IOException {
- synchronized (ourLock) {
- Holder holder = null;
- try {
- holder = getHolder();
- final TIntArrayList list = holder.myMethodQNameToTestNames.get(
- createKey(
- holder.myClassEnumerator.enumerate(classFQName),
- holder.myMethodEnumerator.enumerate(methodName)
+ return myLocalTestRunDataController.withTestDataHolder(new ThrowableConvertor<TestInfoHolder, Collection<String>, IOException>() {
+ @Override
+ public Collection<String> convert(TestInfoHolder localHolder) throws IOException {
+ TIntArrayList remoteList = myRemoteTestRunDataController.withTestDataHolder(
+ remoteHolder -> remoteHolder.myMethodQNameToTestNames.get(
+ TestInfoHolder.createKey(
+ remoteHolder.myClassEnumerator.enumerate(classFQName),
+ remoteHolder.myMethodEnumerator.enumerate(methodName)
+ )
)
);
- if (list == null) return Collections.emptyList();
- final ArrayList<String> result = new ArrayList<String>(list.size());
- for (int testNameId : list.toNativeArray()) result.add(holder.myTestNameEnumerator.valueOf(testNameId));
- return result;
- } catch (Throwable throwable) {
- thingsWentWrongLetsReinitialize(holder, throwable);
- return Collections.emptyList();
- }
- }
- }
-
- private Holder getHolder() {
- Holder holder = myHolder;
-
- if (holder == null) {
- synchronized (ourLock) {
- holder = myHolder;
- if (holder == null) holder = myHolder = new Holder();
- }
- }
- return holder;
- }
-
- public static TestDiscoveryIndex getInstance(Project project) {
- return project.getComponent(TestDiscoveryIndex.class);
- }
-
- @Override
- public void initComponent() {
- }
-
- @Override
- public void disposeComponent() {
- synchronized (ourLock) {
- Holder holder = myHolder;
- if (holder != null) {
- holder.dispose();
- myHolder = null;
- }
- }
- }
- @NotNull
- @Override
- public String getComponentName() {
- return getClass().getName();
- }
-
- @Override
- public void projectOpened() {
- }
-
- @Override
- public void projectClosed() {
- }
+ final TIntArrayList localList = localHolder.myMethodQNameToTestNames.get(
+ TestInfoHolder.createKey(
+ localHolder.myClassEnumerator.enumerate(classFQName),
+ localHolder.myMethodEnumerator.enumerate(methodName)
+ )
+ );
- private static final int VERSION = 2;
-
- private final class Holder {
- final PersistentHashMap<Long, TIntArrayList> myMethodQNameToTestNames;
- final PersistentHashMap<Integer, TIntObjectHashMap<TIntArrayList>> myTestNameToUsedClassesAndMethodMap;
- final PersistentStringEnumerator myClassEnumerator;
- final CachingEnumerator<String> myClassEnumeratorCache;
- final PersistentStringEnumerator myMethodEnumerator;
- final CachingEnumerator<String> myMethodEnumeratorCache;
- final PersistentStringEnumerator myTestNameEnumerator;
- final List<PersistentEnumeratorDelegate> myConstructedDataFiles = new ArrayList<PersistentEnumeratorDelegate>(4);
-
- private ScheduledFuture<?> myFlushingFuture;
- private boolean myDisposed;
-
- Holder() {
- String path = TestDiscoveryExtension.baseTestDiscoveryPathForProject(myProject);
- final File versionFile = getVersionFile(path);
- versionFile.getParentFile().mkdirs();
- final File methodQNameToTestNameFile = new File(path + File.separator + "methodQNameToTestName.data");
- final File testNameToUsedClassesAndMethodMapFile = new File(path + File.separator + "testToCalledMethodNames.data");
- final File classNameEnumeratorFile = new File(path + File.separator + "classNameEnumerator.data");
- final File methodNameEnumeratorFile = new File(path + File.separator + "methodNameEnumerator.data");
- final File testNameEnumeratorFile = new File(path + File.separator + "testNameEnumerator.data");
-
- try {
- int version = readVersion(versionFile);
- if (version != VERSION) {
- LOG.info("TestDiscoveryIndex was rewritten due to version change");
- deleteAllIndexDataFiles(methodQNameToTestNameFile, testNameToUsedClassesAndMethodMapFile, classNameEnumeratorFile, methodNameEnumeratorFile, testNameEnumeratorFile);
-
- writeVersion(versionFile);
+ if (remoteList == null) {
+ return testIdsToTestNames(localList, localHolder);
}
- PersistentHashMap<Long, TIntArrayList> methodQNameToTestNames;
- PersistentHashMap<Integer, TIntObjectHashMap<TIntArrayList>> testNameToUsedClassesAndMethodMap;
- PersistentStringEnumerator classNameEnumerator;
- PersistentStringEnumerator methodNameEnumerator;
- PersistentStringEnumerator testNameEnumerator;
-
- int iterations = 0;
-
- while(true) {
- ++iterations;
-
- try {
- methodQNameToTestNames = new PersistentHashMap<Long, TIntArrayList>(
- methodQNameToTestNameFile,
- new MethodQNameSerializer(),
- new TestNamesExternalizer()
- );
- myConstructedDataFiles.add(methodQNameToTestNames);
-
- testNameToUsedClassesAndMethodMap = new PersistentHashMap<Integer, TIntObjectHashMap<TIntArrayList>>(
- testNameToUsedClassesAndMethodMapFile,
- EnumeratorIntegerDescriptor.INSTANCE,
- new ClassesAndMethodsMapDataExternalizer()
- );
- myConstructedDataFiles.add(testNameToUsedClassesAndMethodMap);
-
- classNameEnumerator = new PersistentStringEnumerator(classNameEnumeratorFile);
- myConstructedDataFiles.add(classNameEnumerator);
-
- methodNameEnumerator = new PersistentStringEnumerator(methodNameEnumeratorFile);
- myConstructedDataFiles.add(methodNameEnumerator);
-
- testNameEnumerator = new PersistentStringEnumerator(testNameEnumeratorFile);
- myConstructedDataFiles.add(testNameEnumerator);
-
- break;
- } catch (Throwable throwable) {
- LOG.info("TestDiscoveryIndex problem", throwable);
- closeAllConstructedFiles(true);
- myConstructedDataFiles.clear();
-
- deleteAllIndexDataFiles(methodQNameToTestNameFile, testNameToUsedClassesAndMethodMapFile, classNameEnumeratorFile, methodNameEnumeratorFile,
- testNameEnumeratorFile);
- // try another time
- }
+ Collection<String> testsFromRemote =
+ myRemoteTestRunDataController.withTestDataHolder(
+ remoteHolder -> testIdsToTestNames(remoteList, remoteHolder)
+ );
- if (iterations >= 3) {
- LOG.error("Unexpected circular initialization problem");
- assert false;
- }
- }
+ if (localList == null) return testsFromRemote;
+ THashSet<String> setOfStrings = new THashSet<>(testsFromRemote);
- myMethodQNameToTestNames = methodQNameToTestNames;
- myTestNameToUsedClassesAndMethodMap = testNameToUsedClassesAndMethodMap;
- myClassEnumerator = classNameEnumerator;
- myMethodEnumerator = methodNameEnumerator;
- myTestNameEnumerator = testNameEnumerator;
- myMethodEnumeratorCache = new CachingEnumerator<String>(methodNameEnumerator, EnumeratorStringDescriptor.INSTANCE);
- myClassEnumeratorCache = new CachingEnumerator<String>(classNameEnumerator, EnumeratorStringDescriptor.INSTANCE);
-
- myFlushingFuture = FlushingDaemon.everyFiveSeconds(() -> {
- synchronized (ourLock) {
- if (myDisposed) {
- myFlushingFuture.cancel(false);
- return;
- }
- for(PersistentEnumeratorDelegate dataFile:myConstructedDataFiles) {
- if (dataFile.isDirty()) {
- dataFile.force();
- }
- }
- myClassEnumeratorCache.clear();
- myMethodEnumeratorCache.clear();
+ for (int testNameId : localList.toNativeArray()) {
+ if (testNameId < 0) {
+ setOfStrings.remove(localHolder.myTestNameEnumerator.valueOf(-testNameId));
+ continue;
}
- });
- }
- catch (IOException ex) {
- throw new RuntimeException(ex);
- }
- }
-
- private void closeAllConstructedFiles(boolean ignoreCloseProblem) {
- for(Closeable closeable:myConstructedDataFiles) {
- try {
- closeable.close();
- } catch (Throwable throwable) {
- if (!ignoreCloseProblem) throw new RuntimeException(throwable);
+ setOfStrings.add(localHolder.myTestNameEnumerator.valueOf(testNameId));
}
- }
- }
-
- private void deleteAllIndexDataFiles(File methodQNameToTestNameFile,
- File testNameToUsedClassesAndMethodMapFile,
- File classNameEnumeratorFile, File methodNameEnumeratorFile, File testNameEnumeratorFile) {
- IOUtil.deleteAllFilesStartingWith(methodQNameToTestNameFile);
- IOUtil.deleteAllFilesStartingWith(testNameToUsedClassesAndMethodMapFile);
- IOUtil.deleteAllFilesStartingWith(classNameEnumeratorFile);
- IOUtil.deleteAllFilesStartingWith(methodNameEnumeratorFile);
- IOUtil.deleteAllFilesStartingWith(testNameEnumeratorFile);
- }
-
- private void writeVersion(File versionFile) throws IOException {
- final DataOutputStream versionOut = new DataOutputStream(new FileOutputStream(versionFile));
-
- try {
- DataInputOutputUtil.writeINT(versionOut, VERSION);
- } finally {
- try { versionOut.close(); } catch (IOException ignore) {}
- }
- }
-
- private int readVersion(File versionFile) throws IOException {
- if (!versionFile.exists()) return 0;
- final DataInputStream versionInput = new DataInputStream(new FileInputStream(versionFile));
- int version;
- try {
- version = DataInputOutputUtil.readINT(versionInput);
- } finally {
- try { versionInput.close(); } catch (IOException ignore) {}
- }
- return version;
- }
- void dispose() {
- assert Thread.holdsLock(ourLock);
- try {
- closeAllConstructedFiles(false);
- }
- finally {
- myDisposed = true;
+ return setOfStrings;
}
- }
- private class TestNamesExternalizer implements DataExternalizer<TIntArrayList> {
- public void save(@NotNull DataOutput dataOutput, TIntArrayList testNameIds) throws IOException {
- for (int testNameId : testNameIds.toNativeArray()) DataInputOutputUtil.writeINT(dataOutput, testNameId);
- }
+ private Collection<String> testIdsToTestNames(TIntArrayList localList, TestInfoHolder localHolder) throws IOException {
+ if (localList == null) return Collections.emptyList();
- public TIntArrayList read(@NotNull DataInput dataInput) throws IOException {
- TIntHashSet result = new TIntHashSet();
-
- while (((InputStream)dataInput).available() > 0) {
- int id = DataInputOutputUtil.readINT(dataInput);
- if (REMOVED_MARKER == id) {
- id = DataInputOutputUtil.readINT(dataInput);
- result.remove(id);
- }
- else {
- result.add(id);
+ final ArrayList<String> result = new ArrayList<String>(localList.size());
+ for (int testNameId : localList.toNativeArray()) {
+ if (testNameId < 0) {
+ int a = 1;
+ continue;
}
+ result.add(localHolder.myTestNameEnumerator.valueOf(testNameId));
}
-
- return new TIntArrayList(result.toArray());
+ return result;
}
- }
+ });
+ }
- private class ClassesAndMethodsMapDataExternalizer implements DataExternalizer<TIntObjectHashMap<TIntArrayList>> {
- public void save(@NotNull final DataOutput dataOutput, TIntObjectHashMap<TIntArrayList> classAndMethodsMap)
- throws IOException {
- DataInputOutputUtil.writeINT(dataOutput, classAndMethodsMap.size());
- final int[] classNameIds = classAndMethodsMap.keys();
- Arrays.sort(classNameIds);
-
- int prevClassNameId = 0;
- for(int classNameId:classNameIds) {
- DataInputOutputUtil.writeINT(dataOutput, classNameId - prevClassNameId);
- TIntArrayList value = classAndMethodsMap.get(classNameId);
- DataInputOutputUtil.writeINT(dataOutput, value.size());
-
- final int[] methodNameIds = value.toNativeArray();
- Arrays.sort(methodNameIds);
- int prevMethodNameId = 0;
- for (int methodNameId : methodNameIds) {
- DataInputOutputUtil.writeINT(dataOutput, methodNameId - prevMethodNameId);
- prevMethodNameId = methodNameId;
- }
- prevClassNameId = classNameId;
- }
+
+ public Collection<String> getTestModulesByMethodName(@NotNull String classFQName, @NotNull String methodName, String prefix) throws IOException {
+ return myLocalTestRunDataController.withTestDataHolder(new ThrowableConvertor<TestInfoHolder, Collection<String>, IOException>() {
+ @Override
+ public Collection<String> convert(TestInfoHolder localHolder) throws IOException {
+ List<String> modules = getTestModules(localHolder);
+ List<String> modulesFromRemote = myRemoteTestRunDataController.withTestDataHolder(
+ this::getTestModules);
+ THashSet<String> modulesSet = new THashSet<>(modules);
+ if (modulesFromRemote != null) modulesSet.addAll(modulesFromRemote);
+ return modulesSet;
}
- public TIntObjectHashMap<TIntArrayList> read(@NotNull DataInput dataInput) throws IOException {
- int numberOfClasses = DataInputOutputUtil.readINT(dataInput);
- TIntObjectHashMap<TIntArrayList> result = new TIntObjectHashMap<TIntArrayList>();
- int prevClassNameId = 0;
-
- while (numberOfClasses-- > 0) {
- int classNameId = DataInputOutputUtil.readINT(dataInput) + prevClassNameId;
- int numberOfMethods = DataInputOutputUtil.readINT(dataInput);
- TIntArrayList methodNameIds = new TIntArrayList(numberOfMethods);
-
- int prevMethodNameId = 0;
- while (numberOfMethods-- > 0) {
- final int methodNameId = DataInputOutputUtil.readINT(dataInput) + prevMethodNameId;
- methodNameIds.add(methodNameId);
- prevMethodNameId = methodNameId;
+ private List<String> getTestModules(TestInfoHolder holder) throws IOException {
+ // todo merging with remote
+ final TIntArrayList list = holder.myTestNameToNearestModule.get(
+ TestInfoHolder.createKey(
+ holder.myClassEnumerator.enumerate(classFQName),
+ holder.myMethodEnumerator.enumerate(methodName)
+ )
+ );
+ if (list == null) return Collections.emptyList();
+ final ArrayList<String> result = new ArrayList<String>(list.size());
+ for (int moduleNameId : list.toNativeArray()) {
+ final String moduleNameWithPrefix = holder.myModuleNameEnumerator.valueOf(moduleNameId);
+ if (moduleNameWithPrefix != null && moduleNameWithPrefix.startsWith(prefix)) {
+ result.add(moduleNameWithPrefix.substring(prefix.length()));
}
-
- result.put(classNameId, methodNameIds);
- prevClassNameId = classNameId;
}
return result;
}
- }
+ });
}
- private static class MethodQNameSerializer implements KeyDescriptor<Long> {
- public static final MethodQNameSerializer INSTANCE = new MethodQNameSerializer();
+ static class TestDataController {
+ private final Object myLock = new Object();
+ private String myBasePath;
+ private final boolean myReadOnly;
+ private volatile TestInfoHolder myHolder;
- @Override
- public void save(@NotNull DataOutput out, Long value) throws IOException {
- out.writeLong(value);
+ TestDataController(String basePath, boolean readonly) {
+ myReadOnly = readonly;
+ init(basePath);
}
- @Override
- public Long read(@NotNull DataInput in) throws IOException {
- return in.readLong();
- }
+ void init(String basePath) {
+ if (myHolder != null) dispose();
- @Override
- public int getHashCode(Long value) {
- return value.hashCode();
+ synchronized (myLock) {
+ myBasePath = basePath;
+ }
}
- @Override
- public boolean isEqual(Long val1, Long val2) {
- return val1.equals(val2);
- }
- }
-
- public void updateFromTestTrace(@NotNull File file) throws IOException {
- int fileNameDotIndex = file.getName().lastIndexOf('.');
- final String testName = fileNameDotIndex != -1 ? file.getName().substring(0, fileNameDotIndex) : file.getName();
- doUpdateFromTestTrace(file, testName);
- }
+ private TestInfoHolder getHolder() {
+ TestInfoHolder holder = myHolder;
- private void doUpdateFromTestTrace(File file, final String testName) throws IOException {
- synchronized (ourLock) {
- Holder holder = getHolder();
- if (holder.myDisposed) return;
- try {
- final int testNameId = holder.myTestNameEnumerator.enumerate(testName);
- TIntObjectHashMap<TIntArrayList> classData = loadClassAndMethodsMap(file, holder);
- TIntObjectHashMap<TIntArrayList> previousClassData = holder.myTestNameToUsedClassesAndMethodMap.get(testNameId);
-
- doUpdateFromDiff(holder, testNameId, classData, previousClassData);
- } catch (Throwable throwable) {
- thingsWentWrongLetsReinitialize(holder, throwable);
+ if (holder == null) {
+ synchronized (myLock) {
+ holder = myHolder;
+ if (holder == null && myBasePath != null) holder = myHolder = new TestInfoHolder(myBasePath, myReadOnly, myLock);
+ }
}
+ return holder;
}
- }
- private void doUpdateFromDiff(Holder holder,
- final int testNameId,
- @Nullable TIntObjectHashMap<TIntArrayList> classData,
- @Nullable TIntObjectHashMap<TIntArrayList> previousClassData) throws IOException {
- ValueDiff valueDiff = new ValueDiff(classData, previousClassData);
-
- if (valueDiff.hasRemovedDelta()) {
- for (int classQName : valueDiff.myRemovedClassData.keys()) {
- for (int methodName : valueDiff.myRemovedClassData.get(classQName).toNativeArray()) {
- holder.myMethodQNameToTestNames.appendData(createKey(classQName, methodName),
- new PersistentHashMap.ValueDataAppender() {
- @Override
- public void append(DataOutput dataOutput) throws IOException {
- DataInputOutputUtil.writeINT(dataOutput, REMOVED_MARKER);
- DataInputOutputUtil.writeINT(dataOutput, testNameId);
- }
- }
- );
+ private void dispose() {
+ synchronized (myLock) {
+ TestInfoHolder holder = myHolder;
+ if (holder != null) {
+ holder.dispose();
+ myHolder = null;
}
}
}
- if (valueDiff.hasAddedDelta()) {
- for (int classQName : valueDiff.myAddedOrChangedClassData.keys()) {
- for (int methodName : valueDiff.myAddedOrChangedClassData.get(classQName).toNativeArray()) {
- holder.myMethodQNameToTestNames.appendData(createKey(classQName, methodName),
- new PersistentHashMap.ValueDataAppender() {
- @Override
- public void append(DataOutput dataOutput) throws IOException {
- DataInputOutputUtil.writeINT(dataOutput, testNameId);
- }
- });
- }
- }
+ private void thingsWentWrongLetsReinitialize(@Nullable TestInfoHolder holder, Throwable throwable) throws IOException {
+ LOG.error("Unexpected problem", throwable);
+ if (holder != null) holder.dispose();
+ final File versionFile = TestInfoHolder.getVersionFile(myBasePath);
+ FileUtil.delete(versionFile);
+
+ myHolder = null;
+ if (throwable instanceof IOException) throw (IOException) throwable;
}
- if ((valueDiff.hasAddedDelta() || valueDiff.hasRemovedDelta())) {
- if(classData != null) {
- holder.myTestNameToUsedClassesAndMethodMap.put(testNameId, classData);
- } else {
- holder.myTestNameToUsedClassesAndMethodMap.remove(testNameId);
+ public <R> R withTestDataHolder(ThrowableConvertor<TestInfoHolder, R, IOException> action) throws IOException {
+ synchronized (myLock) {
+ TestInfoHolder holder = getHolder();
+ if (holder == null || holder.isDisposed()) return null;
+ try {
+ return action.convert(holder);
+ } catch (Throwable throwable) {
+ if (!myReadOnly) thingsWentWrongLetsReinitialize(holder, throwable);
+ else LOG.error(throwable);
+ }
+ return null;
}
}
}
- @NotNull
- private static File getVersionFile(String path) {
- return new File(path + File.separator + "index.version");
+ public static TestDiscoveryIndex getInstance(Project project) {
+ return project.getComponent(TestDiscoveryIndex.class);
}
- private void thingsWentWrongLetsReinitialize(@Nullable Holder holder, Throwable throwable) throws IOException {
- LOG.error("Unexpected problem", throwable);
- if (holder != null) holder.dispose();
- String path = TestDiscoveryExtension.baseTestDiscoveryPathForProject(myProject);
- final File versionFile = getVersionFile(path);
- FileUtil.delete(versionFile);
+ @Override
+ public void initComponent() {
+ }
- myHolder = null;
- if (throwable instanceof IOException) throw (IOException) throwable;
+ @Override
+ public void disposeComponent() {
+ myLocalTestRunDataController.dispose();
+ myRemoteTestRunDataController.dispose();
}
- private static long createKey(int classQName, int methodName) {
- return ((long)classQName << 32) | methodName;
+ @NotNull
+ @Override
+ public String getComponentName() {
+ return getClass().getName();
}
- static class ValueDiff {
- final TIntObjectHashMap<TIntArrayList> myAddedOrChangedClassData;
- final TIntObjectHashMap<TIntArrayList> myRemovedClassData;
-
- ValueDiff(@Nullable TIntObjectHashMap<TIntArrayList> classData, @Nullable TIntObjectHashMap<TIntArrayList> previousClassData) {
- TIntObjectHashMap<TIntArrayList> addedOrChangedClassData = classData;
- TIntObjectHashMap<TIntArrayList> removedClassData = previousClassData;
-
- if (previousClassData != null && !previousClassData.isEmpty()) {
- removedClassData = new TIntObjectHashMap<TIntArrayList>();
- addedOrChangedClassData = new TIntObjectHashMap<TIntArrayList>();
-
- if (classData != null) {
- for (int classQName : classData.keys()) {
- TIntArrayList currentMethods = classData.get(classQName);
- TIntArrayList previousMethods = previousClassData.get(classQName);
-
- if (previousMethods == null) {
- addedOrChangedClassData.put(classQName, currentMethods);
- continue;
- }
-
- final int[] previousMethodIds = previousMethods.toNativeArray();
- TIntHashSet previousMethodsSet = new TIntHashSet(previousMethodIds);
- final int[] currentMethodIds = currentMethods.toNativeArray();
- TIntHashSet currentMethodsSet = new TIntHashSet(currentMethodIds);
- currentMethodsSet.removeAll(previousMethodIds);
- previousMethodsSet.removeAll(currentMethodIds);
-
- if (!currentMethodsSet.isEmpty()) {
- addedOrChangedClassData.put(classQName, new TIntArrayList(currentMethodsSet.toArray()));
- }
- if (!previousMethodsSet.isEmpty()) {
- removedClassData.put(classQName, new TIntArrayList(previousMethodsSet.toArray()));
- }
- }
- }
- if (classData != null) {
- for (int classQName : previousClassData.keys()) {
- if (classData.containsKey(classQName)) continue;
+ @Override
+ public void projectOpened() {
+ }
- TIntArrayList previousMethods = previousClassData.get(classQName);
- removedClassData.put(classQName, previousMethods);
- }
- }
- }
+ @Override
+ public void projectClosed() {
+ }
- myAddedOrChangedClassData = addedOrChangedClassData;
- myRemovedClassData = removedClassData;
- }
+ public void updateFromTestTrace(@NotNull File file, @Nullable JavaTestConfigurationBase configurationBase) throws IOException {
+ int fileNameDotIndex = file.getName().lastIndexOf('.');
+ final String testName = fileNameDotIndex != -1 ? file.getName().substring(0, fileNameDotIndex) : file.getName();
+ final Module module = configurationBase != null ? configurationBase.getConfigurationModule().getModule() : null;
+ doUpdateFromTestTrace(file, testName, module != null ? configurationBase.getFrameworkPrefix() + module.getName() : null);
+ }
- public boolean hasRemovedDelta() {
- return myRemovedClassData != null && !myRemovedClassData.isEmpty();
- }
+ private void doUpdateFromTestTrace(File file, final String testName, @Nullable final String moduleName) throws IOException {
+ myLocalTestRunDataController.withTestDataHolder(new ThrowableConvertor<TestInfoHolder, Void, IOException>() {
+ @Override
+ public Void convert(TestInfoHolder localHolder) throws IOException {
+ final int testNameId = localHolder.myTestNameEnumerator.enumerate(testName);
+ TIntObjectHashMap<TIntArrayList> classData = loadClassAndMethodsMap(file, localHolder);
+ TIntObjectHashMap<TIntArrayList> previousClassData = localHolder.myTestNameToUsedClassesAndMethodMap.get(testNameId);
+ if (previousClassData == null) {
+ previousClassData = myRemoteTestRunDataController.withTestDataHolder(
+ remoteDataHolder -> {
+ TIntObjectHashMap<TIntArrayList> remoteClassData = remoteDataHolder.myTestNameToUsedClassesAndMethodMap.get(testNameId);
+ if (remoteClassData == null) return null;
+ TIntObjectHashMap<TIntArrayList> result = new TIntObjectHashMap<TIntArrayList>(remoteClassData.size());
+ Ref<IOException> exceptionRef = new Ref<IOException>();
+ boolean processingResult = remoteClassData.forEachEntry((remoteClassKey, remoteClassMethodIds) -> {
+ try {
+ int localClassKey =
+ localHolder.myClassEnumeratorCache.enumerate(remoteDataHolder.myClassEnumeratorCache.valueOf(remoteClassKey));
+ TIntArrayList localClassIds = new TIntArrayList(remoteClassMethodIds.size());
+ for (int methodId : remoteClassMethodIds.toNativeArray()) {
+ localClassIds
+ .add(localHolder.myMethodEnumeratorCache.enumerate(remoteDataHolder.myMethodEnumeratorCache.valueOf(methodId)));
+ }
+ result.put(localClassKey, localClassIds);
+ return true;
+ } catch (IOException ex) {
+ exceptionRef.set(ex);
+ return false;
+ }
+ });
+ if (!processingResult) throw exceptionRef.get();
+ return result;
+ });
+ }
- public boolean hasAddedDelta() {
- return myAddedOrChangedClassData != null && !myAddedOrChangedClassData.isEmpty();
- }
+ localHolder.doUpdateFromDiff(testNameId, classData, previousClassData, moduleName != null ? localHolder.myModuleNameEnumerator.enumerate(moduleName) : null);
+ return null;
+ }
+ });
}
@NotNull
- private static TIntObjectHashMap<TIntArrayList> loadClassAndMethodsMap(File file, Holder holder) throws IOException {
+ private static TIntObjectHashMap<TIntArrayList> loadClassAndMethodsMap(File file, TestInfoHolder holder) throws IOException {
DataInputStream inputStream = new DataInputStream(new BufferedInputStream(new FileInputStream(file), 64 * 1024));
byte[] buffer = IOUtil.allocReadWriteUTFBuffer();
import java.util.*;
public class TestDiscoverySearchHelper {
- public static Set<String> search(final Project project,
- final Pair<String, String> position,
+ public static Set<String> search(final Project project,
+ final Pair<String, String> position,
final String changeList,
final String frameworkPrefix) {
final Set<String> patterns = new LinkedHashSet<String>();
@NotNull
private static List<VirtualFile> getAffectedFiles(String changeListName, Project project) {
final ChangeListManager changeListManager = ChangeListManager.getInstance(project);
- if (changeListName == null) {
+ if ("All".equals(changeListName)) {
return changeListManager.getAffectedFiles();
}
final LocalChangeList changeList = changeListManager.findChangeList(changeListName);
--- /dev/null
+/*
+ * Copyright 2000-2016 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.intellij.execution.testDiscovery;
+
+import com.intellij.openapi.vfs.newvfs.persistent.FlushingDaemon;
+import com.intellij.util.io.*;
+import gnu.trove.TIntArrayList;
+import gnu.trove.TIntHashSet;
+import gnu.trove.TIntObjectHashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ScheduledFuture;
+
+final class TestInfoHolder {
+ final PersistentHashMap<Long, TIntArrayList> myMethodQNameToTestNames;
+ final PersistentHashMap<Integer, TIntObjectHashMap<TIntArrayList>> myTestNameToUsedClassesAndMethodMap;
+ final PersistentHashMap<Long, TIntArrayList> myTestNameToNearestModule;
+ final PersistentStringEnumerator myClassEnumerator;
+ final CachingEnumerator<String> myClassEnumeratorCache;
+ final PersistentStringEnumerator myMethodEnumerator;
+ final CachingEnumerator<String> myMethodEnumeratorCache;
+ final PersistentStringEnumerator myTestNameEnumerator;
+ final PersistentStringEnumerator myModuleNameEnumerator;
+ final List<PersistentEnumeratorDelegate> myConstructedDataFiles = new ArrayList<PersistentEnumeratorDelegate>(6);
+
+ private ScheduledFuture<?> myFlushingFuture;
+ private boolean myDisposed;
+ private final Object myLock;
+
+ private static final int VERSION = 4;
+
+ TestInfoHolder(String basePath, boolean readOnly, Object lock) {
+ myLock = lock;
+ final File versionFile = getVersionFile(basePath);
+ versionFile.getParentFile().mkdirs();
+ final File methodQNameToTestNameFile = new File(basePath + File.separator + "methodQNameToTestName.data");
+ final File testNameToUsedClassesAndMethodMapFile = new File(basePath + File.separator + "testToCalledMethodNames.data");
+ final File classNameEnumeratorFile = new File(basePath + File.separator + "classNameEnumerator.data");
+ final File methodNameEnumeratorFile = new File(basePath + File.separator + "methodNameEnumerator.data");
+ final File testNameEnumeratorFile = new File(basePath + File.separator + "testNameEnumerator.data");
+ final File moduleNameEnumeratorFile = new File(basePath + File.separator + "moduleNameEnumerator.data");
+ final File testNameToNearestModuleFile = new File(basePath + File.separator + "testNameToNearestModule.data");
+
+ try {
+ int version = readVersion(versionFile);
+ if (version != VERSION) {
+ assert !readOnly;
+ TestDiscoveryIndex.LOG.info("TestDiscoveryIndex was rewritten due to version change");
+ deleteAllIndexDataFiles(methodQNameToTestNameFile,
+ testNameToUsedClassesAndMethodMapFile,
+ classNameEnumeratorFile,
+ methodNameEnumeratorFile,
+ testNameEnumeratorFile, moduleNameEnumeratorFile,
+ testNameToNearestModuleFile);
+
+ writeVersion(versionFile);
+ }
+
+ PersistentHashMap<Long, TIntArrayList> methodQNameToTestNames;
+ PersistentHashMap<Integer, TIntObjectHashMap<TIntArrayList>> testNameToUsedClassesAndMethodMap;
+ PersistentHashMap<Long, TIntArrayList> testNameToNearestModule;
+ PersistentStringEnumerator classNameEnumerator;
+ PersistentStringEnumerator methodNameEnumerator;
+ PersistentStringEnumerator testNameEnumerator;
+ PersistentStringEnumerator moduleNameEnumerator;
+
+ int iterations = 0;
+
+ while (true) {
+ ++iterations;
+
+ try {
+ methodQNameToTestNames = new PersistentHashMap<Long, TIntArrayList>(
+ methodQNameToTestNameFile,
+ MethodQNameSerializer.INSTANCE,
+ new TestNamesExternalizer()
+ ) {
+ @Override
+ protected boolean isReadOnly() {
+ return readOnly;
+ }
+ };
+ myConstructedDataFiles.add(methodQNameToTestNames);
+
+ testNameToUsedClassesAndMethodMap = new PersistentHashMap<Integer, TIntObjectHashMap<TIntArrayList>>(
+ testNameToUsedClassesAndMethodMapFile,
+ EnumeratorIntegerDescriptor.INSTANCE,
+ new ClassesAndMethodsMapDataExternalizer()
+ ) {
+ @Override
+ protected boolean isReadOnly() {
+ return readOnly;
+ }
+ };
+ myConstructedDataFiles.add(testNameToUsedClassesAndMethodMap);
+
+ testNameToNearestModule = new PersistentHashMap<Long, TIntArrayList>(testNameToNearestModuleFile,
+ MethodQNameSerializer.INSTANCE,
+ new TestNamesExternalizer());
+ myConstructedDataFiles.add(testNameToNearestModule);
+
+ classNameEnumerator = new PersistentStringEnumerator(classNameEnumeratorFile);
+ myConstructedDataFiles.add(classNameEnumerator);
+
+ methodNameEnumerator = new PersistentStringEnumerator(methodNameEnumeratorFile);
+ myConstructedDataFiles.add(methodNameEnumerator);
+
+ moduleNameEnumerator = new PersistentStringEnumerator(moduleNameEnumeratorFile);
+ myConstructedDataFiles.add(moduleNameEnumerator);
+
+ testNameEnumerator = new PersistentStringEnumerator(testNameEnumeratorFile);
+ myConstructedDataFiles.add(testNameEnumerator);
+
+ break;
+ }
+ catch (Throwable throwable) {
+ TestDiscoveryIndex.LOG.info("TestDiscoveryIndex problem", throwable);
+ closeAllConstructedFiles(true);
+ myConstructedDataFiles.clear();
+
+ deleteAllIndexDataFiles(methodQNameToTestNameFile, testNameToUsedClassesAndMethodMapFile, classNameEnumeratorFile,
+ methodNameEnumeratorFile,
+ testNameEnumeratorFile, moduleNameEnumeratorFile, testNameToNearestModuleFile);
+ // try another time
+ }
+
+ if (iterations >= 3) {
+ TestDiscoveryIndex.LOG.error("Unexpected circular initialization problem");
+ assert false;
+ }
+ }
+
+ myMethodQNameToTestNames = methodQNameToTestNames;
+ myTestNameToUsedClassesAndMethodMap = testNameToUsedClassesAndMethodMap;
+ myTestNameToNearestModule = testNameToNearestModule;
+ myClassEnumerator = classNameEnumerator;
+ myMethodEnumerator = methodNameEnumerator;
+ myTestNameEnumerator = testNameEnumerator;
+ myModuleNameEnumerator = moduleNameEnumerator;
+ myMethodEnumeratorCache = new CachingEnumerator<String>(methodNameEnumerator, EnumeratorStringDescriptor.INSTANCE);
+ myClassEnumeratorCache = new CachingEnumerator<String>(classNameEnumerator, EnumeratorStringDescriptor.INSTANCE);
+
+ myFlushingFuture = FlushingDaemon.everyFiveSeconds(() -> {
+ synchronized (myLock) {
+ if (myDisposed) {
+ myFlushingFuture.cancel(false);
+ return;
+ }
+ for (PersistentEnumeratorDelegate dataFile : myConstructedDataFiles) {
+ if (dataFile.isDirty()) {
+ dataFile.force();
+ }
+ }
+ myClassEnumeratorCache.clear();
+ myMethodEnumeratorCache.clear();
+ }
+ });
+ }
+ catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private void closeAllConstructedFiles(boolean ignoreCloseProblem) {
+ for (Closeable closeable : myConstructedDataFiles) {
+ try {
+ closeable.close();
+ }
+ catch (Throwable throwable) {
+ if (!ignoreCloseProblem) throw new RuntimeException(throwable);
+ }
+ }
+ }
+
+ private static void deleteAllIndexDataFiles(File... files) {
+ for (File file : files) {
+ IOUtil.deleteAllFilesStartingWith(file);
+ }
+ }
+
+ private static void writeVersion(File versionFile) throws IOException {
+ final java.io.DataOutputStream versionOut = new java.io.DataOutputStream(new FileOutputStream(versionFile));
+
+ try {
+ DataInputOutputUtil.writeINT(versionOut, VERSION);
+ }
+ finally {
+ try {
+ versionOut.close();
+ }
+ catch (IOException ignore) {
+ }
+ }
+ }
+
+ private static int readVersion(File versionFile) throws IOException {
+ if (!versionFile.exists()) return 0;
+ final DataInputStream versionInput = new DataInputStream(new FileInputStream(versionFile));
+ int version;
+ try {
+ version = DataInputOutputUtil.readINT(versionInput);
+ }
+ finally {
+ try {
+ versionInput.close();
+ }
+ catch (IOException ignore) {
+ }
+ }
+ return version;
+ }
+
+ void dispose() {
+ assert Thread.holdsLock(myLock);
+ try {
+ closeAllConstructedFiles(false);
+ }
+ finally {
+ myDisposed = true;
+ }
+ }
+
+ private static final int REMOVED_MARKER = -1;
+
+ void doUpdateFromDiff(final int testNameId,
+ @Nullable TIntObjectHashMap<TIntArrayList> classData,
+ @Nullable TIntObjectHashMap<TIntArrayList> previousClassData,
+ @Nullable Integer moduleId) throws IOException {
+ ValueDiff valueDiff = new ValueDiff(classData, previousClassData);
+
+ if (valueDiff.hasRemovedDelta()) {
+ for (int classQName : valueDiff.myRemovedClassData.keys()) {
+ for (int methodName : valueDiff.myRemovedClassData.get(classQName).toNativeArray()) {
+ myMethodQNameToTestNames.appendData(createKey(classQName, methodName),
+ dataOutput -> {
+ DataInputOutputUtil.writeINT(dataOutput, REMOVED_MARKER);
+ DataInputOutputUtil.writeINT(dataOutput, testNameId);
+ }
+ );
+ }
+ }
+ }
+
+ if (valueDiff.hasAddedDelta()) {
+ for (int classQName : valueDiff.myAddedOrChangedClassData.keys()) {
+ for (int methodName : valueDiff.myAddedOrChangedClassData.get(classQName).toNativeArray()) {
+ myMethodQNameToTestNames.appendData(createKey(classQName, methodName),
+ dataOutput -> DataInputOutputUtil.writeINT(dataOutput, testNameId));
+ if (moduleId != null) {
+ myTestNameToNearestModule.appendData(createKey(classQName, methodName),
+ dataOutput -> DataInputOutputUtil.writeINT(dataOutput, moduleId));
+ }
+ }
+ }
+ }
+
+ if ((valueDiff.hasAddedDelta() || valueDiff.hasRemovedDelta())) {
+ if (classData != null) {
+ myTestNameToUsedClassesAndMethodMap.put(testNameId, classData);
+ }
+ else {
+ myTestNameToUsedClassesAndMethodMap.remove(testNameId);
+ }
+ }
+ }
+
+ public boolean isDisposed() {
+ return myDisposed;
+ }
+
+ public static boolean isValidPath(String path) {
+ try {
+ return readVersion(getVersionFile(path)) == VERSION;
+ } catch (IOException ex) {
+ return false;
+ }
+ }
+
+ private static class TestNamesExternalizer implements DataExternalizer<TIntArrayList> {
+ public void save(@NotNull DataOutput dataOutput, TIntArrayList testNameIds) throws IOException {
+ for (int testNameId : testNameIds.toNativeArray()) DataInputOutputUtil.writeINT(dataOutput, testNameId);
+ }
+
+ public TIntArrayList read(@NotNull DataInput dataInput) throws IOException {
+ TIntHashSet result = new TIntHashSet();
+
+ while (((InputStream)dataInput).available() > 0) {
+ int id = DataInputOutputUtil.readINT(dataInput);
+ if (REMOVED_MARKER == id) {
+ id = DataInputOutputUtil.readINT(dataInput);
+ if(!result.remove(id)) {
+ result.add(-id);
+ }
+ }
+ else {
+ result.add(id);
+ }
+ }
+
+ return new TIntArrayList(result.toArray());
+ }
+ }
+
+ private static class ClassesAndMethodsMapDataExternalizer implements DataExternalizer<TIntObjectHashMap<TIntArrayList>> {
+ public void save(@NotNull final DataOutput dataOutput, TIntObjectHashMap<TIntArrayList> classAndMethodsMap)
+ throws IOException {
+ DataInputOutputUtil.writeINT(dataOutput, classAndMethodsMap.size());
+ final int[] classNameIds = classAndMethodsMap.keys();
+ Arrays.sort(classNameIds);
+
+ int prevClassNameId = 0;
+ for (int classNameId : classNameIds) {
+ DataInputOutputUtil.writeINT(dataOutput, classNameId - prevClassNameId);
+ TIntArrayList value = classAndMethodsMap.get(classNameId);
+ DataInputOutputUtil.writeINT(dataOutput, value.size());
+
+ final int[] methodNameIds = value.toNativeArray();
+ Arrays.sort(methodNameIds);
+ int prevMethodNameId = 0;
+ for (int methodNameId : methodNameIds) {
+ DataInputOutputUtil.writeINT(dataOutput, methodNameId - prevMethodNameId);
+ prevMethodNameId = methodNameId;
+ }
+ prevClassNameId = classNameId;
+ }
+ }
+
+ public TIntObjectHashMap<TIntArrayList> read(@NotNull DataInput dataInput) throws IOException {
+ int numberOfClasses = DataInputOutputUtil.readINT(dataInput);
+ TIntObjectHashMap<TIntArrayList> result = new TIntObjectHashMap<TIntArrayList>();
+ int prevClassNameId = 0;
+
+ while (numberOfClasses-- > 0) {
+ int classNameId = DataInputOutputUtil.readINT(dataInput) + prevClassNameId;
+ int numberOfMethods = DataInputOutputUtil.readINT(dataInput);
+ TIntArrayList methodNameIds = new TIntArrayList(numberOfMethods);
+
+ int prevMethodNameId = 0;
+ while (numberOfMethods-- > 0) {
+ final int methodNameId = DataInputOutputUtil.readINT(dataInput) + prevMethodNameId;
+ methodNameIds.add(methodNameId);
+ prevMethodNameId = methodNameId;
+ }
+
+ result.put(classNameId, methodNameIds);
+ prevClassNameId = classNameId;
+ }
+ return result;
+ }
+ }
+
+ private static class MethodQNameSerializer implements KeyDescriptor<Long> {
+ public static final MethodQNameSerializer INSTANCE = new MethodQNameSerializer();
+
+ @Override
+ public void save(@NotNull DataOutput out, Long value) throws IOException {
+ out.writeLong(value);
+ }
+
+ @Override
+ public Long read(@NotNull DataInput in) throws IOException {
+ return in.readLong();
+ }
+
+ @Override
+ public int getHashCode(Long value) {
+ return value.hashCode();
+ }
+
+ @Override
+ public boolean isEqual(Long val1, Long val2) {
+ return val1.equals(val2);
+ }
+ }
+
+ @NotNull
+ static File getVersionFile(String path) {
+ return new File(path + File.separator + "index.version");
+ }
+
+ static long createKey(int classQName, int methodName) {
+ return ((long)classQName << 32) | methodName;
+ }
+
+ static class ValueDiff {
+ final TIntObjectHashMap<TIntArrayList> myAddedOrChangedClassData;
+ final TIntObjectHashMap<TIntArrayList> myRemovedClassData;
+
+ ValueDiff(@Nullable TIntObjectHashMap<TIntArrayList> classData, @Nullable TIntObjectHashMap<TIntArrayList> previousClassData) {
+ TIntObjectHashMap<TIntArrayList> addedOrChangedClassData = classData;
+ TIntObjectHashMap<TIntArrayList> removedClassData = previousClassData;
+
+ if (previousClassData != null && !previousClassData.isEmpty()) {
+ removedClassData = new TIntObjectHashMap<TIntArrayList>();
+ addedOrChangedClassData = new TIntObjectHashMap<TIntArrayList>();
+
+ if (classData != null) {
+ for (int classQName : classData.keys()) {
+ TIntArrayList currentMethods = classData.get(classQName);
+ TIntArrayList previousMethods = previousClassData.get(classQName);
+
+ if (previousMethods == null) {
+ addedOrChangedClassData.put(classQName, currentMethods);
+ continue;
+ }
+
+ final int[] previousMethodIds = previousMethods.toNativeArray();
+ TIntHashSet previousMethodsSet = new TIntHashSet(previousMethodIds);
+ final int[] currentMethodIds = currentMethods.toNativeArray();
+ TIntHashSet currentMethodsSet = new TIntHashSet(currentMethodIds);
+ currentMethodsSet.removeAll(previousMethodIds);
+ previousMethodsSet.removeAll(currentMethodIds);
+
+ if (!currentMethodsSet.isEmpty()) {
+ addedOrChangedClassData.put(classQName, new TIntArrayList(currentMethodsSet.toArray()));
+ }
+ if (!previousMethodsSet.isEmpty()) {
+ removedClassData.put(classQName, new TIntArrayList(previousMethodsSet.toArray()));
+ }
+ }
+ }
+ if (classData != null) {
+ for (int classQName : previousClassData.keys()) {
+ if (classData.containsKey(classQName)) continue;
+
+ TIntArrayList previousMethods = previousClassData.get(classQName);
+ removedClassData.put(classQName, previousMethods);
+ }
+ }
+ }
+
+ myAddedOrChangedClassData = addedOrChangedClassData;
+ myRemovedClassData = removedClassData;
+ }
+
+ public boolean hasRemovedDelta() {
+ return myRemovedClassData != null && !myRemovedClassData.isEmpty();
+ }
+
+ public boolean hasAddedDelta() {
+ return myAddedOrChangedClassData != null && !myAddedOrChangedClassData.isEmpty();
+ }
+ }
+}
val allEntries: List<RecentTestsPopupEntry> = runConfigurationSuites.values + urlSuites
return allEntries
.sortedByDescending { it.runDate }
- .fold(listOf(), { popupList, currentEntry ->
- when (currentEntry) {
- is RunConfigurationEntry -> popupList + currentEntry.entriesToShow()
- else -> popupList + currentEntry
- }
+ .fold(listOf(), { popupList, currentEntry ->
+ popupList + currentEntry.getEntriesToShow()
})
}
-}
-
-fun RunConfigurationEntry.entriesToShow(): List<RecentTestsPopupEntry> {
- if (suites.size == 1) {
- return suites[0].entriesToShow()
- }
-
- val failedSuites = suites.filter { it.failedTests.size > 0 }
- if (failedSuites.size == 0) {
- return listOf(this)
- }
- return failedSuites + this
-}
-
-fun SuiteEntry.entriesToShow(): List<RecentTestsPopupEntry> {
- val failed = failedTests
- if (failed.size > 0) {
- return failed.sortedByDescending { it.runDate } + this
- }
- return listOf(this)
}
\ No newline at end of file
fun run(runner: RecentTestRunner)
open fun navigatableElement(locator: TestLocator): PsiElement? = null
+
+ fun getEntriesToShow(): List<RecentTestsPopupEntry>
}
open class SingleTestEntry(val url: String,
}
override fun navigatableElement(locator: TestLocator) = locator.getLocation(url)?.psiElement
+
+ override fun getEntriesToShow(): List<RecentTestsPopupEntry> = listOf(this)
}
override val presentation = suiteName
+ override fun getEntriesToShow(): List<RecentTestsPopupEntry> {
+ val failed = failedTests
+ if (failed.size > 0) {
+ return failed.sortedByDescending { it.runDate } + this
+ }
+ return listOf(this)
+ }
+
+ override val magnitude: TestStateInfo.Magnitude by lazy {
+ tests.find { it.magnitude != PASSED_INDEX && it.magnitude != COMPLETE_INDEX }?.magnitude ?: PASSED_INDEX
+ }
+
}
override val runDate = suites.map { it.runDate }.min()!!
- override val magnitude = COMPLETE_INDEX
+ override val magnitude: TestStateInfo.Magnitude by lazy {
+ suites.find { it.magnitude != PASSED_INDEX && it.magnitude != COMPLETE_INDEX }?.magnitude ?: PASSED_INDEX
+ }
override val presentation = runSettings.name
override fun run(runner: RecentTestRunner) {
runner.run(runSettings)
}
+
+ override fun getEntriesToShow(): List<RecentTestsPopupEntry> {
+ if (suites.size == 1) {
+ return suites[0].getEntriesToShow()
+ }
+
+ return suites
+ .filter { it.failedTests.size > 0}
+ .sortedByDescending { it.runDate }
+ .fold(listOf<RecentTestsPopupEntry>(), { popupList, currentEntry ->
+ popupList + currentEntry.getEntriesToShow()
+ }) + this
+ }
+
}
import com.intellij.codeInspection.util.RefFilter;
import com.intellij.icons.AllIcons;
import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
super(InspectionsBundle.message("inspection.dead.code.entry.point.quickfix"), null, KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), toolWrapper);
}
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ if (e.getPresentation().isEnabledAndVisible()) {
+ final RefEntity[] elements = getInvoker(e).getTree().getSelectedElements();
+ for (RefEntity element : elements) {
+ if (!((RefElement) element).isEntry()) {
+ return;
+ }
+ }
+ e.getPresentation().setEnabled(false);
+ }
+ }
+
@Override
protected boolean applyFix(@NotNull RefEntity[] refElements) {
final EntryPointsManager entryPointsManager = getEntryPointsManager();
package com.intellij.psi
import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.psi.impl.source.PsiFileImpl
assert !file.stub
assert file.treeElement
}
+
+ public void "test no AST loading on file rename"() {
+ PsiJavaFile file = (PsiJavaFile) myFixture.addFileToProject('a.java', 'class Foo {}')
+ assert file.classes.length == 1
+ assert ((PsiFileImpl)file).stub
+
+ WriteCommandAction.runWriteCommandAction project, { file.setName('b.java') }
+ assert file.classes.length == 1
+ assert ((PsiFileImpl)file).stub
+
+ assert file.classes[0].nameIdentifier.text == 'Foo'
+ assert ((PsiFileImpl)file).contentsLoaded
+ }
}
--- /dev/null
+/*
+ * Copyright 2000-2016 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.intellij.testIntergration
+
+import com.intellij.execution.RunnerAndConfigurationSettings
+import com.intellij.execution.testframework.sm.runner.states.TestStateInfo.Magnitude.FAILED_INDEX
+import com.intellij.execution.testframework.sm.runner.states.TestStateInfo.Magnitude.PASSED_INDEX
+import com.intellij.testFramework.LightIdeaTestCase
+import com.intellij.testIntegration.RecentTestsData
+import org.assertj.core.api.Assertions.assertThat
+import org.mockito.Mockito
+import java.util.*
+
+class RecentTestsOrderTest: LightIdeaTestCase() {
+
+ lateinit var data: RecentTestsData
+ lateinit var allTests: RunnerAndConfigurationSettings
+ lateinit var now: Date
+
+
+ override fun setUp() {
+ super.setUp()
+ data = RecentTestsData()
+ allTests = Mockito.mock(RunnerAndConfigurationSettings::class.java)
+ Mockito.`when`(allTests.uniqueID).thenAnswer { "JUnit.all tests" }
+ Mockito.`when`(allTests.name).thenAnswer { "all tests" }
+ now = Date()
+ }
+
+ fun addPassedSuite(suiteUrl: String, date: Date = Date(), runConfiguration: RunnerAndConfigurationSettings = allTests) {
+ data.addSuite(suiteUrl, PASSED_INDEX, date, runConfiguration)
+ }
+
+ fun addFailedSuite(suiteUrl: String, date: Date = Date(), runConfiguration: RunnerAndConfigurationSettings = allTests) {
+ data.addSuite(suiteUrl, FAILED_INDEX, date, runConfiguration)
+ }
+
+ fun addPassedTest(testUrl: String, date: Date = Date(), runConfiguration: RunnerAndConfigurationSettings = allTests) {
+ data.addTest(testUrl, PASSED_INDEX, date, runConfiguration)
+ }
+
+ fun addFailedTest(testUrl: String, date: Date = Date(), runConfiguration: RunnerAndConfigurationSettings = allTests) {
+ data.addTest(testUrl, FAILED_INDEX, date, runConfiguration)
+ }
+
+ fun `test run configuration with one suite shows only suite`() {
+ val suite = "MySingleTest".suite()
+ val test1 = "MySingleTest.test1".test()
+
+ data.addTest(test1, PASSED_INDEX, now, allTests)
+ data.addSuite(suite, PASSED_INDEX, now, allTests)
+
+ val testsToShow = data.getTestsToShow()
+ assertThat(testsToShow).hasSize(1)
+ assertThat(testsToShow[0].presentation).isEqualTo("MySingleTest")
+ }
+
+ fun `test run configuration with multiple suites shows run configuration name`() {
+ val suite1 = "MyFirstTest".suite()
+ val test1 = "MyFirstTest.test1".test()
+
+ val suite2 = "MySecondTest".suite()
+ val test2 = "MySecondTest.test1".test()
+
+ addPassedSuite(suite1, now)
+ addPassedTest(test1, now)
+
+ addPassedSuite(suite2)
+ addPassedTest(test2)
+
+ val tests = data.getTestsToShow()
+ assertThat(tests).hasSize(1)
+ assertThat(tests[0].presentation).isEqualTo("all tests")
+ }
+
+ fun `test show failed suite in test`() {
+ val suite = "SingleTest".suite()
+ val test = "SingleTest.test".test()
+
+ addPassedSuite(suite)
+ addFailedTest(test)
+
+ val tests = data.getTestsToShow()
+ assertThat(tests).hasSize(2)
+
+ assertThat(tests[0].presentation).isEqualTo("SingleTest.test")
+ assertThat(tests[0].magnitude).isEqualTo(FAILED_INDEX)
+
+ assertThat(tests[1].presentation).isEqualTo("SingleTest")
+ assertThat(tests[1].magnitude).isEqualTo(FAILED_INDEX)
+ }
+
+ fun `test show failed suite and test in run configuration`() {
+ val suite = "SingleTest".suite()
+ val test = "SingleTest.test".test()
+ val test2 = "SingleTest.test2".test()
+
+ addPassedSuite(suite)
+ addFailedTest(test)
+ addPassedTest(test2)
+
+ addPassedSuite("PassedSuite".suite())
+
+ val tests = data.getTestsToShow()
+ assertThat(tests).hasSize(3)
+
+ assertThat(tests[0].presentation).isEqualTo("SingleTest.test")
+ assertThat(tests[0].magnitude).isEqualTo(FAILED_INDEX)
+
+ assertThat(tests[1].presentation).isEqualTo("SingleTest")
+ assertThat(tests[1].magnitude).isEqualTo(FAILED_INDEX)
+
+ assertThat(tests[2].presentation).isEqualTo("all tests")
+ assertThat(tests[2].magnitude).isEqualTo(FAILED_INDEX)
+ }
+
+
+}
\ No newline at end of file
val tests = data.getTestsToShow()
- assertThat(tests).hasSize(2)
- assertThat(tests[0].presentation).isEqualTo("JFSDTest")
- assertThat(tests[1].presentation).isEqualTo("all tests")
+ assertThat(tests).hasSize(3)
+
+ assertThat(tests[0].presentation).isEqualTo("JFSDTest.testItMakesMeSadToFixIt")
+ assertThat(tests[0].magnitude).isEqualTo(FAILED_INDEX)
+
+ assertThat(tests[1].presentation).isEqualTo("JFSDTest")
+ assertThat(tests[1].magnitude).isEqualTo(FAILED_INDEX)
+
+ assertThat(tests[2].presentation).isEqualTo("all tests")
+ assertThat(tests[2].magnitude).isEqualTo(FAILED_INDEX)
}
private final Ref<DocumentListener[]> myCachedDocumentListeners = Ref.create(null);
private final List<DocumentListener> myDocumentListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+ private final List<DocumentBulkUpdateListener> myBulkDocumentInternalListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private final RangeMarkerTree<RangeMarkerEx> myRangeMarkers = new RangeMarkerTree<RangeMarkerEx>(this);
private final RangeMarkerTree<RangeMarkerEx> myPersistentRangeMarkers = new RangeMarkerTree<RangeMarkerEx>(this);
private final List<RangeMarker> myGuardedBlocks = new ArrayList<RangeMarker>();
doRemoveDocumentListener(listener, myCachedDocumentListeners, myDocumentListeners);
}
+ public void addInternalBulkModeListener(@NotNull DocumentBulkUpdateListener listener) {
+ myBulkDocumentInternalListeners.add(listener);
+ }
+
+ public void removeInternalBulkModeListener(@NotNull DocumentBulkUpdateListener listener) {
+ myBulkDocumentInternalListeners.remove(listener);
+ }
+
private static void doRemoveDocumentListener(@NotNull DocumentListener listener,
@NotNull Ref<DocumentListener[]> cachedDocumentListenersRef,
@NotNull List<DocumentListener> documentListeners) {
try {
if (value) {
getPublisher().updateStarted(this);
+ notifyInternalListenersOnBulkModeStarted();
myDoingBulkUpdate = true;
}
else {
myDoingBulkUpdate = false;
+ notifyInternalListenersOnBulkModeFinished();
getPublisher().updateFinished(this);
}
}
}
}
+ private void notifyInternalListenersOnBulkModeStarted() {
+ for (DocumentBulkUpdateListener listener : myBulkDocumentInternalListeners) {
+ listener.updateStarted(this);
+ }
+ }
+
+ private void notifyInternalListenersOnBulkModeFinished() {
+ for (DocumentBulkUpdateListener listener : myBulkDocumentInternalListeners) {
+ listener.updateFinished(this);
+ }
+ }
+
private static class DocumentBulkUpdateListenerHolder {
private static final DocumentBulkUpdateListener ourBulkChangePublisher =
ApplicationManager.getApplication().getMessageBus().syncPublisher(DocumentBulkUpdateListener.TOPIC);
@Override
public PsiElement setName(@NotNull String name) throws IncorrectOperationException {
checkSetName(name);
- beforeAstChange();
doClearCaches("setName");
return PsiFileImplUtil.setName(this, name);
}
FileElement element = getTreeElement();
if (element != null) {
AstPath.invalidatePaths(element);
+ } else {
+ LOG.error("No AST; " + derefStub() + "; " + this + " of " + getClass() + "; " + getViewProvider() + " of " + getViewProvider().getClass());
}
myUseStrongRefs = true;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
+import com.intellij.util.NotNullProducer;
import com.intellij.util.PlatformUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufOutputStream;
+import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
}
@NotNull
- public ActivateStatus lock(@NotNull final String[] args) throws Exception {
+ public ActivateStatus lock(@NotNull String[] args) throws Exception {
log("enter: lock(config=%s system=%s)", myConfigPath, mySystemPath);
return underLocks(() -> {
for (Map.Entry<Integer, Collection<String>> entry : portToPath.entrySet()) {
ActivateStatus status = tryActivate(entry.getKey(), entry.getValue(), args);
if (status != ActivateStatus.NO_INSTANCE) {
+ log("exit: lock(): " + status);
return status;
}
}
}
myToken = UUID.randomUUID().toString();
- final String[] lockedPaths = {myConfigPath, mySystemPath};
+ String[] lockedPaths = {myConfigPath, mySystemPath};
int workerCount = PlatformUtils.isIdeaCommunity() || PlatformUtils.isDatabaseIDE() || PlatformUtils.isCidr() ? 1 : 2;
- myServer = BuiltInServer.startNioOrOio(workerCount, 6942, 50, false,
- () -> new MyChannelInboundHandler(lockedPaths, myActivateListener, myToken));
+ NotNullProducer<ChannelHandler> handler = () -> new MyChannelInboundHandler(lockedPaths, myActivateListener, myToken);
+ myServer = BuiltInServer.startNioOrOio(workerCount, 6942, 50, false, handler);
+
byte[] portBytes = Integer.toString(myServer.getPort()).getBytes(CharsetToolkit.UTF8_CHARSET);
FileUtil.writeToFile(portMarkerC, portBytes);
FileUtil.writeToFile(portMarkerS, portBytes);
+
File tokenFile = new File(mySystemPath, TOKEN_FILE);
FileUtil.writeToFile(tokenFile, myToken.getBytes(CharsetToolkit.UTF8_CHARSET));
PosixFileAttributeView view = Files.getFileAttributeView(tokenFile.toPath(), PosixFileAttributeView.class);
log(e);
}
}
+
log("exit: lock(): succeed");
return ActivateStatus.NO_INSTANCE;
});
private <V> V underLocks(@NotNull Callable<V> action) throws Exception {
FileUtilRt.createDirectory(new File(myConfigPath));
- FileOutputStream lock1 = new FileOutputStream(new File(myConfigPath, PORT_LOCK_FILE), true);
- try {
+ try (@SuppressWarnings("unused") FileOutputStream lock1 = new FileOutputStream(new File(myConfigPath, PORT_LOCK_FILE), true)) {
FileUtilRt.createDirectory(new File(mySystemPath));
- FileOutputStream lock2 = new FileOutputStream(new File(mySystemPath, PORT_LOCK_FILE), true);
- try {
+ try (@SuppressWarnings("unused") FileOutputStream lock2 = new FileOutputStream(new File(mySystemPath, PORT_LOCK_FILE), true)) {
return action.call();
}
- finally {
- lock2.close();
- }
- }
- finally {
- lock1.close();
}
}
import com.intellij.util.concurrency.EdtExecutorService;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
-import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.text.CharArrayCharSequence;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.util.ui.*;
@NotNull private final SoftWrapModelImpl mySoftWrapModel;
@NotNull private static final RepaintCursorCommand ourCaretBlinkingCommand = new RepaintCursorCommand();
- private MessageBusConnection myConnection;
+ private DocumentBulkUpdateListener myBulkUpdateListener;
@MouseSelectionState
private int myMouseSelectionState;
myImmediatePainter = new ImmediatePainter(this);
- if (project != null) {
- myConnection = project.getMessageBus().connect();
- myConnection.subscribe(DocumentBulkUpdateListener.TOPIC, new EditorDocumentBulkUpdateAdapter());
+ if (project != null && myDocument instanceof DocumentImpl) {
+ myBulkUpdateListener = new EditorDocumentBulkUpdateAdapter();
+ ((DocumentImpl)myDocument).addInternalBulkModeListener(myBulkUpdateListener);
}
myMarkupModelListener = new MarkupModelListener() {
myEditorComponent.removeMouseMotionListener(myMouseMotionListener);
myGutterComponent.removeMouseMotionListener(myMouseMotionListener);
- if (myConnection != null) {
- myConnection.disconnect();
+ if (myBulkUpdateListener != null) {
+ ((DocumentImpl)myDocument).removeInternalBulkModeListener(myBulkUpdateListener);
}
if (myDocument instanceof DocumentImpl && !myUseNewRendering) {
((DocumentImpl)myDocument).giveUpTabTracking();
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.pom.Navigatable;
import com.intellij.psi.PsiElement;
-import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBList;
import com.intellij.ui.speedSearch.ListWithFilter;
import com.intellij.util.ArrayUtil;
@Nullable
protected JComponent createDefaultRightComponent() {
- final JBLabel label = new JBLabel("Nothing selected", SwingConstants.CENTER);
- label.setFontColor(UIUtil.FontColor.BRIGHTER);
- return label;
+ JBList list = new JBList();
+ list.setEmptyText("Nothing selected");
+ return list;
}
protected JComponent createLeftComponent() {
launch_with_port(port, token)
except:
type, value, traceback = sys.exc_info()
- print('No IDE instance has been found. New one will be started.') # todo error
+ print('Cannot activate a running instance: ' + str(value))
else:
print('No IDE instance has been found. New one will be started.')
if sys.platform == "darwin":
import com.intellij.openapi.editor.event.CaretEvent;
import com.intellij.openapi.editor.event.SelectionEvent;
import com.intellij.openapi.editor.event.SelectionListener;
+import com.intellij.openapi.editor.ex.DocumentBulkUpdateListener;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.util.EditorUtil;
+import com.intellij.openapi.editor.markup.HighlighterTargetArea;
+import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.testFramework.EditorTestUtil;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
assertEquals("caret:LogicalPosition: (0, 7)selection:(4,7)", output.toString());
checkResultByText(" abc<selection>def<caret></selection>");
}
+
+ public void testChangingHighlightersInBulkModeListener() throws Exception {
+ DocumentBulkUpdateListener.Adapter listener = new DocumentBulkUpdateListener.Adapter() {
+ @Override
+ public void updateFinished(@NotNull Document doc) {
+ if (doc == myEditor.getDocument()) {
+ myEditor.getMarkupModel().addRangeHighlighter(7, 8, 0, null, HighlighterTargetArea.EXACT_RANGE);
+ }
+ }
+ };
+ getProject().getMessageBus().connect(myTestRootDisposable).subscribe(DocumentBulkUpdateListener.TOPIC, listener);
+ initText("abcdef");
+ DocumentEx document = (DocumentEx)myEditor.getDocument();
+ new WriteCommandAction.Simple(getProject()) {
+ @Override
+ protected void run() throws Throwable {
+ document.setInBulkUpdate(true);
+ document.insertString(3, "\n\n");
+ document.setInBulkUpdate(false);
+ }
+ }.execute();
+ RangeHighlighter[] highlighters = myEditor.getMarkupModel().getAllHighlighters();
+ assertEquals(1, highlighters.length);
+ assertEquals(7, highlighters[0].getStartOffset());
+ assertEquals(8, highlighters[0].getEndOffset());
+ }
}
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.NoTestsRemainException;
+import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
public void run(final TestResult testResult) {
loadTestRecorder();
+ final TestListener testListener = loadDiscoveryListener();
+ if (testListener != null) {
+ testResult.addListener(testListener);
+ }
+
List<Class> classes = myTestCaseLoader.getClasses();
int totalTests = classes.size();
for (Class<?> aClass : classes) {
if (testResult.shouldStop()) break;
}
+ if (testListener instanceof Closeable) {
+ try {
+ ((Closeable)testListener).close();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
tryGc(10);
}
+ private TestListener loadDiscoveryListener() {
+ final String discoveryListener = System.getProperty("test.discovery.listener");
+ if (discoveryListener != null) {
+ try {
+ return (TestListener)Class.forName(discoveryListener).newInstance();
+ }
+ catch (Throwable e) {
+ return null;
+ }
+ }
+ return null;
+ }
+
private static boolean shouldRecord(@NotNull Class<?> aClass) {
return aClass.getAnnotation(RecordExecution.class) != null;
}
package com.intellij.execution;
import com.intellij.AppTopics;
+import com.intellij.execution.testframework.autotest.AutoTestWatcher;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import java.util.Collection;
import java.util.Set;
-public class DelayedDocumentWatcher {
+public class DelayedDocumentWatcher implements AutoTestWatcher {
// All instance fields are be accessed from EDT
private final Project myProject;
--- /dev/null
+/*
+ * Copyright 2000-2016 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.intellij.execution.testframework.autotest;
+
+import com.intellij.execution.ExecutionManager;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.execution.configurations.RunProfile;
+import com.intellij.execution.impl.RunManagerImpl;
+import com.intellij.execution.process.ProcessAdapter;
+import com.intellij.execution.process.ProcessEvent;
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.execution.process.ProcessListener;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.execution.runners.ExecutionUtil;
+import com.intellij.execution.ui.RunContentDescriptor;
+import com.intellij.execution.ui.RunContentManager;
+import com.intellij.ide.DataManager;
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.ui.content.Content;
+import com.intellij.util.ObjectUtils;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.xmlb.annotations.AbstractCollection;
+import com.intellij.util.xmlb.annotations.Attribute;
+import com.intellij.util.xmlb.annotations.Tag;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.List;
+import java.util.Set;
+
+public abstract class AbstractAutoTestManager implements PersistentStateComponent<AbstractAutoTestManager.State> {
+ protected static final String AUTO_TEST_MANAGER_DELAY = "auto.test.manager.delay";
+ protected static final int AUTO_TEST_MANAGER_DELAY_DEFAULT = 3000;
+ private static final Key<ProcessListener> ON_TERMINATION_RESTARTER_KEY = Key.create("auto.test.manager.on.termination.restarter");
+ private final Project myProject;
+ private final Set<RunProfile> myEnabledRunProfiles = ContainerUtil.newHashSet();
+ protected int myDelayMillis;
+ private AutoTestWatcher myWatcher;
+
+ public AbstractAutoTestManager(@NotNull Project project) {
+ myProject = project;
+ myDelayMillis = PropertiesComponent.getInstance(project).getInt(AUTO_TEST_MANAGER_DELAY, AUTO_TEST_MANAGER_DELAY_DEFAULT);
+ myWatcher = createWatcher(project);
+ }
+
+ @Nullable
+ private static ExecutionEnvironment getCurrentEnvironment(@NotNull Content content) {
+ JComponent component = content.getComponent();
+ if (component == null) {
+ return null;
+ }
+ return LangDataKeys.EXECUTION_ENVIRONMENT.getData(DataManager.getInstance().getDataContext(component));
+ }
+
+ private static void clearRestarterListener(@NotNull ProcessHandler processHandler) {
+ ProcessListener restarterListener = ON_TERMINATION_RESTARTER_KEY.get(processHandler, null);
+ if (restarterListener != null) {
+ processHandler.removeProcessListener(restarterListener);
+ ON_TERMINATION_RESTARTER_KEY.set(processHandler, null);
+ }
+ }
+
+ private static void restart(@NotNull RunContentDescriptor descriptor) {
+ descriptor.setActivateToolWindowWhenAdded(false);
+ descriptor.setReuseToolWindowActivation(true);
+ ExecutionUtil.restart(descriptor);
+ }
+
+ public static void saveConfigurationState(State state, RunProfile profile) {
+ RunConfiguration runConfiguration = ObjectUtils.tryCast(profile, RunConfiguration.class);
+ if (runConfiguration != null) {
+ RunConfigurationDescriptor descriptor = new RunConfigurationDescriptor();
+ descriptor.myType = runConfiguration.getType().getId();
+ descriptor.myName = runConfiguration.getName();
+ state.myEnabledRunConfigurations.add(descriptor);
+ }
+ }
+
+ public static List<RunConfiguration> loadConfigurations(State state, Project project) {
+ List<RunConfiguration> configurations = ContainerUtil.newArrayList();
+ RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(project);
+ List<RunConfigurationDescriptor> descriptors = ContainerUtil.notNullize(state.myEnabledRunConfigurations);
+ for (RunConfigurationDescriptor descriptor : descriptors) {
+ if (descriptor.myType != null && descriptor.myName != null) {
+ RunnerAndConfigurationSettings settings = runManager.findConfigurationByTypeAndName(descriptor.myType,
+ descriptor.myName);
+ RunConfiguration configuration = settings != null ? settings.getConfiguration() : null;
+ if (configuration != null) {
+ configurations.add(configuration);
+ }
+ }
+ }
+ return configurations;
+ }
+
+ @NotNull
+ protected abstract AutoTestWatcher createWatcher(Project project);
+
+ public void setAutoTestEnabled(@NotNull RunContentDescriptor descriptor, @NotNull ExecutionEnvironment environment, boolean enabled) {
+ Content content = descriptor.getAttachedContent();
+ if (content != null) {
+ if (enabled) {
+ myEnabledRunProfiles.add(environment.getRunProfile());
+ myWatcher.activate();
+ }
+ else {
+ myEnabledRunProfiles.remove(environment.getRunProfile());
+ if (!hasEnabledAutoTests()) {
+ myWatcher.deactivate();
+ }
+ ProcessHandler processHandler = descriptor.getProcessHandler();
+ if (processHandler != null) {
+ clearRestarterListener(processHandler);
+ }
+ }
+ }
+ }
+
+ private boolean hasEnabledAutoTests() {
+ RunContentManager contentManager = ExecutionManager.getInstance(myProject).getContentManager();
+ for (RunContentDescriptor descriptor : contentManager.getAllDescriptors()) {
+ if (isAutoTestEnabledForDescriptor(descriptor)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean isAutoTestEnabled(@NotNull RunContentDescriptor descriptor) {
+ return isAutoTestEnabledForDescriptor(descriptor);
+ }
+
+ private boolean isAutoTestEnabledForDescriptor(@NotNull RunContentDescriptor descriptor) {
+ Content content = descriptor.getAttachedContent();
+ if (content != null) {
+ ExecutionEnvironment environment = getCurrentEnvironment(content);
+ return environment != null && myEnabledRunProfiles.contains(environment.getRunProfile());
+ }
+ return false;
+ }
+
+ protected void restartAllAutoTests(int modificationStamp) {
+ RunContentManager contentManager = ExecutionManager.getInstance(myProject).getContentManager();
+ boolean active = false;
+ for (RunContentDescriptor descriptor : contentManager.getAllDescriptors()) {
+ if (isAutoTestEnabledForDescriptor(descriptor)) {
+ restartAutoTest(descriptor, modificationStamp, myWatcher);
+ active = true;
+ }
+ }
+ if (!active) {
+ myWatcher.deactivate();
+ }
+ }
+
+ private void restartAutoTest(@NotNull RunContentDescriptor descriptor,
+ int modificationStamp,
+ @NotNull AutoTestWatcher documentWatcher) {
+ ProcessHandler processHandler = descriptor.getProcessHandler();
+ if (processHandler != null && !processHandler.isProcessTerminated()) {
+ scheduleRestartOnTermination(descriptor, processHandler, modificationStamp, documentWatcher);
+ }
+ else {
+ restart(descriptor);
+ }
+ }
+
+ private void scheduleRestartOnTermination(@NotNull final RunContentDescriptor descriptor,
+ @NotNull final ProcessHandler processHandler,
+ final int modificationStamp,
+ @NotNull final AutoTestWatcher watcher) {
+ ProcessListener restarterListener = ON_TERMINATION_RESTARTER_KEY.get(processHandler);
+ if (restarterListener != null) {
+ clearRestarterListener(processHandler);
+ }
+ restarterListener = new ProcessAdapter() {
+ @Override
+ public void processTerminated(ProcessEvent event) {
+ clearRestarterListener(processHandler);
+ ApplicationManager.getApplication().invokeLater(() -> {
+ if (isAutoTestEnabledForDescriptor(descriptor) && watcher.isUpToDate(modificationStamp)) {
+ restart(descriptor);
+ }
+ }, ModalityState.any());
+ }
+ };
+ ON_TERMINATION_RESTARTER_KEY.set(processHandler, restarterListener);
+ processHandler.addProcessListener(restarterListener);
+ }
+
+ int getDelay() {
+ return myDelayMillis;
+ }
+
+ void setDelay(int delay) {
+ myDelayMillis = delay;
+ myWatcher.deactivate();
+ myWatcher = createWatcher(myProject);
+ if (hasEnabledAutoTests()) {
+ myWatcher.activate();
+ }
+ PropertiesComponent.getInstance(myProject).setValue(AUTO_TEST_MANAGER_DELAY, myDelayMillis, AUTO_TEST_MANAGER_DELAY_DEFAULT);
+ }
+
+ @Nullable
+ @Override
+ public State getState() {
+ State state = new State();
+ for (RunProfile profile : myEnabledRunProfiles) {
+ saveConfigurationState(state, profile);
+ }
+ return state;
+ }
+
+ @Override
+ public void loadState(State state) {
+ List<RunConfiguration> configurations = loadConfigurations(state, myProject);
+ myEnabledRunProfiles.clear();
+ myEnabledRunProfiles.addAll(configurations);
+ if (!configurations.isEmpty()) {
+ myWatcher.activate();
+ }
+ }
+
+ public static class State {
+ @Tag("enabled-run-configurations")
+ @AbstractCollection(surroundWithTag = false)
+ List<AutoTestManager.RunConfigurationDescriptor> myEnabledRunConfigurations = ContainerUtil.newArrayList();
+ }
+
+ @Tag("run-configuration")
+ static class RunConfigurationDescriptor {
+ @Attribute("type")
+ String myType;
+
+ @Attribute("name")
+ String myName;
+ }
+}
package com.intellij.execution.testframework.autotest;
import com.intellij.execution.*;
-import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.execution.configurations.RunProfile;
-import com.intellij.execution.impl.RunManagerImpl;
-import com.intellij.execution.process.ProcessAdapter;
-import com.intellij.execution.process.ProcessEvent;
-import com.intellij.execution.process.ProcessHandler;
-import com.intellij.execution.process.ProcessListener;
-import com.intellij.execution.runners.ExecutionEnvironment;
-import com.intellij.execution.runners.ExecutionUtil;
-import com.intellij.execution.ui.RunContentDescriptor;
-import com.intellij.execution.ui.RunContentManager;
-import com.intellij.ide.DataManager;
import com.intellij.ide.scratch.ScratchFileService;
-import com.intellij.ide.util.PropertiesComponent;
-import com.intellij.openapi.actionSystem.LangDataKeys;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.*;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.ui.content.Content;
-import com.intellij.util.Consumer;
-import com.intellij.util.ObjectUtils;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.xmlb.annotations.AbstractCollection;
-import com.intellij.util.xmlb.annotations.Attribute;
-import com.intellij.util.xmlb.annotations.Tag;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import java.util.List;
-import java.util.Set;
/**
* @author yole
name = "AutoTestManager",
storages = {@Storage(StoragePathMacros.WORKSPACE_FILE)}
)
-public class AutoTestManager implements PersistentStateComponent<AutoTestManager.State> {
- private static final String AUTO_TEST_MANAGER_DELAY = "auto.test.manager.delay";
- private static final int AUTO_TEST_MANAGER_DELAY_DEFAULT = 3000;
-
- private static final Key<ProcessListener> ON_TERMINATION_RESTARTER_KEY = Key.create("auto.test.manager.on.termination.restarter");
-
- private final Project myProject;
- private int myDelayMillis;
- private DelayedDocumentWatcher myDocumentWatcher;
- private final Set<RunProfile> myEnabledRunProfiles = ContainerUtil.newHashSet();
+public class AutoTestManager extends AbstractAutoTestManager {
@NotNull
public static AutoTestManager getInstance(Project project) {
}
public AutoTestManager(@NotNull Project project) {
- myProject = project;
- myDelayMillis = PropertiesComponent.getInstance(project).getInt(AUTO_TEST_MANAGER_DELAY, AUTO_TEST_MANAGER_DELAY_DEFAULT);
- myDocumentWatcher = createWatcher();
+ super(project);
}
+ @Override
@NotNull
- private DelayedDocumentWatcher createWatcher() {
- return new DelayedDocumentWatcher(myProject, myDelayMillis, modificationStamp -> restartAllAutoTests(modificationStamp), file -> {
+ protected AutoTestWatcher createWatcher(Project project) {
+ return new DelayedDocumentWatcher(project, myDelayMillis, this::restartAllAutoTests, file -> {
if (ScratchFileService.getInstance().getRootType(file) != null) {
return false;
}
// Vladimir.Krivosheev - I don't know, why AutoTestManager checks it, but old behavior is preserved
- return FileEditorManager.getInstance(myProject).isFileOpen(file);
+ return FileEditorManager.getInstance(project).isFileOpen(file);
});
}
-
- public void setAutoTestEnabled(@NotNull RunContentDescriptor descriptor, @NotNull ExecutionEnvironment environment, boolean enabled) {
- Content content = descriptor.getAttachedContent();
- if (content != null) {
- if (enabled) {
- myEnabledRunProfiles.add(environment.getRunProfile());
- myDocumentWatcher.activate();
- }
- else {
- myEnabledRunProfiles.remove(environment.getRunProfile());
- if (!hasEnabledAutoTests()) {
- myDocumentWatcher.deactivate();
- }
- ProcessHandler processHandler = descriptor.getProcessHandler();
- if (processHandler != null) {
- clearRestarterListener(processHandler);
- }
- }
- }
- }
-
- private boolean hasEnabledAutoTests() {
- RunContentManager contentManager = ExecutionManager.getInstance(myProject).getContentManager();
- for (RunContentDescriptor descriptor : contentManager.getAllDescriptors()) {
- if (isAutoTestEnabledForDescriptor(descriptor)) {
- return true;
- }
- }
- return false;
- }
-
- public boolean isAutoTestEnabled(@NotNull RunContentDescriptor descriptor) {
- return isAutoTestEnabledForDescriptor(descriptor);
- }
-
- private boolean isAutoTestEnabledForDescriptor(@NotNull RunContentDescriptor descriptor) {
- Content content = descriptor.getAttachedContent();
- if (content != null) {
- ExecutionEnvironment environment = getCurrentEnvironment(content);
- return environment != null && myEnabledRunProfiles.contains(environment.getRunProfile());
- }
- return false;
- }
-
- @Nullable
- private static ExecutionEnvironment getCurrentEnvironment(@NotNull Content content) {
- JComponent component = content.getComponent();
- if (component == null) {
- return null;
- }
- return LangDataKeys.EXECUTION_ENVIRONMENT.getData(DataManager.getInstance().getDataContext(component));
- }
-
- private static void clearRestarterListener(@NotNull ProcessHandler processHandler) {
- ProcessListener restarterListener = ON_TERMINATION_RESTARTER_KEY.get(processHandler, null);
- if (restarterListener != null) {
- processHandler.removeProcessListener(restarterListener);
- ON_TERMINATION_RESTARTER_KEY.set(processHandler, null);
- }
- }
-
- private void restartAllAutoTests(int modificationStamp) {
- RunContentManager contentManager = ExecutionManager.getInstance(myProject).getContentManager();
- boolean active = false;
- for (RunContentDescriptor descriptor : contentManager.getAllDescriptors()) {
- if (isAutoTestEnabledForDescriptor(descriptor)) {
- restartAutoTest(descriptor, modificationStamp, myDocumentWatcher);
- active = true;
- }
- }
- if (!active) {
- myDocumentWatcher.deactivate();
- }
- }
-
- private void restartAutoTest(@NotNull RunContentDescriptor descriptor,
- int modificationStamp,
- @NotNull DelayedDocumentWatcher documentWatcher) {
- ProcessHandler processHandler = descriptor.getProcessHandler();
- if (processHandler != null && !processHandler.isProcessTerminated()) {
- scheduleRestartOnTermination(descriptor, processHandler, modificationStamp, documentWatcher);
- }
- else {
- restart(descriptor);
- }
- }
-
- private void scheduleRestartOnTermination(@NotNull final RunContentDescriptor descriptor,
- @NotNull final ProcessHandler processHandler,
- final int modificationStamp,
- @NotNull final DelayedDocumentWatcher documentWatcher) {
- ProcessListener restarterListener = ON_TERMINATION_RESTARTER_KEY.get(processHandler);
- if (restarterListener != null) {
- clearRestarterListener(processHandler);
- }
- restarterListener = new ProcessAdapter() {
- @Override
- public void processTerminated(ProcessEvent event) {
- clearRestarterListener(processHandler);
- ApplicationManager.getApplication().invokeLater(() -> {
- if (isAutoTestEnabledForDescriptor(descriptor) && documentWatcher.isUpToDate(modificationStamp)) {
- restart(descriptor);
- }
- }, ModalityState.any());
- }
- };
- ON_TERMINATION_RESTARTER_KEY.set(processHandler, restarterListener);
- processHandler.addProcessListener(restarterListener);
- }
-
- private static void restart(@NotNull RunContentDescriptor descriptor) {
- descriptor.setActivateToolWindowWhenAdded(false);
- descriptor.setReuseToolWindowActivation(true);
- ExecutionUtil.restart(descriptor);
- }
-
- int getDelay() {
- return myDelayMillis;
- }
-
- void setDelay(int delay) {
- myDelayMillis = delay;
- myDocumentWatcher.deactivate();
- myDocumentWatcher = createWatcher();
- if (hasEnabledAutoTests()) {
- myDocumentWatcher.activate();
- }
- PropertiesComponent.getInstance(myProject).setValue(AUTO_TEST_MANAGER_DELAY, myDelayMillis, AUTO_TEST_MANAGER_DELAY_DEFAULT);
- }
-
- @Nullable
- @Override
- public State getState() {
- State state = new State();
- for (RunProfile profile : myEnabledRunProfiles) {
- RunConfiguration runConfiguration = ObjectUtils.tryCast(profile, RunConfiguration.class);
- if (runConfiguration != null) {
- RunConfigurationDescriptor descriptor = new RunConfigurationDescriptor();
- descriptor.myType = runConfiguration.getType().getId();
- descriptor.myName = runConfiguration.getName();
- state.myEnabledRunConfigurations.add(descriptor);
- }
- }
- return state;
- }
-
- @Override
- public void loadState(State state) {
- List<RunConfiguration> configurations = ContainerUtil.newArrayList();
- RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(myProject);
- List<RunConfigurationDescriptor> descriptors = ContainerUtil.notNullize(state.myEnabledRunConfigurations);
- for (RunConfigurationDescriptor descriptor : descriptors) {
- if (descriptor.myType != null && descriptor.myName != null) {
- RunnerAndConfigurationSettings settings = runManager.findConfigurationByTypeAndName(descriptor.myType,
- descriptor.myName);
- RunConfiguration configuration = settings != null ? settings.getConfiguration() : null;
- if (configuration != null) {
- configurations.add(configuration);
- }
- }
- }
- myEnabledRunProfiles.clear();
- myEnabledRunProfiles.addAll(configurations);
- }
-
- static class State {
- @Tag("enabled-run-configurations")
- @AbstractCollection(surroundWithTag = false)
- List<RunConfigurationDescriptor> myEnabledRunConfigurations = ContainerUtil.newArrayList();
- }
-
- @Tag("run-configuration")
- static class RunConfigurationDescriptor {
- @Attribute("type")
- String myType;
-
- @Attribute("name")
- String myName;
- }
}
--- /dev/null
+/*
+ * Copyright 2000-2016 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.intellij.execution.testframework.autotest;
+
+public interface AutoTestWatcher {
+ void activate();
+ void deactivate();
+
+ boolean isUpToDate(int modificationStamp);
+}
public boolean isSelected(AnActionEvent e) {
Project project = e.getProject();
RunContentDescriptor descriptor = e.getData(LangDataKeys.RUN_CONTENT_DESCRIPTOR);
- return project != null && descriptor != null && AutoTestManager.getInstance(project).isAutoTestEnabled(descriptor);
+ return project != null && descriptor != null && getAutoTestManager(project).isAutoTestEnabled(descriptor);
}
@Override
RunContentDescriptor descriptor = e.getData(LangDataKeys.RUN_CONTENT_DESCRIPTOR);
ExecutionEnvironment environment = e.getData(LangDataKeys.EXECUTION_ENVIRONMENT);
if (project != null && descriptor != null && environment != null) {
- AutoTestManager.getInstance(project).setAutoTestEnabled(descriptor, environment, state);
+ getAutoTestManager(project).setAutoTestEnabled(descriptor, environment, state);
}
}
+
+ public AbstractAutoTestManager getAutoTestManager(Project project) {
+ return AutoTestManager.getInstance(project);
+ }
}
GitSimpleHandler diff = new GitSimpleHandler(project, root, GitCommand.DIFF);
diff.setSilent(true);
diff.setStdoutSuppressed(true);
- diff.addParameters("--diff-filter=ADMRUX", "--name-status", "HEAD");
+ diff.addParameters("--diff-filter=ADMRUX", "--name-status", "--no-renames", "HEAD");
diff.endOptions();
String output;
try {
GitSimpleHandler h = new GitSimpleHandler(myProject, myRoot, GitCommand.DIFF);
h.setSilent(true);
// note that moves are not detected here
- h.addParameters("--name-status", "--diff-filter=ADMRUX", revisions);
+ h.addParameters("--name-status", "--diff-filter=ADMRUX", "--no-renames", revisions);
for (StringScanner s = new StringScanner(h.run()); s.hasMoreData();) {
if (s.isEol()) {
s.nextLine();
<programRunner implementation="com.intellij.execution.junit.JUnitDebuggerRunner"/>
<codeInsight.externalLibraryResolver implementation="com.intellij.execution.junit.codeInsight.JUnitExternalLibraryResolver"/>
<junitListener implementation="com.intellij.junit4.JUnitTestDiscoveryListener"/>
- <configurationType implementation="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationType"/>
<runConfigurationProducer implementation="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer"/>
</extensions>
@NonNls public static final String TEST_DIRECTORY = "directory";
@NonNls public static final String TEST_CATEGORY = "category";
@NonNls public static final String TEST_METHOD = "method";
+ @NonNls public static final String BY_SOURCE_POSITION = "source location";
+ @NonNls public static final String BY_SOURCE_CHANGES = "changes";
//fork modes
@NonNls public static final String FORK_NONE = "none";
setGeneratedName();
}
+ public void beFromSourcePosition(PsiLocation<PsiMethod> sourceLocation) {
+ myData.setTestMethod(sourceLocation);
+ myData.TEST_OBJECT = BY_SOURCE_POSITION;
+ }
+
public void setMainClass(final PsiClass testClass) {
final boolean shouldUpdateName = isGeneratedName();
setModule(myData.setMainClass(testClass));
private String REPEAT_MODE = RepeatCount.ONCE;
private LinkedHashSet<String> myPattern = new LinkedHashSet<String>();
private Map<String, String> myEnvs = new LinkedHashMap<String, String>();
+ private String myChangeList = "All";
public boolean equals(final Object object) {
if (!(object instanceof Data)) return false;
public void setCategoryName(String categoryName) {
CATEGORY_NAME = categoryName;
}
+
+ public String getChangeList() {
+ return myChangeList;
+ }
+
+ public void setChangeList(String changeList) {
+ myChangeList = changeList;
+ }
}
}
import com.intellij.execution.JavaTestFrameworkDebuggerRunner;
import com.intellij.execution.configurations.RunProfile;
-import com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfiguration;
import org.jetbrains.annotations.NotNull;
/**
public class JUnitDebuggerRunner extends JavaTestFrameworkDebuggerRunner {
@Override
protected boolean validForProfile(@NotNull RunProfile profile) {
- return profile instanceof JUnitConfiguration ||
- profile instanceof JUnitTestDiscoveryConfiguration;
+ return profile instanceof JUnitConfiguration;
}
@NotNull
import com.intellij.execution.configurations.ParametersList;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.configurations.RuntimeConfigurationException;
+import com.intellij.execution.junit.testDiscovery.TestBySource;
+import com.intellij.execution.junit.testDiscovery.TestsByChanges;
import com.intellij.execution.junit2.TestProxy;
import com.intellij.execution.junit2.segments.DeferredActionsQueue;
import com.intellij.execution.junit2.segments.DeferredActionsQueueImpl;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
if (JUnitConfiguration.TEST_PATTERN.equals(id)) {
return new TestsPattern(configuration, environment);
}
+ if (JUnitConfiguration.BY_SOURCE_POSITION.equals(id)) {
+ return new TestBySource(configuration, environment);
+ }
+ if (JUnitConfiguration.BY_SOURCE_CHANGES.equals(id)) {
+ return new TestsByChanges(configuration, environment);
+ }
LOG.error(MESSAGE + id);
return null;
}
+++ /dev/null
-/*
- * 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.intellij.execution.junit.testDiscovery;
-
-import com.intellij.execution.ExecutionException;
-import com.intellij.execution.Executor;
-import com.intellij.execution.configurations.*;
-import com.intellij.execution.junit.JUnitConfiguration;
-import com.intellij.execution.junit.JUnitConfigurationType;
-import com.intellij.execution.junit.TestObject;
-import com.intellij.execution.runners.ExecutionEnvironment;
-import com.intellij.execution.testDiscovery.TestDiscoveryConfiguration;
-import com.intellij.execution.testDiscovery.TestDiscoverySearchHelper;
-import com.intellij.execution.testframework.SearchForTestsTask;
-import com.intellij.execution.testframework.SourceScope;
-import com.intellij.execution.testframework.TestSearchScope;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.*;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.refactoring.listeners.RefactoringElementListener;
-import com.intellij.util.FunctionUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Set;
-
-public class JUnitTestDiscoveryConfiguration extends TestDiscoveryConfiguration {
-
- public JUnitTestDiscoveryConfiguration(String name, Project project, ConfigurationFactory factory) {
- super(name, new JavaRunConfigurationModule(project, false), factory,
- new JUnitConfiguration("", project, JUnitConfigurationType.getInstance().getConfigurationFactories()[0]));
- }
-
- @Nullable
- @Override
- public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment) throws ExecutionException {
- return new JUnitTestDiscoveryRunnableState(environment);
- }
-
- @Nullable
- @Override
- public RefactoringElementListener getRefactoringElementListener(PsiElement element) {
- return null;
- }
-
- @NotNull
- @Override
- public String getFrameworkPrefix() {
- return "j";
- }
-
- private class JUnitTestDiscoveryRunnableState extends TestObject {
- public JUnitTestDiscoveryRunnableState(ExecutionEnvironment environment) {
- super(((JUnitConfiguration)myDelegate), environment);
- }
-
- @Override
- protected TestSearchScope getScope() {
- return getConfigurationModule().getModule() != null ? TestSearchScope.MODULE_WITH_DEPENDENCIES : TestSearchScope.WHOLE_PROJECT;
- }
-
- @Override
- protected boolean forkPerModule() {
- return spansMultipleModules("");
- }
-
- @Override
- protected PsiElement retrievePsiElement(Object pattern) {
- if (pattern instanceof String) {
- final String className = StringUtil.getPackageName((String)pattern, ',');
- if (!pattern.equals(className)) {
- final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
- final SourceScope sourceScope = getSourceScope();
- final GlobalSearchScope globalSearchScope = sourceScope != null ? sourceScope.getGlobalSearchScope()
- : GlobalSearchScope.projectScope(getProject());
- return facade.findClass(className, globalSearchScope);
- }
- }
- return null;
- }
-
- @Override
- public SearchForTestsTask createSearchingForTestsTask() {
- return new SearchForTestsTask(getProject(), myServerSocket) {
-
- private Set<String> myPatterns;
-
- @Override
- protected void search() throws ExecutionException {
- myPatterns = TestDiscoverySearchHelper.search(getProject(), getPosition(), getChangeList(), getFrameworkPrefix());
- }
-
- @Override
- protected void onFound() {
- if (myPatterns != null) {
- try {
- addClassesListToJavaParameters(myPatterns, FunctionUtil.<String>id(), "", false, getJavaParameters());
- }
- catch (ExecutionException ignored) {}
- }
- }
- };
- }
-
- @Override
- protected JavaParameters createJavaParameters() throws ExecutionException {
- final JavaParameters javaParameters = super.createJavaParameters();
- createTempFiles(javaParameters);
-
- createServerSocket(javaParameters);
- return javaParameters;
- }
-
- @Override
- public String suggestActionName() {
- return "";
- }
-
- @Override
- public RefactoringElementListener getListener(PsiElement element, JUnitConfiguration configuration) {
- return null;
- }
-
- @Override
- public boolean isConfiguredByElement(JUnitConfiguration configuration,
- PsiClass testClass,
- PsiMethod testMethod,
- PsiPackage testPackage,
- PsiDirectory testDir) {
- return false;
- }
- }
-}
*/
package com.intellij.execution.junit.testDiscovery;
-import com.intellij.execution.configurations.ConfigurationTypeUtil;
+import com.intellij.execution.JavaTestConfigurationBase;
+import com.intellij.execution.PsiLocation;
+import com.intellij.execution.junit.JUnitConfiguration;
+import com.intellij.execution.junit.JUnitConfigurationType;
import com.intellij.execution.testDiscovery.TestDiscoveryConfigurationProducer;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiMethod;
public class JUnitTestDiscoveryConfigurationProducer extends TestDiscoveryConfigurationProducer {
protected JUnitTestDiscoveryConfigurationProducer() {
- super(ConfigurationTypeUtil.findConfigurationType(JUnitTestDiscoveryConfigurationType.class));
+ super(JUnitConfigurationType.getInstance());
+ }
+
+ @Override
+ protected void setPosition(JavaTestConfigurationBase configuration, PsiLocation<PsiMethod> position) {
+ ((JUnitConfiguration)configuration).beFromSourcePosition(position);
+ }
+
+ @Override
+ protected Pair<String, String> getPosition(JavaTestConfigurationBase configuration) {
+ final JUnitConfiguration.Data data = ((JUnitConfiguration)configuration).getPersistentData();
+ if (data.TEST_OBJECT.equals(JUnitConfiguration.BY_SOURCE_POSITION)) {
+ return Pair.create(data.getMainClassName(), data.getMethodName());
+ }
+ return null;
}
}
+++ /dev/null
-/*
- * 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.intellij.execution.junit.testDiscovery;
-
-import com.intellij.execution.configuration.ConfigurationFactoryEx;
-import com.intellij.execution.configurations.ConfigurationFactory;
-import com.intellij.execution.configurations.ConfigurationType;
-import com.intellij.execution.configurations.ModuleBasedConfiguration;
-import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.execution.testDiscovery.TestDiscoveryConfiguration;
-import com.intellij.icons.AllIcons;
-import com.intellij.openapi.project.Project;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-
-public class JUnitTestDiscoveryConfigurationType implements ConfigurationType {
- private final ConfigurationFactory myFactory;
-
- public JUnitTestDiscoveryConfigurationType() {
- myFactory = new ConfigurationFactoryEx(this) {
- public RunConfiguration createTemplateConfiguration(Project project) {
- return new JUnitTestDiscoveryConfiguration("", project, this);
- }
-
- @Override
- public void onNewConfigurationCreated(@NotNull RunConfiguration configuration) {
- ((ModuleBasedConfiguration)configuration).onNewConfigurationCreated();
- }
- };
- }
-
- @Override
- public String getDisplayName() {
- return "JUnit Test Discovery";
- }
-
- @Override
- public String getConfigurationTypeDescription() {
- return "Runs junit tests which passed changed code";
- }
-
- @Override
- public Icon getIcon() {
- return AllIcons.RunConfigurations.Junit;
- }
-
- @NotNull
- @Override
- public String getId() {
- return "JUnitTestDiscovery";
- }
-
- @Override
- public ConfigurationFactory[] getConfigurationFactories() {
- return new ConfigurationFactory[] {myFactory};
- }
-}
--- /dev/null
+/*
+ * Copyright 2000-2016 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.intellij.execution.junit.testDiscovery;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.JavaParameters;
+import com.intellij.execution.junit.JUnitConfiguration;
+import com.intellij.execution.junit.TestObject;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.execution.testDiscovery.TestDiscoverySearchHelper;
+import com.intellij.execution.testframework.SearchForTestsTask;
+import com.intellij.execution.testframework.SourceScope;
+import com.intellij.execution.testframework.TestSearchScope;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.refactoring.listeners.RefactoringElementListener;
+import com.intellij.util.FunctionUtil;
+
+import java.util.Set;
+
+abstract class JUnitTestDiscoveryRunnableState extends TestObject {
+ public JUnitTestDiscoveryRunnableState(JUnitConfiguration configuration, ExecutionEnvironment environment) {
+ super(configuration, environment);
+ }
+
+ protected abstract String getChangeList();
+ protected abstract Pair<String, String> getPosition();
+
+
+ @Override
+ protected TestSearchScope getScope() {
+ return getConfiguration().getConfigurationModule().getModule() != null ? TestSearchScope.MODULE_WITH_DEPENDENCIES : TestSearchScope.WHOLE_PROJECT;
+ }
+
+ @Override
+ protected boolean forkPerModule() {
+ return getConfiguration().getConfigurationModule().getModule() == null;
+ }
+
+ @Override
+ protected PsiElement retrievePsiElement(Object pattern) {
+ if (pattern instanceof String) {
+ final String className = StringUtil.getPackageName((String)pattern, ',');
+ if (!pattern.equals(className)) {
+ final Project project = getConfiguration().getProject();
+ final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
+ final SourceScope sourceScope = getSourceScope();
+ final GlobalSearchScope globalSearchScope = sourceScope != null ? sourceScope.getGlobalSearchScope()
+ : GlobalSearchScope.projectScope(project);
+ return facade.findClass(className, globalSearchScope);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public SearchForTestsTask createSearchingForTestsTask() {
+ return new SearchForTestsTask(getConfiguration().getProject(), myServerSocket) {
+
+ private Set<String> myPatterns;
+
+ @Override
+ protected void search() throws ExecutionException {
+ myPatterns = TestDiscoverySearchHelper.search(getProject(), getPosition(), getChangeList(), getConfiguration().getFrameworkPrefix());
+ }
+
+ @Override
+ protected void onFound() {
+ if (myPatterns != null) {
+ try {
+ addClassesListToJavaParameters(myPatterns, FunctionUtil.<String>id(), "", false, getJavaParameters());
+ }
+ catch (ExecutionException ignored) {
+ }
+ }
+ }
+ };
+ }
+
+ @Override
+ protected JavaParameters createJavaParameters() throws ExecutionException {
+ final JavaParameters javaParameters = super.createJavaParameters();
+ createTempFiles(javaParameters);
+
+ createServerSocket(javaParameters);
+ return javaParameters;
+ }
+
+ @Override
+ public String suggestActionName() {
+ return "";
+ }
+
+ @Override
+ public RefactoringElementListener getListener(PsiElement element, JUnitConfiguration configuration) {
+ return null;
+ }
+
+ @Override
+ public boolean isConfiguredByElement(JUnitConfiguration configuration,
+ PsiClass testClass,
+ PsiMethod testMethod,
+ PsiPackage testPackage,
+ PsiDirectory testDir) {
+ return false;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2016 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.intellij.execution.junit.testDiscovery;
+
+import com.intellij.execution.junit.JUnitConfiguration;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.openapi.util.Pair;
+
+public class TestBySource extends JUnitTestDiscoveryRunnableState {
+ public TestBySource(JUnitConfiguration configuration,
+ ExecutionEnvironment environment) {
+ super(configuration, environment);
+ }
+
+ @Override
+ protected String getChangeList() {
+ return null;
+ }
+
+ @Override
+ protected Pair<String, String> getPosition() {
+ final JUnitConfiguration.Data data = getConfiguration().getPersistentData();
+ return Pair.create(data.getMainClassName(), data.getMethodName());
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2016 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.intellij.execution.junit.testDiscovery;
+
+import com.intellij.execution.junit.JUnitConfiguration;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.openapi.util.Pair;
+
+public class TestsByChanges extends JUnitTestDiscoveryRunnableState {
+ public TestsByChanges(JUnitConfiguration configuration, ExecutionEnvironment environment) {
+ super(configuration, environment);
+ }
+
+ @Override
+ protected String getChangeList() {
+ return getConfiguration().getPersistentData().getChangeList();
+ }
+
+ @Override
+ protected Pair<String, String> getPosition() {
+ return null;
+ }
+}
<grid id="ece1c" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <xy x="28" y="28" width="722" height="566"/>
+ <xy x="28" y="28" width="722" height="591"/>
</constraints>
<properties/>
<border type="none"/>
</constraints>
<properties/>
</component>
- <grid id="5947e" layout-manager="GridLayoutManager" row-count="7" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="5947e" layout-manager="GridLayoutManager" row-count="8" 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="2" vsize-policy="3" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
<children>
<component id="b109" class="com.intellij.openapi.ui.LabeledComponent" binding="myMethod" custom-create="true">
<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>
<enabled value="true"/>
<text value="Directory"/>
</properties>
</component>
+ <component id="9b01f" class="com.intellij.openapi.ui.LabeledComponent" binding="myChangeListLabeledComponent" default-binding="true">
+ <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"/>
+ </constraints>
+ <properties>
+ <componentClass value="javax.swing.JComboBox"/>
+ <labelLocation value="West"/>
+ <text value="Change list"/>
+ </properties>
+ </component>
<grid id="c9a5f" binding="myScopesPanel" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="7" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
import com.intellij.openapi.ui.ex.MessagesEx;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.vcs.changes.ChangeListManager;
+import com.intellij.openapi.vcs.changes.LocalChangeList;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
public class JUnitConfigurable<T extends JUnitConfiguration> extends SettingsEditor<T> implements PanelWithAnchor {
private static final List<TIntArrayList> ourEnabledFields = Arrays.asList(
new TIntArrayList(new int[]{1, 2}),
new TIntArrayList(new int[]{3}),
new TIntArrayList(new int[]{4}),
- new TIntArrayList(new int[]{5})
- );
+ new TIntArrayList(new int[]{5}),
+ new TIntArrayList(new int[]{1, 2}),
+ new TIntArrayList(new int[]{6})
+ );
private static final String[] FORK_MODE_ALL =
{JUnitConfiguration.FORK_NONE, JUnitConfiguration.FORK_METHOD, JUnitConfiguration.FORK_KLASS};
private static final String[] FORK_MODE = {JUnitConfiguration.FORK_NONE, JUnitConfiguration.FORK_METHOD};
private JPanel myScopesPanel;
private JComboBox myRepeatCb;
private JTextField myRepeatCountField;
+ private LabeledComponent<JComboBox<String>> myChangeListLabeledComponent;
private Project myProject;
private JComponent anchor;
aModel.addElement(JUnitConfigurationModel.CLASS);
aModel.addElement(JUnitConfigurationModel.METHOD);
aModel.addElement(JUnitConfigurationModel.CATEGORY);
+ if (Registry.is("testDiscovery.enabled")) {
+ aModel.addElement(JUnitConfigurationModel.BY_SOURCE_POSITION);
+ aModel.addElement(JUnitConfigurationModel.BY_SOURCE_CHANGES);
+ }
myTypeChooser.setModel(aModel);
myTypeChooser.setRenderer(new ListCellRendererWrapper<Integer>() {
@Override
case JUnitConfigurationModel.CATEGORY:
setText("Category");
break;
+ case JUnitConfigurationModel.BY_SOURCE_POSITION:
+ setText("Through source location");
+ break;
+ case JUnitConfigurationModel.BY_SOURCE_CHANGES:
+ setText("Over changes in sources");
+ break;
}
}
});
setAnchor(mySearchForTestsLabel);
myJrePathEditor.setAnchor(myModule.getLabel());
myCommonJavaParameters.setAnchor(myModule.getLabel());
+
+ final DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
+ myChangeListLabeledComponent.getComponent().setModel(model);
+ model.addElement("All");
+
+ final List<LocalChangeList> changeLists = ChangeListManager.getInstance(project).getChangeLists();
+ for (LocalChangeList changeList : changeLists) {
+ model.addElement(changeList.getName());
+ }
}
private static void addRadioButtonsListeners(final JRadioButton[] radioButtons, ChangeListener listener) {
public void applyEditorTo(final JUnitConfiguration configuration) {
myModel.apply(getModuleSelector().getModule(), configuration);
+ configuration.getPersistentData().setChangeList((String)myChangeListLabeledComponent.getComponent().getSelectedItem());
applyHelpersTo(configuration);
final JUnitConfiguration.Data data = configuration.getPersistentData();
if (myWholeProjectScope.isSelected()) {
myRepeatCb.setSelectedItem(configuration.getRepeatMode());
myModel.reset(configuration);
+ myChangeListLabeledComponent.getComponent().setSelectedItem(configuration.getPersistentData().getChangeList());
myCommonJavaParameters.reset(configuration);
getModuleSelector().reset(configuration);
final TestSearchScope scope = configuration.getPersistentData().getScope();
myCategory.setVisible(false);
myMethod.setVisible(false);
myDir.setVisible(false);
+ myChangeListLabeledComponent.setVisible(false);
myForkCb.setEnabled(true);
myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE_ALL));
myForkCb.setSelectedItem(selectedItem);
myPattern.setVisible(false);
myClass.setVisible(false);
myCategory.setVisible(false);
+ myChangeListLabeledComponent.setVisible(false);
myMethod.setVisible(false);
myForkCb.setEnabled(true);
myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE_ALL));
myDir.setVisible(false);
myClass.setVisible(true);
myCategory.setVisible(false);
+ myChangeListLabeledComponent.setVisible(false);
myMethod.setVisible(false);
myForkCb.setEnabled(true);
myForkCb.setModel(getForkModelBasedOnRepeat());
myForkCb.setSelectedItem(selectedItem != JUnitConfiguration.FORK_KLASS ? selectedItem : JUnitConfiguration.FORK_METHOD);
}
- else if (selectedType == JUnitConfigurationModel.METHOD){
+ else if (selectedType == JUnitConfigurationModel.METHOD || selectedType == JUnitConfigurationModel.BY_SOURCE_POSITION){
myPackagePanel.setVisible(false);
myScopesPanel.setVisible(false);
myPattern.setVisible(false);
myClass.setVisible(true);
myCategory.setVisible(false);
myMethod.setVisible(true);
+ myChangeListLabeledComponent.setVisible(false);
myForkCb.setEnabled(false);
myForkCb.setSelectedItem(JUnitConfiguration.FORK_NONE);
} else if (selectedType == JUnitConfigurationModel.CATEGORY) {
myClass.setVisible(false);
myCategory.setVisible(true);
myMethod.setVisible(false);
+ myChangeListLabeledComponent.setVisible(false);
+ myForkCb.setEnabled(true);
+ myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE_ALL));
+ myForkCb.setSelectedItem(selectedItem);
+ }
+ else if (selectedType == JUnitConfigurationModel.BY_SOURCE_CHANGES) {
+ myPackagePanel.setVisible(false);
+ myScopesPanel.setVisible(false);
+ myDir.setVisible(false);
+ myPattern.setVisible(false);
+ myClass.setVisible(false);
+ myCategory.setVisible(false);
+ myMethod.setVisible(false);
+ myChangeListLabeledComponent.setVisible(true);
myForkCb.setEnabled(true);
myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE_ALL));
myForkCb.setSelectedItem(selectedItem);
myClass.setVisible(false);
myCategory.setVisible(false);
myMethod.setVisible(true);
+ myChangeListLabeledComponent.setVisible(false);
myForkCb.setEnabled(true);
myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE_ALL));
myForkCb.setSelectedItem(selectedItem);
myPattern.setAnchor(anchor);
myPackage.setAnchor(anchor);
myCategory.setAnchor(anchor);
+ myChangeListLabeledComponent.setAnchor(anchor);
}
public void onTypeChanged(final int newType) {
public static final int PATTERN = 3;
public static final int DIR = 4;
public static final int CATEGORY = 5;
+ public static final int BY_SOURCE_POSITION = 6;
+ public static final int BY_SOURCE_CHANGES = 7;
private static final List<String> ourTestObjects;
JUnitConfiguration.TEST_METHOD,
JUnitConfiguration.TEST_PATTERN,
JUnitConfiguration.TEST_DIRECTORY,
- JUnitConfiguration.TEST_CATEGORY);
+ JUnitConfiguration.TEST_CATEGORY,
+ JUnitConfiguration.BY_SOURCE_POSITION,
+ JUnitConfiguration.BY_SOURCE_CHANGES);
}
if (testObject != JUnitConfiguration.TEST_PACKAGE &&
testObject != JUnitConfiguration.TEST_PATTERN &&
testObject != JUnitConfiguration.TEST_DIRECTORY &&
- testObject != JUnitConfiguration.TEST_CATEGORY) {
+ testObject != JUnitConfiguration.TEST_CATEGORY &&
+ testObject != JUnitConfiguration.BY_SOURCE_CHANGES) {
try {
data.METHOD_NAME = getJUnitTextValue(METHOD);
final PsiClass testClass = !myProject.isDefault() && !StringUtil.isEmptyOrSpaces(className) ? JUnitUtil.findPsiClass(className, module, myProject) : null;
data.MAIN_CLASS_NAME = className;
}
}
- else {
+ else if (testObject != JUnitConfiguration.BY_SOURCE_CHANGES) {
if (testObject == JUnitConfiguration.TEST_PACKAGE) {
data.PACKAGE_NAME = getJUnitTextValue(ALL_IN_PACKAGE);
}
<programRunner implementation="com.theoryinpractice.testng.configuration.TestNGDebuggerRunner"/>
<runConfigurationProducer
implementation="com.theoryinpractice.testng.configuration.testDiscovery.TestNGTestDiscoveryConfigurationProducer"/>
- <configurationType implementation="com.theoryinpractice.testng.configuration.testDiscovery.TestNGTestDiscoveryConfigurationType"/>
</extensions>
<extensions defaultExtensionNs="com.theoryinpractice.testng">
<listener implementation="org.testng.TestNGTestDiscoveryListener"/>
import com.intellij.refactoring.listeners.RefactoringElementAdapter;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.listeners.UndoRefactoringElementListener;
+import com.theoryinpractice.testng.configuration.testDiscovery.TestNGTestDiscoveryRunnableState;
import com.theoryinpractice.testng.model.TestData;
import com.theoryinpractice.testng.model.TestNGConsoleProperties;
import com.theoryinpractice.testng.model.TestNGTestObject;
}
public RunProfileState getState(@NotNull final Executor executor, @NotNull final ExecutionEnvironment env) throws ExecutionException {
+ final TestData data = getPersistantData();
+ if (data.TEST_OBJECT.equals(TestType.SOURCE.getType()) || data.getChangeList() != null) {
+ return new TestNGTestDiscoveryRunnableState(env, this);
+ }
return new TestNGRunnableState(env, this);
}
.collect(Collectors.toSet());
return groups.isEmpty() ? null : groups;
}
+
+ public void beFromSourcePosition(PsiLocation<PsiMethod> position) {
+ setMethodConfiguration(position);
+ getPersistantData().TEST_OBJECT = TestType.SOURCE.getType();
+ }
}
<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>
- <grid id="3054c" layout-manager="GridLayoutManager" row-count="1" column-count="7" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="3054c" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<properties/>
<border type="none"/>
<children>
- <component id="5eaf8" class="javax.swing.JRadioButton" binding="groupTest">
- <constraints>
- <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text value="&Group"/>
- </properties>
- </component>
- <component id="61e8b" class="javax.swing.JRadioButton" binding="classTest">
- <constraints>
- <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text value="C&lass"/>
- </properties>
- </component>
- <component id="2ab9d" class="javax.swing.JRadioButton" binding="methodTest">
- <constraints>
- <grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text value="&Method"/>
- </properties>
- </component>
- <component id="dcd9c" class="javax.swing.JRadioButton" binding="packageTest">
+ <hspacer id="99645">
<constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
- <properties>
- <text value="All in &package"/>
- </properties>
- </component>
- <component id="d8c06" class="javax.swing.JRadioButton" binding="suiteTest">
+ </hspacer>
+ <component id="fccce" class="javax.swing.JComboBox" binding="myTestKind">
<constraints>
- <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
- <properties>
- <text value="S&uite"/>
- </properties>
+ <properties/>
</component>
- <component id="99b4d" class="com.intellij.ui.components.JBRadioButton" binding="patternTest">
+ <component id="ec186" class="com.intellij.ui.components.JBLabel" binding="myTestLabel">
<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"/>
+ <grid row="0" column="0" 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"/>
+ <text value="Test kind:"/>
</properties>
</component>
- <hspacer id="99645">
- <constraints>
- <grid row="0" column="6" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- </hspacer>
</children>
</grid>
</children>
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.*;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.*;
+import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBList;
import com.intellij.ui.table.TableView;
import com.intellij.util.IconUtil;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Map;
public class TestNGConfigurationEditor<T extends TestNGConfiguration> extends SettingsEditor<T> implements PanelWithAnchor {
private LabeledComponent<ModulesComboBox> moduleClasspath;
private JrePathEditor alternateJDK;
private final ConfigurationModuleSelector moduleSelector;
- private JRadioButton suiteTest;
- private JRadioButton packageTest;
- private JRadioButton classTest;
- private JRadioButton methodTest;
- private JRadioButton groupTest;
- private JRadioButton patternTest;
+ private JComboBox<TestType> myTestKind;
+ private JBLabel myTestLabel;
private final TestNGConfigurationModel model;
private LabeledComponent<EditorTextFieldWithBrowseButton> methodField;
private LabeledComponent<EditorTextFieldWithBrowseButton> packageField;
});
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();
- if (buttonModel.isSelected()) {
- if (buttonModel == packageTest.getModel()) {
- model.setType(TestType.PACKAGE);
- }
- else if (buttonModel == classTest.getModel()) {
- model.setType(TestType.CLASS);
- }
- else if (buttonModel == methodTest.getModel()) {
- model.setType(TestType.METHOD);
- }
- else if (buttonModel == groupTest.getModel()) {
- model.setType(TestType.GROUP);
- }
- else if (buttonModel == suiteTest.getModel()) {
- model.setType(TestType.SUITE);
- }
- else if (buttonModel == patternTest.getModel()) {
- model.setType(TestType.PATTERN);
- }
- }
+ final CollectionComboBoxModel<TestType> testKindModel = new CollectionComboBoxModel<>(Arrays.asList(TestType.values()));
+ if (!Registry.is("testDiscovery.enabled")) {
+ testKindModel.remove(TestType.SOURCE);
+ }
+ myTestKind.setModel(testKindModel);
+ myTestKind.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ TestNGConfigurationEditor.this.model.setType((TestType)myTestKind.getSelectedItem());
}
});
+ myTestKind.setRenderer(new ListCellRendererWrapper<TestType>() {
+ @Override
+ public void customize(JList list, TestType value, int index, boolean selected, boolean hasFocus) {
+ if (value != null) {
+ setText(value.getPresentableName());
+ }
+ }
+ });
registerListener(new JRadioButton[]{packagesInProject, packagesInModule, packagesAcrossModules}, null);
packagesInProject.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
}
private void redisplay() {
- if (packageTest.isSelected()) {
+ final TestType testKind = (TestType)myTestKind.getSelectedItem();
+ if (testKind == TestType.PACKAGE) {
packagePanel.setVisible(true);
packageField.setVisible(true);
classField.setVisible(false);
suiteField.setVisible(false);
myPattern.setVisible(false);
}
- else if (classTest.isSelected()) {
+ else if (testKind == TestType.CLASS) {
packagePanel.setVisible(false);
classField.setVisible(true);
methodField.setVisible(false);
suiteField.setVisible(false);
myPattern.setVisible(false);
}
- else if (methodTest.isSelected()) {
+ else if (testKind == TestType.METHOD || testKind == TestType.SOURCE) {
packagePanel.setVisible(false);
classField.setVisible(true);
methodField.setVisible(true);
suiteField.setVisible(false);
myPattern.setVisible(false);
}
- else if (groupTest.isSelected()) {
+ else if (testKind == TestType.GROUP) {
packagePanel.setVisible(true);
classField.setVisible(false);
methodField.setVisible(false);
suiteField.setVisible(false);
myPattern.setVisible(false);
}
- else if (suiteTest.isSelected()) {
+ else if (testKind == TestType.SUITE) {
packagePanel.setVisible(true);
classField.setVisible(false);
methodField.setVisible(false);
suiteField.setVisible(true);
myPattern.setVisible(false);
}
- else if (patternTest.isSelected()) {
+ else if (testKind == TestType.PATTERN) {
packagePanel.setVisible(true);
classField.setVisible(false);
methodField.setVisible(false);
model.apply(getModuleSelector().getModule(), config);
getModuleSelector().applyTo(config);
TestData data = config.getPersistantData();
- if (!classTest.isSelected() && !methodTest.isSelected()) {
+ final TestType testKind = (TestType)myTestKind.getSelectedItem();
+ if (testKind != TestType.CLASS && testKind != TestType.METHOD && testKind != TestType.SOURCE) {
if (packagesInProject.isSelected()) {
data.setScope(TestSearchScope.WHOLE_PROJECT);
}
outputDirectory.setAnchor(anchor);
classField.setAnchor(anchor);
myPattern.setAnchor(anchor);
+ myTestLabel.setAnchor(anchor);
}
private static void registerListener(JRadioButton[] buttons, ChangeListener changelistener) {
private void createView() {
commonParametersPanel.add(commonJavaParameters, BorderLayout.CENTER);
-
- packageTest.setSelected(false);
- suiteTest.setSelected(false);
- suiteTest.setEnabled(true);
- groupTest.setSelected(false);
- 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
public Visibility isDeclarationVisible(PsiElement declaration, PsiElement place) {
public void onTypeChanged(TestType type) {
//LOGGER.info("onTypeChanged with " + type);
+ myTestKind.setSelectedItem(type);
if (type == TestType.PACKAGE) {
- packageTest.setSelected(true);
packageField.setEnabled(true);
classField.setEnabled(false);
methodField.setEnabled(false);
myPattern.setEnabled(false);
}
else if (type == TestType.CLASS) {
- classTest.setSelected(true);
packageField.setEnabled(false);
classField.setEnabled(true);
methodField.setEnabled(false);
suiteField.setEnabled(false);
myPattern.setEnabled(false);
}
- else if (type == TestType.METHOD) {
- methodTest.setSelected(true);
+ else if (type == TestType.METHOD || type == TestType.SOURCE) {
packageField.setEnabled(false);
classField.setEnabled(true);
methodField.setEnabled(true);
myPattern.setEnabled(false);
}
else if (type == TestType.GROUP) {
- groupTest.setSelected(true);
groupField.setEnabled(true);
packageField.setVisible(false);
classField.setEnabled(false);
myPattern.setEnabled(false);
}
else if (type == TestType.SUITE) {
- suiteTest.setSelected(true);
suiteField.setEnabled(true);
packageField.setVisible(false);
classField.setEnabled(false);
myPattern.setEnabled(false);
}
else if (type == TestType.PATTERN) {
- patternTest.setSelected(true);
myPattern.setEnabled(true);
suiteField.setEnabled(false);
packageField.setVisible(false);
import com.intellij.execution.JavaTestFrameworkDebuggerRunner;
import com.intellij.execution.configurations.RunProfile;
-import com.theoryinpractice.testng.configuration.testDiscovery.TestNGTestDiscoveryConfiguration;
import org.jetbrains.annotations.NotNull;
public class TestNGDebuggerRunner extends JavaTestFrameworkDebuggerRunner {
@Override
protected boolean validForProfile(@NotNull RunProfile profile) {
- return profile instanceof TestNGConfiguration ||
- profile instanceof TestNGTestDiscoveryConfiguration;
+ return profile instanceof TestNGConfiguration;
}
@NotNull
+++ /dev/null
-/*
- * 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.configuration.testDiscovery;
-
-import com.intellij.execution.CantRunException;
-import com.intellij.execution.ExecutionException;
-import com.intellij.execution.Executor;
-import com.intellij.execution.configurations.*;
-import com.intellij.execution.runners.ExecutionEnvironment;
-import com.intellij.execution.testDiscovery.TestDiscoveryConfiguration;
-import com.intellij.execution.testDiscovery.TestDiscoverySearchHelper;
-import com.intellij.execution.testframework.TestSearchScope;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.refactoring.listeners.RefactoringElementListener;
-import com.theoryinpractice.testng.configuration.SearchingForTestsTask;
-import com.theoryinpractice.testng.configuration.TestNGConfiguration;
-import com.theoryinpractice.testng.configuration.TestNGConfigurationType;
-import com.theoryinpractice.testng.configuration.TestNGRunnableState;
-import com.theoryinpractice.testng.model.TestNGTestPattern;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Set;
-
-public class TestNGTestDiscoveryConfiguration extends TestDiscoveryConfiguration {
-
- public TestNGTestDiscoveryConfiguration(String name, Project project, ConfigurationFactory factory) {
- super(name, new JavaRunConfigurationModule(project, false), factory,
- new TestNGConfiguration("", project, TestNGConfigurationType.getInstance().getConfigurationFactories()[0]));
- }
-
- @Nullable
- @Override
- public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment) throws ExecutionException {
- return new TestNGTestDiscoveryRunnableState(environment);
- }
-
- @Nullable
- @Override
- public RefactoringElementListener getRefactoringElementListener(PsiElement element) {
- return null;
- }
-
- @NotNull
- @Override
- public String getFrameworkPrefix() {
- return "g";
- }
-
- private class TestNGTestDiscoveryRunnableState extends TestNGRunnableState {
- public TestNGTestDiscoveryRunnableState(ExecutionEnvironment environment) {
- super(environment, ((TestNGConfiguration)myDelegate));
- }
-
- @Override
- protected TestSearchScope getScope() {
- return TestSearchScope.MODULE_WITH_DEPENDENCIES;
- }
-
- @Override
- protected boolean forkPerModule() {
- return spansMultipleModules("");
- }
-
- @Override
- public SearchingForTestsTask createSearchingForTestsTask() {
- return new SearchingForTestsTask(myServerSocket, getConfiguration(), myTempFile, client) {
- @Override
- protected void search() throws CantRunException {
- myClasses.clear();
- final Set<String> patterns = TestDiscoverySearchHelper.search(getProject(), getPosition(), getChangeList(), getFrameworkPrefix());
- final Module module = getConfigurationModule().getModule();
- final GlobalSearchScope searchScope =
- module != null ? GlobalSearchScope.moduleWithDependenciesScope(module) : GlobalSearchScope.projectScope(getProject());
- TestNGTestPattern.fillTestObjects(myClasses, patterns, TestSearchScope.MODULE_WITH_DEPENDENCIES,
- TestNGTestDiscoveryConfiguration.this, searchScope);
- }
-
- @Override
- protected void onFound() {
- super.onFound();
- writeClassesPerModule(myClasses);
- }
- };
- }
- }
-}
*/
package com.theoryinpractice.testng.configuration.testDiscovery;
+import com.intellij.execution.JavaTestConfigurationBase;
+import com.intellij.execution.PsiLocation;
import com.intellij.execution.configurations.ConfigurationTypeUtil;
import com.intellij.execution.testDiscovery.TestDiscoveryConfigurationProducer;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiMethod;
+import com.theoryinpractice.testng.configuration.TestNGConfiguration;
+import com.theoryinpractice.testng.configuration.TestNGConfigurationType;
+import com.theoryinpractice.testng.model.TestData;
+import com.theoryinpractice.testng.model.TestType;
public class TestNGTestDiscoveryConfigurationProducer extends TestDiscoveryConfigurationProducer {
protected TestNGTestDiscoveryConfigurationProducer() {
- super(ConfigurationTypeUtil.findConfigurationType(TestNGTestDiscoveryConfigurationType.class));
+ super(TestNGConfigurationType.getInstance());
+ }
+
+ @Override
+ protected void setPosition(JavaTestConfigurationBase configuration, PsiLocation<PsiMethod> position) {
+ ((TestNGConfiguration)configuration).beFromSourcePosition(position);
+ }
+
+ @Override
+ protected Pair<String, String> getPosition(JavaTestConfigurationBase configuration) {
+ final TestData data = ((TestNGConfiguration)configuration).getPersistantData();
+ if (data.TEST_OBJECT.equals(TestType.SOURCE.getType())) {
+ return Pair.create(data.getMainClassName(), data.getMethodName());
+ }
+ return null;
}
}
+++ /dev/null
-/*
- * 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.configuration.testDiscovery;
-
-import com.intellij.execution.configuration.ConfigurationFactoryEx;
-import com.intellij.execution.configurations.ConfigurationFactory;
-import com.intellij.execution.configurations.ConfigurationType;
-import com.intellij.execution.configurations.ModuleBasedConfiguration;
-import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.icons.AllIcons;
-import com.intellij.openapi.project.Project;
-import icons.TestngIcons;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-
-public class TestNGTestDiscoveryConfigurationType implements ConfigurationType {
- private final ConfigurationFactory myFactory;
-
- public TestNGTestDiscoveryConfigurationType() {
- myFactory = new ConfigurationFactoryEx(this) {
- public RunConfiguration createTemplateConfiguration(Project project) {
- return new TestNGTestDiscoveryConfiguration("", project, this);
- }
-
- @Override
- public void onNewConfigurationCreated(@NotNull RunConfiguration configuration) {
- ((ModuleBasedConfiguration)configuration).onNewConfigurationCreated();
- }
- };
- }
-
- @Override
- public String getDisplayName() {
- return "TestNG Test Discovery";
- }
-
- @Override
- public String getConfigurationTypeDescription() {
- return "Runs TestNG tests which passed changed code";
- }
-
- @Override
- public Icon getIcon() {
- return TestngIcons.TestNG;
- }
-
- @NotNull
- @Override
- public String getId() {
- return "TestNGTestDiscovery";
- }
-
- @Override
- public ConfigurationFactory[] getConfigurationFactories() {
- return new ConfigurationFactory[] {myFactory};
- }
-}
--- /dev/null
+/*
+ * Copyright 2000-2016 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.configuration.testDiscovery;
+
+import com.intellij.execution.CantRunException;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.execution.testDiscovery.TestDiscoverySearchHelper;
+import com.intellij.execution.testframework.TestSearchScope;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.theoryinpractice.testng.configuration.SearchingForTestsTask;
+import com.theoryinpractice.testng.configuration.TestNGConfiguration;
+import com.theoryinpractice.testng.configuration.TestNGRunnableState;
+import com.theoryinpractice.testng.model.TestData;
+import com.theoryinpractice.testng.model.TestNGTestPattern;
+import com.theoryinpractice.testng.model.TestType;
+
+import java.util.Set;
+
+public class TestNGTestDiscoveryRunnableState extends TestNGRunnableState {
+
+ public TestNGTestDiscoveryRunnableState(ExecutionEnvironment environment,
+ TestNGConfiguration configuration) {
+ super(environment, configuration);
+ }
+
+ @Override
+ protected TestSearchScope getScope() {
+ return TestSearchScope.MODULE_WITH_DEPENDENCIES;
+ }
+
+ @Override
+ protected boolean forkPerModule() {
+ return getConfiguration().getConfigurationModule().getModule() == null;
+ }
+
+ @Override
+ public SearchingForTestsTask createSearchingForTestsTask() {
+ return new SearchingForTestsTask(myServerSocket, getConfiguration(), myTempFile, client) {
+ @Override
+ protected void search() throws CantRunException {
+ myClasses.clear();
+ final TestData data = getConfiguration().getPersistantData();
+ final Pair<String, String> position = data.TEST_OBJECT.equals(TestType.SOURCE.getType())
+ ? Pair.create(data.getMainClassName(), data.getMethodName()) : null;
+ final Set<String> patterns = TestDiscoverySearchHelper
+ .search(getProject(), position, data.getChangeList(), getConfiguration().getFrameworkPrefix());
+ final Module module = getConfiguration().getConfigurationModule().getModule();
+ final GlobalSearchScope searchScope =
+ module != null ? GlobalSearchScope.moduleWithDependenciesScope(module) : GlobalSearchScope.projectScope(getProject());
+ TestNGTestPattern.fillTestObjects(myClasses, patterns, TestSearchScope.MODULE_WITH_DEPENDENCIES,
+ getConfiguration(), searchScope);
+ }
+
+ @Override
+ protected void onFound() {
+ super.onFound();
+ writeClassesPerModule(myClasses);
+ }
+ };
+ }
+}
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiPackage;
public boolean USE_DEFAULT_REPORTERS = false;
public String PROPERTIES_FILE;
private LinkedHashSet<String> myPatterns = new LinkedHashSet<String>();
+ private String myChangeList;
public TestData() {
TEST_OBJECT = TestType.CLASS.getType();
public void setPatterns(LinkedHashSet<String> set) {
myPatterns = set;
}
+
+ public String getChangeList() {
+ return myChangeList;
+ }
+
+ public void setChangeList(String changeList) {
+ myChangeList = changeList;
+ }
}
private final Project project;
public TestNGConfigurationModel(Project project) {
- type = TestType.INVALID;
+ type = TestType.CLASS;
for (int i = 3; i < typeDocuments.length; i++)
typeDocuments[i] = new PlainDocument();
--- /dev/null
+/*
+ * Copyright 2000-2016 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.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+import com.theoryinpractice.testng.configuration.TestNGConfiguration;
+
+import java.util.List;
+import java.util.Map;
+
+public class TestNGSource extends TestNGTestMethod {
+ public TestNGSource(TestNGConfiguration config) {
+ super(config);
+ }
+
+ @Override
+ public void fillTestObjects(Map<PsiClass, Map<PsiMethod, List<String>>> classes) throws CantRunException {}
+
+ @Override
+ public String getGeneratedName() {
+ final TestData data = myConfig.getPersistantData();
+ return "Tests for " + StringUtil.getQualifiedName(data.getMainClassName(), data.getMethodName());
+ }
+
+ @Override
+ public String getActionName() {
+ return getGeneratedName();
+ }
+
+ @Override
+ public void checkConfiguration() throws RuntimeConfigurationException {
+ super.checkConfiguration();
+ }
+}
if (testObject.equals(TestType.SUITE.getType())){
return new TestNGTestSuite(config);
}
+
+ if (testObject.equals(TestType.SOURCE.getType())) {
+ return new TestNGSource(config);
+ }
assert false : testObject;
return null;
}
*/
package com.theoryinpractice.testng.model;
-public class TestType
+public enum TestType
{
- public static final TestType INVALID = new TestType("INVALID", -1);
- public static final TestType PACKAGE = new TestType("PACKAGE", 0);
- public static final TestType CLASS = new TestType("CLASS", 1);
- 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);
+
+ PACKAGE("PACKAGE", "All in package", 0),
+ CLASS ("CLASS", "Class", 1),
+ METHOD ("METHOD", "Method", 2),
+ GROUP ("GROUP", "Group", 3),
+ SUITE ("SUITE", "Suite", 4),
+ PATTERN("PATTERN", "Pattern", 5),
+ SOURCE ("SOURCE", "Source location", 6);
public final String type;
+ private final String presentableName;
public final int value;
- private TestType(String type, int value) {
+ TestType(String type, String presentableName, int value) {
this.type = type;
+ this.presentableName = presentableName;
this.value = value;
}
public int getValue() {
return value;
}
-
- public static TestType valueOf(String type)
- {
- if(INVALID.type.equals(type))
- {
- return INVALID;
- }
- if(PACKAGE.type.equals(type))
- {
- return PACKAGE;
- }
- if(CLASS.type.equals(type))
- {
- return CLASS;
- }
- if(METHOD.type.equals(type))
- {
- return METHOD;
- }
- if(GROUP.type.equals(type))
- {
- return GROUP;
- }
- if(SUITE.type.equals(type))
- {
- return SUITE;
- }
- if (PATTERN.type.equals(type)) {
- return PATTERN;
- }
- throw new IllegalArgumentException("Invalid type requested " + type);
+
+ public String getPresentableName() {
+ return presentableName;
}
}
\ No newline at end of file
<applicationService serviceInterface="com.intellij.codeInsight.TestFrameworks"
serviceImplementation="com.intellij.codeInsight.TestFrameworksImpl"/>
+ <projectService serviceInterface="com.intellij.execution.testDiscovery.JavaAutoRunManager"
+ serviceImplementation="com.intellij.execution.testDiscovery.JavaAutoRunManager"/>
+
<projectService serviceInterface="com.intellij.ide.util.TreeClassChooserFactory"
serviceImplementation="com.intellij.ide.util.TreeClassChooserFactoryImpl"/>
<projectService serviceInterface="com.intellij.psi.JavaPsiFacade"
<action id="ShowRecentTests" class="com.intellij.testIntegration.ShowRecentTests">
<keyboard-shortcut first-keystroke="control shift SEMICOLON" keymap="$default"/>
</action>
+ <action class="com.intellij.execution.testDiscovery.ConfigureTestDiscoveryAction" id="TestDiscoveryIndexChooser" text="Choose external test discovery indices">
+ <add-to-group group-id="Internal" anchor="last"/>
+ </action>
</actions>
</idea-plugin>