file structure base test case

This commit is contained in:
Konstantin Bulenkov
2012-01-30 12:55:18 +01:00
parent d70ddb25fd
commit 894f63ec70
5 changed files with 215 additions and 48 deletions
@@ -90,7 +90,7 @@ public class ViewStructureAction extends AnAction {
}
@Nullable
private static FileStructurePopup createPopup(final Editor editor, Project project, Navigatable navigatable, final FileEditor fileEditor) {
public static FileStructurePopup createPopup(final Editor editor, Project project, @Nullable Navigatable navigatable, final FileEditor fileEditor) {
final StructureViewBuilder structureViewBuilder = fileEditor.getStructureViewBuilder();
if (structureViewBuilder == null) return null;
StructureView structureView = structureViewBuilder.createStructureView(fileEditor, project);
@@ -149,6 +149,7 @@ public class FileStructurePopup implements Disposable {
myTree = new JBTreeWithHintProvider(new DefaultMutableTreeNode(myTreeStructure.getRootElement())) {
@Override
protected PsiElement getPsiElementForHint(Object selectedValue) {
//noinspection ConstantConditions
return getPsi((FilteringTreeStructure.FilteringNode)((DefaultMutableTreeNode)selectedValue).getUserObject());
}
};
@@ -218,12 +219,13 @@ public class FileStructurePopup implements Disposable {
return current.isEmpty() ? null : findClosestTo(myInitialPsiElement, current);
}
@Nullable
private Object findClosestTo(PsiElement path, ArrayList<ObjectWithWeight> paths) {
if (path == null || myInitialPsiElement == null) {
return paths.get(0).node;
}
final Set<PsiElement> parents = getAllParents(myInitialPsiElement);
Object cur = paths.get(0).node;
ArrayList<TreePath> cur = new ArrayList<TreePath>();
int max = -1;
for (ObjectWithWeight p : paths) {
final Object last = ((TreePath)p.node).getLastPathComponent();
@@ -238,14 +240,21 @@ public class FileStructurePopup implements Disposable {
final int size = ContainerUtil.intersection(parents, elements).size();
if (size > max) {
max = size;
cur = p.node;
} else if (size == max && size == parents.size()) {
cur = p.node;
cur.clear();
cur.add((TreePath)p.node);
} else if (size == max) {
cur.add((TreePath)p.node);
}
}
}
return cur;
Collections.sort(cur, new Comparator<TreePath>() {
@Override
public int compare(TreePath o1, TreePath o2) {
return o2.getPathCount() - o1.getPathCount();
}
});
return cur.isEmpty() ? null : cur.get(0);
}
class ObjectWithWeight {
@@ -285,7 +294,7 @@ public class FileStructurePopup implements Disposable {
mySpeedSearch.setComparator(new SpeedSearchComparator(false, true));
final FileStructurePopupFilter filter = new FileStructurePopupFilter();
myFilteringStructure = new FilteringTreeStructure(filter, myTreeStructure, false);
myFilteringStructure = new FilteringTreeStructure(filter, myTreeStructure, ApplicationManager.getApplication().isUnitTestMode());
myAbstractTreeBuilder = new FilteringTreeBuilder(myTree, filter, myFilteringStructure, null) {
@Override
protected boolean validateNode(Object child) {
@@ -385,35 +394,37 @@ public class FileStructurePopup implements Disposable {
});
}
});
final Alarm alarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, myPopup);
alarm.addRequest(new Runnable() {
String filter = "";
if (!ApplicationManager.getApplication().isUnitTestMode()) {
final Alarm alarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, myPopup);
alarm.addRequest(new Runnable() {
String filter = "";
@Override
public void run() {
alarm.cancelAllRequests();
String prefix = mySpeedSearch.getEnteredPrefix();
myTree.getEmptyText().setText(StringUtil.isEmpty(prefix) ? "Nothing to show" : "Can't find '" + prefix + "'");
if (prefix == null) prefix = "";
@Override
public void run() {
alarm.cancelAllRequests();
String prefix = mySpeedSearch.getEnteredPrefix();
myTree.getEmptyText().setText(StringUtil.isEmpty(prefix) ? "Nothing to show" : "Can't find '" + prefix + "'");
if (prefix == null) prefix = "";
if (!filter.equals(prefix)) {
filter = prefix;
myAbstractTreeBuilder.refilter(null, false, false).doWhenProcessed(new Runnable() {
@Override
public void run() {
myTree.repaint();
//if (mySpeedSearch.isPopupActive()) {
// mySpeedSearch.refreshSelection();
//}
}
});
if (!filter.equals(prefix)) {
filter = prefix;
myAbstractTreeBuilder.refilter(null, false, false).doWhenProcessed(new Runnable() {
@Override
public void run() {
myTree.repaint();
//if (mySpeedSearch.isPopupActive()) {
// mySpeedSearch.refreshSelection();
//}
}
});
}
alarm.addRequest(this, 300);
}
alarm.addRequest(this, 300);
}
}, 300);
}, 300);
}
}
private void selectPsiElement(PsiElement element) {
public void selectPsiElement(PsiElement element) {
Set<PsiElement> parents = getAllParents(element);
FilteringTreeStructure.FilteringNode node = (FilteringTreeStructure.FilteringNode)myAbstractTreeBuilder.getRootElement();
@@ -478,7 +489,7 @@ public class FileStructurePopup implements Disposable {
}
@Nullable
protected PsiElement getCurrentElement(@Nullable final PsiFile psiFile) {
public PsiElement getCurrentElement(@Nullable final PsiFile psiFile) {
if (psiFile == null) return null;
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
@@ -718,6 +729,18 @@ public class FileStructurePopup implements Disposable {
myTitle = title;
}
public Tree getTree() {
return myTree;
}
public TreeSpeedSearch getSpeedSearch() {
return mySpeedSearch;
}
public FilteringTreeBuilder getTreeBuilder() {
return myAbstractTreeBuilder;
}
private class FileStructurePopupFilter implements ElementFilter {
private String myLastFilter = null;
private HashSet<Object> myVisibleParents = new HashSet<Object>();
@@ -2362,7 +2362,7 @@ public class AbstractTreeUi {
final ActionCallback done = new ActionCallback();
invokeLaterIfNeeded(new Runnable() {
final Runnable cancelUpdate = new Runnable() {
public void run() {
if (isReleased()) {
done.setRejected();
@@ -2371,21 +2371,29 @@ public class AbstractTreeUi {
if (myResettingToReadyNow.get()) {
_getReady().notify(done);
} else if (isReady()) {
}
else if (isReady()) {
resetToReadyNow();
done.setDone();
} else {
}
else {
if (isIdle() && hasPendingWork()) {
resetToReadyNow();
done.setDone();
} else {
}
else {
_getReady().notify(done);
}
}
maybeReady();
}
}, false);
};
if (ApplicationManager.getApplication().isUnitTestMode()) {
cancelUpdate.run();
} else {
invokeLaterIfNeeded(cancelUpdate, false);
}
if (isEdt() || isPassthroughMode()) {
maybeReady();
@@ -18,6 +18,7 @@ package com.intellij.ui.treeStructure.filtered;
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.AbstractTreeStructure;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.speedSearch.ElementFilter;
@@ -120,7 +121,7 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder {
myRefilterQueue.cancelAllUpdates();
}
final ActionCallback callback = new ActionCallback();
getUi().cancelUpdate().doWhenProcessed(new Runnable() {
final Runnable afterCancelUpdate = new Runnable() {
@Override
public void run() {
if (myRefilterQueue == null || now) {
@@ -145,7 +146,12 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder {
});
}
}
});
};
if (!ApplicationManager.getApplication().isUnitTestMode()) {
getUi().cancelUpdate().doWhenProcessed(afterCancelUpdate);
} else {
afterCancelUpdate.run();
}
return callback;
}
@@ -155,7 +161,7 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder {
final ActionCallback selectionDone = new ActionCallback();
getFilteredStructure().refilter();
queueUpdate().doWhenProcessed(new Runnable() {
final Runnable selectionRunnable = new Runnable() {
public void run() {
revalidateTree();
@@ -173,25 +179,36 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder {
selectionDone.setDone();
}
});
} else {
}
else {
TreeUtil.ensureSelection(myTree);
selectionDone.setDone();
}
} else {
}
else {
selectionDone.setDone();
}
}
});
};
if (!ApplicationManager.getApplication().isUnitTestMode()) {
queueUpdate().doWhenProcessed(selectionRunnable);
} else {
selectionRunnable.run();
}
final ActionCallback result = new ActionCallback();
selectionDone.doWhenDone(new Runnable() {
public void run() {
scrollSelectionToVisible(new Runnable() {
public void run() {
getReady(this).notify(result);
}
}, false);
if (!ApplicationManager.getApplication().isUnitTestMode()) {
scrollSelectionToVisible(new Runnable() {
public void run() {
getReady(this).notify(result);
}
}, false);
} else {
result.setDone();
}
}
}).doWhenRejected(new Runnable() {
@Override
@@ -0,0 +1,119 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.testFramework;
import com.intellij.ide.actions.ViewStructureAction;
import com.intellij.ide.util.FileStructurePopup;
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure;
import com.intellij.util.ui.tree.TreeUtil;
import junit.framework.Assert;
import org.junit.Before;
import java.io.File;
/**
* @author Konstantin Bulenkov
*/
public abstract class FileStructureTestBase extends CodeInsightFixtureTestCase {
FileStructurePopup myPopup;
@Before
public void setUp() throws Exception {
super.setUp();
myFixture.configureByFile(getFileName(getFileExtension()));
myPopup = ViewStructureAction.createPopup(myFixture.getEditor(),
myFixture.getProject(),
null,
TextEditorProvider.getInstance().getTextEditor(myFixture.getEditor()));
update();
}
protected abstract String getFileExtension();
@Override
public void tearDown() throws Exception {
Disposer.dispose(myPopup);
super.tearDown();
}
private String getFileName(String ext) {
return getTestName(false) + (StringUtil.isEmpty(ext) ? "" : "." + ext);
}
protected String getTreeFileName() {
return getFileName("tree");
}
protected void checkTree() throws Exception {
final String expected = FileUtil.loadFile(new File(getTestDataPath() + "/" + getTreeFileName()));
Assert.assertEquals(expected, PlatformTestUtil.print(getTree(), true));
}
private void update() throws InterruptedException {
myPopup.getTreeBuilder().refilter().doWhenProcessed(new Runnable() {
@Override
public void run() {
getStructure().rebuild();
updateTree();
TreeUtil.expandAll(getTree());
myPopup.selectPsiElement(getFile());
}
});
}
protected Tree getTree() {
return myPopup.getTree();
}
protected FilteringTreeBuilder getBuilder() {
return myPopup.getTreeBuilder();
}
protected TreeSpeedSearch getSpeedSearch() {
return myPopup.getSpeedSearch();
}
protected void updateTree() {
updateRecursively(getRootNode());
}
protected FilteringTreeStructure getStructure() {
final FilteringTreeStructure structure = (FilteringTreeStructure)getBuilder().getTreeStructure();
assert structure != null;
return structure;
}
protected FilteringTreeStructure.FilteringNode getRootNode() {
return (FilteringTreeStructure.FilteringNode)getStructure().getRootElement();
}
protected void updateRecursively(final FilteringTreeStructure.FilteringNode node) {
node.update();
for (FilteringTreeStructure.FilteringNode child : node.children()) {
updateRecursively(child);
}
}
}