blob: 6b772d9cd019ab78bf80a4cdb3d5f328103e3c16 [file] [log] [blame]
/*
* Copyright 2000-2009 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.execution.ExecutionBundle;
import com.intellij.ide.OccurenceNavigator;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import java.util.ArrayList;
import java.util.List;
public class FailedTestsNavigator implements OccurenceNavigator {
private static final String NEXT_NAME = ExecutionBundle.message("next.faled.test.action.name");
private static final String PREVIOUS_NAME = ExecutionBundle.message("prev.faled.test.action.name");
private TestFrameworkRunningModel myModel;
public boolean hasNextOccurence() {
return myModel != null && getNextOccurenceInfo().hasNextOccurence();
}
public boolean hasPreviousOccurence() {
return myModel != null && getPreviousOccurenceInfo().hasNextOccurence();
}
public OccurenceNavigator.OccurenceInfo goNextOccurence() {
final FailedTestInfo result = getNextOccurenceInfo();
myModel.selectAndNotify(result.getDefect());
return new OccurenceInfo(TestsUIUtil.getOpenFileDescriptor(result.myDefect, myModel), result.getDefectNumber(),
result.getDefectsCount());
}
public void setModel(final TestFrameworkRunningModel model) {
myModel = model;
Disposer.register(myModel, new Disposable() {
public void dispose() {
myModel = null;
}
});
}
public OccurenceNavigator.OccurenceInfo goPreviousOccurence() {
final FailedTestInfo result = getPreviousOccurenceInfo();
myModel.selectAndNotify(result.getDefect());
return new OccurenceInfo(TestsUIUtil.getOpenFileDescriptor(result.myDefect, myModel), result.getDefectNumber(),
result.getDefectsCount());
}
public String getNextOccurenceActionName() {
return NEXT_NAME;
}
public String getPreviousOccurenceActionName() {
return PREVIOUS_NAME;
}
private FailedTestInfo getNextOccurenceInfo() {
return new NextFailedTestInfo().execute();
}
private FailedTestInfo getPreviousOccurenceInfo() {
return new PreviousFailedTestInfo().execute();
}
protected abstract class FailedTestInfo {
private AbstractTestProxy myDefect = null;
private List<AbstractTestProxy> myAllTests;
private List<AbstractTestProxy> myDefects;
public AbstractTestProxy getDefect() {
return myDefect;
}
private int getDefectNumber() {
return myDefect == null ? getDefectsCount() : myDefects.indexOf(myDefect) + 1;
}
public FailedTestInfo execute() {
myAllTests = new ArrayList<AbstractTestProxy>(myModel.getRoot().getAllTests());
myDefects = Filter.DEFECTIVE_LEAF.select(myAllTests);
final AbstractTestProxy selectedTest = myModel.getTreeView().getSelectedTest();
final int selectionIndex = myAllTests.indexOf(selectedTest);
if (selectionIndex == -1)
return this;
final AbstractTestProxy defect = findNextDefect(selectionIndex);
if (defect == null)
return this;
if (defect != selectedTest) {
myDefect = defect;
return this;
}
final int defectIndex = myDefects.indexOf(defect);
if (defectIndex == -1 || defectIndex == getBoundIndex())
return this;
myDefect = myDefects.get(nextIndex(defectIndex));
return this;
}
private AbstractTestProxy findNextDefect(final int startIndex) {
for (int i = nextIndex(startIndex); 0 <= i && i < myAllTests.size(); i = nextIndex(i)) {
final AbstractTestProxy nextDefect = myAllTests.get(i);
if (Filter.DEFECTIVE_LEAF.shouldAccept(nextDefect))
return nextDefect;
}
return null;
}
protected abstract int nextIndex(int defectIndex);
protected abstract int getBoundIndex();
protected int getDefectsCount() {
return myDefects.size();
}
private boolean hasNextOccurence() {
return myDefect != null;
}
}
private class NextFailedTestInfo extends FailedTestInfo {
protected int nextIndex(final int defectIndex) {
return defectIndex + 1;
}
protected int getBoundIndex() {
return getDefectsCount() - 1;
}
}
private class PreviousFailedTestInfo extends FailedTestInfo {
protected int nextIndex(final int defectIndex) {
return defectIndex - 1;
}
protected int getBoundIndex() {
return 0;
}
}
}