navigate through test failures without closing diff view (IDEA-119967)

This commit is contained in:
Anna Kozlova
2014-09-09 13:41:14 +04:00
parent 819b9c9931
commit be895ed80c
7 changed files with 199 additions and 13 deletions
@@ -30,7 +30,7 @@ import org.jetbrains.annotations.Nullable;
/**
* @author Roman.Chernyatchik
*/
public class TestComparisionFailedState extends TestFailedState implements AbstractTestProxy.AssertEqualsDiffViewerProvider {
public class TestComparisionFailedState extends TestFailedState implements AbstractTestProxy.AssertEqualsMultiDiffViewProvider {
private final String myErrorMsgPresentation;
private final String myStacktracePresentation;
private DiffHyperlink myHyperlink;
@@ -77,4 +77,14 @@ public class TestComparisionFailedState extends TestFailedState implements Abstr
public String getActual() {
return myHyperlink.getRight();
}
@Override
public void openMultiDiff(Project project, AbstractTestProxy.AssertEqualsDiffChain chain) {
myHyperlink.openMultiDiff(project, chain);
}
@Override
public String getFilePath() {
return myHyperlink.getFilePath();
}
}
@@ -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();
}
}
@@ -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);
@@ -16,12 +16,13 @@
package com.intellij.execution.testframework.actions;
import com.intellij.execution.testframework.AbstractTestProxy;
import com.intellij.execution.testframework.TestTreeViewAction;
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 implements TestTreeViewAction {
@NonNls public static final String ACTION_ID = "openAssertEqualsDiff";
@@ -31,11 +32,35 @@ public class ViewAssertEqualsDiffAction extends AnAction implements TestTreeView
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,4 +80,39 @@ public class ViewAssertEqualsDiffAction extends AnAction implements TestTreeView
presentation.setEnabled(enabled);
presentation.setVisible(enabled);
}
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;
}
}
}
@@ -22,14 +22,23 @@ 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.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
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 +65,85 @@ 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) {
@Override
protected AbstractTestProxy.AssertEqualsMultiDiffViewProvider getNextId() {
return chain.getPrevious();
}
});
toolbar.addAction(new NextPrevAction("Compare Next Failure", AllIcons.Actions.Nextfile, chain) {
@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() {
@@ -24,7 +24,7 @@ import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NonNls;
public class ComparisonFailureState extends FaultyState implements AbstractTestProxy.AssertEqualsDiffViewerProvider {
public class ComparisonFailureState extends FaultyState implements AbstractTestProxy.AssertEqualsMultiDiffViewProvider {
private DiffHyperlink myHyperlink;
@NonNls
protected static final String EXPECTED_VALUE_MESSAGE_TEXT = "expected:<";
@@ -59,4 +59,19 @@ public class ComparisonFailureState extends FaultyState implements AbstractTestP
public void openDiff(final Project project) {
if (myHyperlink != null) myHyperlink.openDiff(project);
}
@Override
public void openMultiDiff(Project project, AbstractTestProxy.AssertEqualsDiffChain chain) {
if (myHyperlink != null) {
myHyperlink.openMultiDiff(project, chain);
}
}
@Override
public String getFilePath() {
if (myHyperlink != null) {
return myHyperlink.getFilePath();
}
return null;
}
}
@@ -292,7 +292,7 @@ public class TestProxy extends AbstractTestProxy {
if (myHyperlink == null) {
return null;
}
return new AssertEqualsDiffViewerProvider() {
return new AssertEqualsMultiDiffViewProvider() {
@Override
public void openDiff(Project project) {
myHyperlink.openDiff(project);
@@ -307,6 +307,16 @@ public class TestProxy extends AbstractTestProxy {
public String getActual() {
return myHyperlink.getRight();
}
@Override
public void openMultiDiff(Project project, AssertEqualsDiffChain chain) {
myHyperlink.openMultiDiff(project, chain);
}
@Override
public String getFilePath() {
return myHyperlink.getFilePath();
}
};
}