2f085e64d422980cb57d17b09d5945af4c9985c2
[idea/community.git] / platform / platform-impl / testSrc / com / intellij / ide / util / treeView / FilteringTreeBuilderTest.java
1 package com.intellij.ide.util.treeView;
2
3 import com.intellij.openapi.util.ActionCallback;
4 import com.intellij.openapi.util.Condition;
5 import com.intellij.openapi.util.Disposer;
6 import com.intellij.openapi.util.Ref;
7 import com.intellij.ui.TreeUIHelper;
8 import com.intellij.ui.speedSearch.ElementFilter;
9 import com.intellij.ui.treeStructure.*;
10 import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
11 import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure;
12
13 import java.util.LinkedHashMap;
14
15 public class FilteringTreeBuilderTest extends BaseTreeTestCase  {
16   private FilteringTreeBuilder myBuilder;
17   private MyFilter myFilter;
18   private Node myRoot;
19   private SimpleTreeStructure myStructure;
20
21   public FilteringTreeBuilderTest() {
22     super(false, false);
23   }
24
25   @Override
26   protected void setUp() throws Exception {
27     super.setUp();
28     myTree = new SimpleTree() {
29       @Override
30       protected void configureUiHelper(final TreeUIHelper helper) {
31       }
32     };
33
34     myFilter = new MyFilter();
35     myRoot = new Node(null, "/");
36     myStructure = new SimpleTreeStructure.Impl(myRoot);
37   }
38
39   private void initBuilder() throws Exception {
40     myBuilder = new FilteringTreeBuilder(null, myTree, myFilter, myStructure, AlphaComparator.INSTANCE) {
41       @Override
42       protected AbstractTreeUpdater createUpdater() {
43        return _createUpdater(this);
44       }
45     };
46
47     showTree();
48
49     Disposer.register(getRootDisposable(), myBuilder);
50   }
51
52   public void testFilter() throws Exception {
53     myTree.setRootVisible(false);
54
55     final Node f1 = myRoot.addChild("folder1");
56     f1.addChild("file11");
57     f1.addChild("file12");
58     Node f11 = f1.addChild("folder11");
59     f11.addChild("element111");
60     myRoot.addChild("folder2").addChild("file21");
61
62     initBuilder();
63
64     assertTree("-/\n"
65              + " -folder1\n"
66              + "  file11\n"
67              + "  file12\n"
68              + "  -folder11\n"
69              + "   element111\n"
70              + " -folder2\n"
71              + "  file21\n");
72
73     update("", findNode("file11"));
74     assertTree("-/\n"
75              + " -folder1\n"
76              + "  [file11]\n"
77              + "  file12\n"
78              + "  -folder11\n"
79              + "   element111\n"
80              + " -folder2\n"
81              + "  file21\n");
82
83     update("f", null);
84     assertTree("-/\n"
85              + " -folder1\n"
86              + "  [file11]\n"
87              + "  file12\n"
88              + "  folder11\n"
89              + " -folder2\n"
90              + "  file21\n");
91
92     update("fo", null);
93     assertTree("-/\n"
94              + " -folder1\n"
95              + "  [folder11]\n"
96              + " folder2\n");
97
98     update("fo_", null);
99     assertTree("+/\n");
100
101     update("", null);
102     assertTree("-/\n"
103              + " -[folder1]\n"
104              + "  file11\n"
105              + "  file12\n"
106              + "  -folder11\n"
107              + "   element111\n"
108              + " -folder2\n"
109              + "  file21\n");
110
111
112     select("element111");
113     assertTree("-/\n"
114              + " -folder1\n"
115              + "  file11\n"
116              + "  file12\n"
117              + "  -folder11\n"
118              + "   [element111]\n"
119              + " -folder2\n"
120              + "  file21\n");
121
122     update("folder2", null);
123     assertTree("-/\n"
124              + " [folder2]\n");
125
126     update("", null);
127     assertTree("-/\n"
128              + " -folder1\n"
129              + "  file11\n"
130              + "  file12\n"
131              + "  -folder11\n"
132              + "   element111\n"
133              + " -[folder2]\n"
134              + "  file21\n");
135
136     update("file1", null);
137     assertTree("-/\n"
138              + " -[folder1]\n"
139              + "  file11\n"
140              + "  file12\n");
141
142     select("file12");
143     assertTree("-/\n"
144              + " -folder1\n"
145              + "  file11\n"
146              + "  [file12]\n");
147
148     update("", null);
149     assertTree("-/\n"
150              + " -folder1\n"
151              + "  file11\n"
152              + "  [file12]\n"
153              + "  -folder11\n"
154              + "   element111\n"
155              + " -folder2\n"
156              + "  file21\n");
157
158   }
159
160   private void select(String element) throws Exception {
161     FilteringTreeStructure.Node node = myBuilder.getVisibleNodeFor(findNode(element));
162     select(new Object[] {node}, false);
163   }
164
165   private void update(final String text, final Object selection) throws Exception {
166     final ActionCallback result = new ActionCallback();
167     doAndWaitForBuilder(new Runnable() {
168       public void run() {
169         myFilter.update(text, selection).notify(result);
170       }
171     }, new Condition<Object>() {
172       public boolean value(Object o) {
173         return result.isProcessed();
174       }
175     });
176   }
177
178   private class Node extends CachingSimpleNode {
179
180     private final LinkedHashMap<String, Node> myKids = new LinkedHashMap<String, Node>();
181
182     private Node(final SimpleNode aParent, String name) {
183       super(aParent);
184       myName = name;
185     }
186
187     public Node addChild(String name) {
188       if (!myKids.containsKey(name)) {
189         myKids.put(name, new Node(this, name));
190       }
191
192       return myKids.get(name);
193     }
194
195     @Override
196     protected void doUpdate() {
197       setPlainText(myName);
198     }
199
200     protected SimpleNode[] buildChildren() {
201       return myKids.values().toArray(new Node[myKids.size()]);
202     }
203
204     @Override
205     public String toString() {
206       return myName;
207     }
208
209     @Override
210     protected void updateFileStatus() {
211       
212     }
213   }
214
215   private Object findNode(final String name) {
216     final Ref<Object> node = new Ref<Object>();
217     ((SimpleTree)myTree).accept(myBuilder, new SimpleNodeVisitor() {
218       public boolean accept(final SimpleNode simpleNode) {
219         if (name.equals(simpleNode.toString())) {
220           node.set(myBuilder.getOriginalNode(simpleNode));
221           return true;
222         } else {
223           return false;
224         }
225       }
226     });
227
228     return node.get();
229   }
230
231
232   private class MyFilter extends ElementFilter.Active.Impl {
233
234     String myPattern = "";
235
236     public boolean shouldBeShowing(final Object value) {
237       return value.toString().startsWith(myPattern);
238     }
239
240     public ActionCallback update(final String pattern, Object selection) {
241       myPattern = pattern;
242       return fireUpdate(selection, true, false);
243     }
244   }
245
246   @Override
247   AbstractTreeBuilder getBuilder() {
248     return myBuilder;
249   }
250 }
251
252