summaryrefslogtreecommitdiff
path: root/platform/testRunner/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'platform/testRunner/src/com')
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java12
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/Filter.java10
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java9
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/TestTreeViewAction.java19
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/TestTreeViewActionsPromoter.java38
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java6
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/actions/AbstractRerunFailedTestsAction.java170
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/actions/RerunFailedTestsAction.java12
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/actions/ViewAssertEqualsDiffAction.java69
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/stacktrace/DiffHyperlink.java88
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/ui/TestResultsPanel.java10
11 files changed, 322 insertions, 121 deletions
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java b/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java
index 73ecdb2ddd8c..7b84c66ae2ac 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/AbstractTestProxy.java
@@ -143,4 +143,16 @@ public abstract class AbstractTestProxy extends CompositePrintable {
String getExpected();
String getActual();
}
+
+ public interface AssertEqualsDiffChain {
+ AssertEqualsMultiDiffViewProvider getPrevious();
+ AssertEqualsMultiDiffViewProvider getCurrent();
+ AssertEqualsMultiDiffViewProvider getNext();
+ void setCurrent(AssertEqualsMultiDiffViewProvider provider);
+ }
+
+ public interface AssertEqualsMultiDiffViewProvider extends AssertEqualsDiffViewerProvider {
+ void openMultiDiff(Project project, AssertEqualsDiffChain chain);
+ String getFilePath();
+ }
}
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/Filter.java b/platform/testRunner/src/com/intellij/execution/testframework/Filter.java
index 7d43fcd2a7e1..8dd6363c5940 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/Filter.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/Filter.java
@@ -61,42 +61,49 @@ public abstract class Filter<T extends AbstractTestProxy> {
}
public static final Filter NO_FILTER = new Filter() {
+ @Override
public boolean shouldAccept(final AbstractTestProxy test) {
return true;
}
};
public static final Filter DEFECT = new Filter() {
+ @Override
public boolean shouldAccept(final AbstractTestProxy test) {
return test.isDefect();
}
};
public static final Filter IGNORED = new Filter() {
+ @Override
public boolean shouldAccept(final AbstractTestProxy test) {
return test.isIgnored();
}
};
public static final Filter NOT_PASSED = new Filter() {
+ @Override
public boolean shouldAccept(final AbstractTestProxy test) {
return !test.isPassed();
}
};
public static final Filter PASSED = new Filter() {
+ @Override
public boolean shouldAccept(final AbstractTestProxy test) {
return test.isPassed();
}
};
public static final Filter FAILED_OR_INTERRUPTED = new Filter() {
+ @Override
public boolean shouldAccept(final AbstractTestProxy test) {
return test.isInterrupted() || test.isDefect();
}
};
public static final Filter LEAF = new Filter() {
+ @Override
public boolean shouldAccept(final AbstractTestProxy test) {
return test.isLeaf();
}
@@ -122,6 +129,7 @@ public abstract class Filter<T extends AbstractTestProxy> {
myFilter2 = filter2;
}
+ @Override
public boolean shouldAccept(final AbstractTestProxy test) {
return myFilter1.shouldAccept(test) && myFilter2.shouldAccept(test);
}
@@ -134,6 +142,7 @@ public abstract class Filter<T extends AbstractTestProxy> {
myFilter = filter;
}
+ @Override
public boolean shouldAccept(final AbstractTestProxy test) {
return !myFilter.shouldAccept(test);
}
@@ -148,6 +157,7 @@ public abstract class Filter<T extends AbstractTestProxy> {
myFilter2 = filter2;
}
+ @Override
public boolean shouldAccept(final AbstractTestProxy test) {
return myFilter1.shouldAccept(test) || myFilter2.shouldAccept(test);
}
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java
index 839568b4c2a9..5d1d2b346a85 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java
@@ -46,6 +46,8 @@ import java.util.ArrayList;
import java.util.List;
public abstract class TestTreeView extends Tree implements DataProvider, CopyProvider {
+ public static final DataKey<TestFrameworkRunningModel> MODEL_DATA_KEY = DataKey.create("testFrameworkModel.dataId");
+
private TestFrameworkRunningModel myModel;
protected abstract TreeCellRenderer getRenderer(TestConsoleProperties properties);
@@ -127,7 +129,11 @@ public abstract class TestTreeView extends Tree implements DataProvider, CopyPro
return locations.isEmpty() ? null : locations.toArray(new Location[locations.size()]);
}
}
-
+
+ if (MODEL_DATA_KEY.is(dataId)) {
+ return myModel;
+ }
+
final TreePath selectionPath = getSelectionPath();
if (selectionPath == null) return null;
final AbstractTestProxy testProxy = getSelectedTest(selectionPath);
@@ -162,7 +168,6 @@ public abstract class TestTreeView extends Tree implements DataProvider, CopyPro
});
TreeUtil.installActions(this);
PopupHandler.installPopupHandler(this, IdeActions.GROUP_TESTTREE_POPUP, ActionPlaces.TESTTREE_VIEW_POPUP);
- ViewAssertEqualsDiffAction.registerShortcut(this);
}
@JdkConstants.TreeSelectionMode
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeViewAction.java b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeViewAction.java
new file mode 100644
index 000000000000..8a700d1b5dbd
--- /dev/null
+++ b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeViewAction.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2000-2014 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;
+
+public interface TestTreeViewAction {
+}
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeViewActionsPromoter.java b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeViewActionsPromoter.java
new file mode 100644
index 000000000000..445c33c682be
--- /dev/null
+++ b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeViewActionsPromoter.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2014 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;
+
+import com.intellij.openapi.actionSystem.ActionPromoter;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.DataContext;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class TestTreeViewActionsPromoter implements ActionPromoter {
+ @Override
+ public List<AnAction> promote(List<AnAction> actions, DataContext context) {
+ if (AbstractTestProxy.DATA_KEY.getData(context) != null) {
+ for (AnAction action : actions) {
+ if (action instanceof TestTreeViewAction) {
+ return Arrays.asList(action);
+ }
+ }
+ }
+ return Collections.emptyList();
+ }
+}
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java b/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java
index 836635a58b0e..cbb0373f34c1 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java
@@ -86,7 +86,7 @@ public class TestsUIUtil {
}
return false;
}
-
+
public static Navigatable getOpenFileDescriptor(final AbstractTestProxy testProxy, final TestFrameworkRunningModel model) {
final TestConsoleProperties testConsoleProperties = model.getProperties();
return getOpenFileDescriptor(testProxy, testConsoleProperties,
@@ -114,7 +114,7 @@ public class TestsUIUtil {
public static void notifyByBalloon(@NotNull final Project project,
boolean started,
final AbstractTestProxy root,
- final TestConsoleProperties properties,
+ final TestConsoleProperties properties,
@Nullable final String comment) {
if (project.isDisposed()) return;
if (properties == null) return;
@@ -231,7 +231,7 @@ public class TestsUIUtil {
myType = MessageType.ERROR;
}
else if (notStartedCount > 0) {
- myTitle = !notStarted.isEmpty() ? ExecutionBundle.message("junit.runing.info.failed.to.start.error.message") : "Tests Ignored";
+ myTitle = !notStarted.isEmpty() ? ExecutionBundle.message("junit.running.info.failed.to.start.error.message") : "Tests Ignored";
myText = passedCount + " passed, " + notStartedCount + (!notStarted.isEmpty() ? " not started" : " ignored");
myType = notStarted.isEmpty() ? MessageType.WARNING : MessageType.ERROR;
}
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/actions/AbstractRerunFailedTestsAction.java b/platform/testRunner/src/com/intellij/execution/testframework/actions/AbstractRerunFailedTestsAction.java
index 30f8599e2aaf..a7d036b33ef7 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/actions/AbstractRerunFailedTestsAction.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/actions/AbstractRerunFailedTestsAction.java
@@ -34,20 +34,20 @@ import com.intellij.execution.testframework.Filter;
import com.intellij.execution.testframework.TestConsoleProperties;
import com.intellij.execution.testframework.TestFrameworkRunningModel;
import com.intellij.idea.ActionsBundle;
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComponentContainer;
import com.intellij.openapi.ui.popup.JBPopupFactory;
-import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.components.JBList;
-import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
@@ -57,40 +57,24 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.List;
-public class AbstractRerunFailedTestsAction extends AnAction implements AnAction.TransparentUpdate, Disposable {
- private static final List<AbstractRerunFailedTestsAction> registry = ContainerUtil.createLockFreeCopyOnWriteList();
- private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit2.ui.actions.RerunFailedTestsAction");
+public class AbstractRerunFailedTestsAction extends AnAction implements AnAction.TransparentUpdate {
+ private static final Logger LOG = Logger.getInstance(AbstractRerunFailedTestsAction.class);
+
private TestFrameworkRunningModel myModel;
private Getter<TestFrameworkRunningModel> myModelProvider;
protected TestConsoleProperties myConsoleProperties;
- protected ExecutionEnvironment myEnvironment;
- private final JComponent myParent;
-
- @SuppressWarnings("UnusedDeclaration")
- public AbstractRerunFailedTestsAction() {
- //We call this constructor with a little help from reflection.
- myParent = null;
- }
protected AbstractRerunFailedTestsAction(@NotNull ComponentContainer componentContainer) {
- myParent = componentContainer.getComponent();
- registry.add(this);
- Disposer.register(componentContainer, this);
copyFrom(ActionManager.getInstance().getAction("RerunFailedTests"));
- registerCustomShortcutSet(getShortcutSet(), myParent);
+ registerCustomShortcutSet(getShortcutSet(), componentContainer.getComponent());
}
- @Override
- public void dispose() {
- registry.remove(this);
- }
-
- public void init(final TestConsoleProperties consoleProperties,
- final ExecutionEnvironment environment) {
- myEnvironment = environment;
+ public void init(TestConsoleProperties consoleProperties) {
myConsoleProperties = consoleProperties;
}
@@ -102,48 +86,27 @@ public class AbstractRerunFailedTestsAction extends AnAction implements AnAction
myModelProvider = modelProvider;
}
- @NotNull
- private AbstractRerunFailedTestsAction findActualAction() {
- if (myParent != null || registry.isEmpty())
- return this;
- List<AbstractRerunFailedTestsAction> candidates = new ArrayList<AbstractRerunFailedTestsAction>(registry);
- Collections.sort(candidates, new Comparator<AbstractRerunFailedTestsAction>() {
- @Override
- public int compare(AbstractRerunFailedTestsAction action1, AbstractRerunFailedTestsAction action2) {
- Window window1 = SwingUtilities.windowForComponent(action1.myParent);
- Window window2 = SwingUtilities.windowForComponent(action2.myParent);
- if (window1 == null)
- return 1;
- if (window2 == null)
- return -1;
- boolean showing1 = action1.myParent.isShowing();
- boolean showing2 = action2.myParent.isShowing();
- if (showing1 && !showing2)
- return -1;
- if (showing2 && !showing1)
- return 1;
- return (window1.isActive() ? -1 : 1);
- }
- });
- return candidates.get(0);
- }
-
@Override
- public final void update(AnActionEvent e) {
- AbstractRerunFailedTestsAction action = findActualAction();
- e.getPresentation().setEnabled(action.isActive(e));
+ public final void update(@NotNull AnActionEvent e) {
+ e.getPresentation().setEnabled(isActive(e));
}
private boolean isActive(AnActionEvent e) {
- DataContext dataContext = e.getDataContext();
- Project project = CommonDataKeys.PROJECT.getData(dataContext);
- if (project == null) return false;
+ Project project = e.getProject();
+ if (project == null) {
+ return false;
+ }
+
TestFrameworkRunningModel model = getModel();
- if (model == null || model.getRoot() == null) return false;
- final List<? extends AbstractTestProxy> myAllTests = model.getRoot().getAllTests();
- final Filter filter = getFailuresFilter();
- for (Object test : myAllTests) {
- if (filter.shouldAccept((AbstractTestProxy)test)) return true;
+ if (model == null || model.getRoot() == null) {
+ return false;
+ }
+ Filter filter = getFailuresFilter();
+ for (AbstractTestProxy test : model.getRoot().getAllTests()) {
+ //noinspection unchecked
+ if (filter.shouldAccept(test)) {
+ return true;
+ }
}
return false;
}
@@ -151,10 +114,10 @@ public class AbstractRerunFailedTestsAction extends AnAction implements AnAction
@NotNull
protected List<AbstractTestProxy> getFailedTests(Project project) {
TestFrameworkRunningModel model = getModel();
- final List<? extends AbstractTestProxy> myAllTests = model != null
- ? model.getRoot().getAllTests()
- : Collections.<AbstractTestProxy>emptyList();
- return getFilter(project, model != null ? model.getProperties().getScope() : GlobalSearchScope.allScope(project)).select(myAllTests);
+ //noinspection unchecked
+ return getFilter(project, model != null ? model.getProperties().getScope() : GlobalSearchScope.allScope(project)).select(model != null
+ ? model.getRoot().getAllTests()
+ : Collections.<AbstractTestProxy>emptyList());
}
@NotNull
@@ -162,7 +125,7 @@ public class AbstractRerunFailedTestsAction extends AnAction implements AnAction
return getFailuresFilter();
}
- protected Filter getFailuresFilter() {
+ protected Filter<?> getFailuresFilter() {
if (TestConsoleProperties.INCLUDE_NON_STARTED_IN_RERUN_FAILED.value(myConsoleProperties)) {
return Filter.NOT_PASSED.and(Filter.IGNORED.not()).or(Filter.FAILED_OR_INTERRUPTED);
}
@@ -170,30 +133,27 @@ public class AbstractRerunFailedTestsAction extends AnAction implements AnAction
}
@Override
- public void actionPerformed(AnActionEvent e) {
- findActualAction().showPopup(e);
- }
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ ExecutionEnvironment environment = e.getData(LangDataKeys.EXECUTION_ENVIRONMENT);
+ if (environment == null) {
+ return;
+ }
- private void showPopup(AnActionEvent e) {
- boolean isDebug = myConsoleProperties.isDebug();
- final MyRunProfile profile = getRunProfile();
+ MyRunProfile profile = getRunProfile(environment);
if (profile == null) {
return;
}
- final Executor executor = isDebug ? DefaultDebugExecutor.getDebugExecutorInstance() : DefaultRunExecutor.getRunExecutorInstance();
+ final ExecutionEnvironmentBuilder environmentBuilder = new ExecutionEnvironmentBuilder(environment).runProfile(profile);
final InputEvent event = e.getInputEvent();
if (!(event instanceof MouseEvent) || !event.isShiftDown()) {
- final ProgramRunner runner = RunnerRegistry.getInstance().getRunner(executor.getId(), profile);
- LOG.assertTrue(runner != null);
- performAction(runner, profile, myEnvironment.getExecutor());
+ performAction(environmentBuilder);
return;
}
final LinkedHashMap<Executor, ProgramRunner> availableRunners = new LinkedHashMap<Executor, ProgramRunner>();
- final Executor[] executors = new Executor[] {DefaultRunExecutor.getRunExecutorInstance(), DefaultDebugExecutor.getDebugExecutorInstance()};
- for (Executor ex : executors) {
+ for (Executor ex : new Executor[] {DefaultRunExecutor.getRunExecutorInstance(), DefaultDebugExecutor.getDebugExecutorInstance()}) {
final ProgramRunner runner = RunnerRegistry.getInstance().getRunner(ex.getId(), profile);
if (runner != null) {
availableRunners.put(ex, runner);
@@ -201,19 +161,20 @@ public class AbstractRerunFailedTestsAction extends AnAction implements AnAction
}
if (availableRunners.isEmpty()) {
- LOG.error(executor.getActionName() + " is not available now");
- return;
+ LOG.error(environment.getExecutor().getActionName() + " is not available now");
}
-
- if (availableRunners.size() == 1) {
- performAction(availableRunners.get(executor), profile, executor);
- } else {
+ else if (availableRunners.size() == 1) {
+ //noinspection ConstantConditions
+ performAction(environmentBuilder.runner(availableRunners.get(environment.getExecutor())));
+ }
+ else {
final JBList list = new JBList(availableRunners.keySet());
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
- list.setSelectedValue(executor, true);
+ list.setSelectedValue(environment.getExecutor(), true);
list.setCellRenderer(new DefaultListCellRenderer() {
+ @NotNull
@Override
- public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ public Component getListCellRendererComponent(@NotNull JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
final Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof Executor) {
setText(UIUtil.removeMnemonic(((Executor)value).getStartActionText()));
@@ -222,6 +183,7 @@ public class AbstractRerunFailedTestsAction extends AnAction implements AnAction
return component;
}
});
+ //noinspection ConstantConditions
JBPopupFactory.getInstance().createListPopupBuilder(list)
.setTitle("Restart Failed Tests")
.setMovable(false)
@@ -232,35 +194,39 @@ public class AbstractRerunFailedTestsAction extends AnAction implements AnAction
public void run() {
final Object value = list.getSelectedValue();
if (value instanceof Executor) {
- performAction(availableRunners.get(value), profile, (Executor)value);
+ //noinspection ConstantConditions
+ performAction(environmentBuilder.runner(availableRunners.get(value)).executor((Executor)value));
}
}
}).createPopup().showUnderneathOf(event.getComponent());
}
}
- private void performAction(ProgramRunner runner, MyRunProfile profile, Executor executor) {
+ private static void performAction(@NotNull ExecutionEnvironmentBuilder builder) {
+ ExecutionEnvironment environment = builder.build();
try {
- new ExecutionEnvironmentBuilder(myEnvironment)
- .runner(runner)
- .executor(executor)
- .runProfile(profile)
- .buildAndExecute();
+ environment.getRunner().execute(environment);
}
- catch (ExecutionException e1) {
- LOG.error(e1);
+ catch (ExecutionException e) {
+ LOG.error(e);
}
finally {
- profile.clear();
+ ((MyRunProfile)environment.getRunProfile()).clear();
}
}
- @Nullable
+ @Deprecated
public MyRunProfile getRunProfile() {
return null;
}
@Nullable
+ protected MyRunProfile getRunProfile(@NotNull ExecutionEnvironment environment) {
+ //noinspection deprecation
+ return getRunProfile();
+ }
+
+ @Nullable
public TestFrameworkRunningModel getModel() {
if (myModel != null) {
return myModel;
@@ -293,7 +259,6 @@ public class AbstractRerunFailedTestsAction extends AnAction implements AnAction
public void clear() {
}
-
@Override
public void checkConfiguration() throws RuntimeConfigurationException {
}
@@ -351,6 +316,7 @@ public class AbstractRerunFailedTestsAction extends AnAction implements AnAction
return myConfiguration.getPredefinedLogFiles();
}
+ @NotNull
@Override
public ArrayList<LogFileOptions> getAllLogFiles() {
return myConfiguration.getAllLogFiles();
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/actions/RerunFailedTestsAction.java b/platform/testRunner/src/com/intellij/execution/testframework/actions/RerunFailedTestsAction.java
new file mode 100644
index 000000000000..af15e3c14ce1
--- /dev/null
+++ b/platform/testRunner/src/com/intellij/execution/testframework/actions/RerunFailedTestsAction.java
@@ -0,0 +1,12 @@
+package com.intellij.execution.testframework.actions;
+
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import org.jetbrains.annotations.NotNull;
+
+class RerunFailedTestsAction extends AnAction {
+ @Override
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ throw new IllegalStateException("Action only as template");
+ }
+}
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/actions/ViewAssertEqualsDiffAction.java b/platform/testRunner/src/com/intellij/execution/testframework/actions/ViewAssertEqualsDiffAction.java
index fd80ea0154db..5d19c5ee0877 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/actions/ViewAssertEqualsDiffAction.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/actions/ViewAssertEqualsDiffAction.java
@@ -16,13 +16,15 @@
package com.intellij.execution.testframework.actions;
-import com.intellij.execution.testframework.AbstractTestProxy;
+import com.intellij.execution.testframework.*;
import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NonNls;
-import javax.swing.*;
+import java.util.ArrayList;
+import java.util.List;
-public class ViewAssertEqualsDiffAction extends AnAction {
+public class ViewAssertEqualsDiffAction extends AnAction implements TestTreeViewAction {
@NonNls public static final String ACTION_ID = "openAssertEqualsDiff";
public void actionPerformed(final AnActionEvent e) {
@@ -30,11 +32,35 @@ public class ViewAssertEqualsDiffAction extends AnAction {
if (testProxy != null) {
final AbstractTestProxy.AssertEqualsDiffViewerProvider diffViewerProvider = testProxy.getDiffViewerProvider();
if (diffViewerProvider != null) {
- diffViewerProvider.openDiff(CommonDataKeys.PROJECT.getData(e.getDataContext()));
+ final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
+ if (diffViewerProvider instanceof AbstractTestProxy.AssertEqualsMultiDiffViewProvider) {
+ final TestFrameworkRunningModel runningModel = TestTreeView.MODEL_DATA_KEY.getData(e.getDataContext());
+ final List<AbstractTestProxy.AssertEqualsMultiDiffViewProvider> providers = collectAvailableProviders(runningModel);
+ final MyAssertEqualsDiffChain diffChain =
+ providers.size() > 1 ? new MyAssertEqualsDiffChain(providers, (AbstractTestProxy.AssertEqualsMultiDiffViewProvider)diffViewerProvider) : null;
+ ((AbstractTestProxy.AssertEqualsMultiDiffViewProvider)diffViewerProvider).openMultiDiff(project, diffChain);
+ } else {
+ diffViewerProvider.openDiff(project);
+ }
}
}
}
+ private static List<AbstractTestProxy.AssertEqualsMultiDiffViewProvider> collectAvailableProviders(TestFrameworkRunningModel model) {
+ final List<AbstractTestProxy.AssertEqualsMultiDiffViewProvider> providers = new ArrayList<AbstractTestProxy.AssertEqualsMultiDiffViewProvider>();
+ if (model != null) {
+ final AbstractTestProxy root = model.getRoot();
+ final List<? extends AbstractTestProxy> allTests = root.getAllTests();
+ for (AbstractTestProxy test : allTests) {
+ final AbstractTestProxy.AssertEqualsDiffViewerProvider provider = test.getDiffViewerProvider();
+ if (provider instanceof AbstractTestProxy.AssertEqualsMultiDiffViewProvider) {
+ providers.add((AbstractTestProxy.AssertEqualsMultiDiffViewProvider)provider);
+ }
+ }
+ }
+ return providers;
+ }
+
public void update(final AnActionEvent e) {
final Presentation presentation = e.getPresentation();
final boolean enabled;
@@ -55,7 +81,38 @@ public class ViewAssertEqualsDiffAction extends AnAction {
presentation.setVisible(enabled);
}
- public static void registerShortcut(final JComponent component) {
- ActionManager.getInstance().getAction(ACTION_ID).registerCustomShortcutSet(CommonShortcuts.ALT_ENTER, component);
+ private static class MyAssertEqualsDiffChain implements AbstractTestProxy.AssertEqualsDiffChain {
+
+
+ private final List<AbstractTestProxy.AssertEqualsMultiDiffViewProvider> myProviders;
+ private AbstractTestProxy.AssertEqualsMultiDiffViewProvider myProvider;
+
+ public MyAssertEqualsDiffChain(List<AbstractTestProxy.AssertEqualsMultiDiffViewProvider> providers,
+ AbstractTestProxy.AssertEqualsMultiDiffViewProvider provider) {
+ myProviders = providers;
+ myProvider = provider;
+ }
+
+ @Override
+ public AbstractTestProxy.AssertEqualsMultiDiffViewProvider getPrevious() {
+ final int prevIdx = (myProviders.size() + myProviders.indexOf(myProvider) - 1) % myProviders.size();
+ return myProviders.get(prevIdx);
+ }
+
+ @Override
+ public AbstractTestProxy.AssertEqualsMultiDiffViewProvider getCurrent() {
+ return myProvider;
+ }
+
+ @Override
+ public AbstractTestProxy.AssertEqualsMultiDiffViewProvider getNext() {
+ final int nextIdx = (myProviders.indexOf(myProvider) + 1) % myProviders.size();
+ return myProviders.get(nextIdx);
+ }
+
+ @Override
+ public void setCurrent(AbstractTestProxy.AssertEqualsMultiDiffViewProvider provider) {
+ myProvider = provider;
+ }
}
}
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/stacktrace/DiffHyperlink.java b/platform/testRunner/src/com/intellij/execution/testframework/stacktrace/DiffHyperlink.java
index b60770692d9b..f8ff62996eca 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/stacktrace/DiffHyperlink.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/stacktrace/DiffHyperlink.java
@@ -22,14 +22,20 @@ package com.intellij.execution.testframework.stacktrace;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.filters.HyperlinkInfo;
+import com.intellij.execution.testframework.AbstractTestProxy;
import com.intellij.execution.testframework.Printable;
import com.intellij.execution.testframework.Printer;
import com.intellij.execution.ui.ConsoleViewContentType;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.diff.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
import java.io.File;
public class DiffHyperlink implements Printable {
@@ -56,21 +62,93 @@ public class DiffHyperlink implements Printable {
myPrintOneLine = printOneLine;
}
- public void openDiff(final Project project) {
+ public void openDiff(Project project) {
+ openMultiDiff(project, null);
+ }
+
+ public void openMultiDiff(final Project project,
+ final AbstractTestProxy.AssertEqualsDiffChain chain) {
+ final SimpleDiffRequest diffData = createRequest(project, chain, myFilePath, myExpected, myActual);
+ DiffManager.getInstance().getIdeaDiffTool().show(diffData);
+ }
+
+ private SimpleDiffRequest createRequest(final Project project,
+ final AbstractTestProxy.AssertEqualsDiffChain chain,
+ String filePath, String expected, String actual) {
String expectedTitle = ExecutionBundle.message("diff.content.expected.title");
final DiffContent expectedContent;
final VirtualFile vFile;
- if (myFilePath != null && (vFile = LocalFileSystem.getInstance().findFileByPath(myFilePath)) != null) {
+ if (filePath != null && (vFile = LocalFileSystem.getInstance().findFileByPath(filePath)) != null) {
expectedContent = DiffContent.fromFile(project, vFile);
expectedTitle += " (" + vFile.getPresentableUrl() + ")";
- } else expectedContent = new SimpleContent(myExpected);
+ } else {
+ expectedContent = new SimpleContent(expected);
+ }
final SimpleDiffRequest diffData = new SimpleDiffRequest(project, getTitle());
- diffData.setContents(expectedContent, new SimpleContent(myActual));
+ if (chain != null) {
+ diffData.setToolbarAddons(new DiffRequest.ToolbarAddons() {
+ @Override
+ public void customize(DiffToolbar toolbar) {
+ toolbar.addAction(new NextPrevAction("Compare Previous Failure", AllIcons.Actions.Prevfile, chain) {
+ {
+ registerCustomShortcutSet(ActionManager.getInstance().getAction("PreviousTab").getShortcutSet(), null);
+ }
+
+ @Override
+ protected AbstractTestProxy.AssertEqualsMultiDiffViewProvider getNextId() {
+ return chain.getPrevious();
+ }
+ });
+ toolbar.addAction(new NextPrevAction("Compare Next Failure", AllIcons.Actions.Nextfile, chain) {
+ {
+ registerCustomShortcutSet(ActionManager.getInstance().getAction("NextTab").getShortcutSet(), null);
+ }
+
+ @Override
+ protected AbstractTestProxy.AssertEqualsMultiDiffViewProvider getNextId() {
+ return chain.getNext();
+ }
+ });
+ }
+ });
+ }
+ diffData.setContents(expectedContent, new SimpleContent(actual));
diffData.setContentTitles(expectedTitle, ExecutionBundle.message("diff.content.actual.title"));
diffData.addHint(DiffTool.HINT_SHOW_FRAME);
diffData.addHint(DiffTool.HINT_DO_NOT_IGNORE_WHITESPACES);
diffData.setGroupKey("#com.intellij.execution.junit2.states.ComparisonFailureState$DiffDialog");
- DiffManager.getInstance().getIdeaDiffTool().show(diffData);
+ return diffData;
+ }
+
+ abstract class NextPrevAction extends AnAction {
+
+ private final AbstractTestProxy.AssertEqualsDiffChain myChain;
+
+ public NextPrevAction(@Nullable String text, @Nullable Icon icon,
+ final AbstractTestProxy.AssertEqualsDiffChain chain) {
+ super(text, text, icon);
+ myChain = chain;
+ }
+
+ @Override
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ final DiffViewer viewer = e.getData(PlatformDataKeys.DIFF_VIEWER);
+ final Project project = e.getData(CommonDataKeys.PROJECT);
+ final AbstractTestProxy.AssertEqualsMultiDiffViewProvider nextProvider = getNextId();
+ myChain.setCurrent(nextProvider);
+ final SimpleDiffRequest nextRequest =
+ createRequest(project, myChain, nextProvider.getFilePath(), nextProvider.getExpected(), nextProvider.getActual());
+ viewer.setDiffRequest(nextRequest);
+ }
+
+ @Override
+ public void update(@NotNull AnActionEvent e) {
+ final DiffViewer viewer = e.getData(PlatformDataKeys.DIFF_VIEWER);
+ final Project project = e.getData(CommonDataKeys.PROJECT);
+ e.getPresentation().setEnabled(project != null && viewer != null);
+ }
+
+ protected abstract AbstractTestProxy.AssertEqualsMultiDiffViewProvider getNextId();
}
protected String getTitle() {
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestResultsPanel.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestResultsPanel.java
index a7519429381d..1f4b93238f9c 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestResultsPanel.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestResultsPanel.java
@@ -75,6 +75,7 @@ public abstract class TestResultsPanel extends JPanel implements Disposable {
Disposer.register(this, myToolbarPanel);
final Splitter splitter = createSplitter(mySplitterProportionProperty, mySplitterDefaultProportion);
Disposer.register(this, new Disposable(){
+ @Override
public void dispose() {
remove(splitter);
splitter.dispose();
@@ -91,6 +92,7 @@ public abstract class TestResultsPanel extends JPanel implements Disposable {
rightPanel.add(SameHeightPanel.wrap(myStatusLine, myToolbarPanel), BorderLayout.NORTH);
myStatisticsSplitter = createSplitter(myStatisticsSplitterProportionProperty, 0.5f);
new AwtVisitor(myConsole) {
+ @Override
public boolean visit(Component component) {
if (component instanceof JScrollPane) {
((JScrollPane) component).putClientProperty(UIUtil.KEEP_BORDER_SIDES, SideBorder.TOP | SideBorder.LEFT);
@@ -104,6 +106,7 @@ public abstract class TestResultsPanel extends JPanel implements Disposable {
showStatistics();
}
myProperties.addListener(TestConsoleProperties.SHOW_STATISTICS, new TestFrameworkPropertyListener<Boolean>() {
+ @Override
public void onChanged(Boolean value) {
if (value.booleanValue()) {
showStatistics();
@@ -145,6 +148,7 @@ public abstract class TestResultsPanel extends JPanel implements Disposable {
return outputTab;
}
+ @Override
public void dispose() {
}
@@ -167,9 +171,9 @@ public abstract class TestResultsPanel extends JPanel implements Disposable {
}
splitter.addPropertyChangeListener(new PropertyChangeListener() {
- public void propertyChange(final PropertyChangeEvent evt) {
- if (propertiesComponent == null) return;
- if (evt.getPropertyName().equals(Splitter.PROP_PROPORTION)) {
+ @Override
+ public void propertyChange(@NotNull final PropertyChangeEvent event) {
+ if (event.getPropertyName().equals(Splitter.PROP_PROPORTION)) {
propertiesComponent.setValue(proportionProperty, String.valueOf(splitter.getProportion()));
}
}