View Javadoc

1   // Copyright (C) 2005 - 2009 Philip Aston
2   // All rights reserved.
3   //
4   // This file is part of The Grinder software distribution. Refer to
5   // the file LICENSE which is part of The Grinder distribution for
6   // licensing details. The Grinder distribution is available on the
7   // Internet at http://grinder.sourceforge.net/
8   //
9   // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
12  // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
13  // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
14  // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16  // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17  // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
18  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
20  // OF THE POSSIBILITY OF SUCH DAMAGE.
21  
22  package net.grinder.console.swingui;
23  
24  import java.io.File;
25  import java.io.FileFilter;
26  
27  import javax.swing.event.TreeModelEvent;
28  import javax.swing.event.TreeModelListener;
29  
30  import net.grinder.console.common.Resources;
31  import net.grinder.console.distribution.AgentCacheState;
32  import net.grinder.console.distribution.FileChangeWatcher;
33  import net.grinder.console.editor.Buffer;
34  import net.grinder.console.editor.EditorModel;
35  import net.grinder.console.editor.TextSource;
36  import net.grinder.console.editor.TextSource.Factory;
37  import net.grinder.console.swingui.FileTreeModel.FileNode;
38  import net.grinder.console.swingui.FileTreeModel.Node;
39  import net.grinder.testutility.AbstractFileTestCase;
40  import net.grinder.testutility.AssertUtilities;
41  import net.grinder.testutility.CallData;
42  import net.grinder.testutility.RandomStubFactory;
43  
44  
45  /**
46   * Unit tests for {@link FileTreeModel}.
47   *
48   * @author Philip Aston
49   */
50  public class TestFileTreeModel extends AbstractFileTestCase {
51  
52    private RandomStubFactory<Resources> m_resourcesStubFactory =
53      RandomStubFactory.create(Resources.class);
54    private Resources m_resources = m_resourcesStubFactory.getStub();
55  
56    private RandomStubFactory<Factory> m_textSourceFactoryStubFactory =
57      RandomStubFactory.create(TextSource.Factory.class);
58    private TextSource.Factory m_textSourceFactory =
59      m_textSourceFactoryStubFactory.getStub();
60  
61    private RandomStubFactory<AgentCacheState> m_agentCacheStateStubFactory =
62      RandomStubFactory.create(AgentCacheState.class);
63    private AgentCacheState m_agentCacheState =
64      m_agentCacheStateStubFactory.getStub();
65  
66    private final RandomStubFactory<FileChangeWatcher>
67      m_fileChangeWatcherStubFactory =
68        RandomStubFactory.create(FileChangeWatcher.class);
69    private final FileChangeWatcher m_fileChangeWatcher =
70      m_fileChangeWatcherStubFactory.getStub();
71  
72    final EditorModel m_editorModel = new EditorModel(m_resources,
73                                                      m_textSourceFactory,
74                                                      m_agentCacheState,
75                                                      m_fileChangeWatcher);
76  
77    private final FileFilter m_nullFileFilter = new FileFilter() {
78        public boolean accept(File pathname) {
79          return true;
80        }
81      };
82  
83    public void testWithRootNode() throws Exception {
84      final FileTreeModel fileTreeModel =
85        new FileTreeModel(m_editorModel, m_nullFileFilter, getDirectory());
86  
87      final Node rootNode = (Node)fileTreeModel.getRoot();
88      assertFalse(rootNode instanceof FileNode);
89      assertFalse(rootNode.canOpen());
90      assertNull(rootNode.getBuffer());
91  
92      assertEquals(getDirectory(), rootNode.getFile());
93      assertEquals(getDirectory().getPath(), rootNode.toString());
94  
95      final FileTreeModel fileTreeModel2 =
96        new FileTreeModel(m_editorModel, m_nullFileFilter, getDirectory());
97      assertTrue(rootNode.belongsToModel(fileTreeModel));
98      assertFalse(rootNode.belongsToModel(fileTreeModel2));
99  
100     assertNull(fileTreeModel.getChild(rootNode, 0));
101     assertNull(fileTreeModel2.getChild(rootNode, 0));
102     assertEquals(0, fileTreeModel.getChildCount(rootNode));
103     assertEquals(0, fileTreeModel2.getChildCount(rootNode));
104 
105     assertFalse(fileTreeModel.isLeaf(rootNode));
106     assertFalse(fileTreeModel2.isLeaf(rootNode));
107 
108     assertEquals(-1, fileTreeModel.getIndexOfChild(null, null));
109     assertEquals(-1, fileTreeModel.getIndexOfChild(rootNode, null));
110     assertEquals(-1, fileTreeModel.getIndexOfChild(rootNode, rootNode));
111   }
112 
113   public void testListener() throws Exception {
114     final RandomStubFactory<TreeModelListener> listenerStubFactory1 =
115       RandomStubFactory.create(TreeModelListener.class);
116     final RandomStubFactory<TreeModelListener> listenerStubFactory2 =
117       RandomStubFactory.create(TreeModelListener.class);
118 
119     final FileTreeModel fileTreeModel =
120       new FileTreeModel(m_editorModel, m_nullFileFilter, getDirectory());
121     fileTreeModel.addTreeModelListener(listenerStubFactory1.getStub());
122     fileTreeModel.addTreeModelListener(listenerStubFactory2.getStub());
123 
124     fileTreeModel.setRootDirectory(getDirectory());
125     final Node rootNode = (Node)fileTreeModel.getRoot();
126 
127     final CallData callData =
128       listenerStubFactory1.assertSuccess("treeStructureChanged",
129                                          TreeModelEvent.class);
130     final TreeModelEvent event = (TreeModelEvent)callData.getParameters()[0];
131     assertEquals(fileTreeModel, event.getSource());
132     AssertUtilities.assertArraysEqual(rootNode.getPath().getPath(),
133                                       event.getPath());
134     listenerStubFactory1.assertNoMoreCalls();
135     listenerStubFactory2.assertSuccess("treeStructureChanged",
136       TreeModelEvent.class);
137     listenerStubFactory2.assertNoMoreCalls();
138 
139     fileTreeModel.refresh();
140     listenerStubFactory1.assertSuccess("treeStructureChanged",
141       TreeModelEvent.class);
142     listenerStubFactory1.assertNoMoreCalls();
143     listenerStubFactory2.assertSuccess("treeStructureChanged",
144       TreeModelEvent.class);
145     listenerStubFactory2.assertNoMoreCalls();
146 
147     // For some reason, if we record the "equals" invocations that the
148     // remove causes, the next assertNoMoreCalls fails with a
149     // ConcurrentModificationException. Seems bogus to me, but its not
150     // pertinent to the test.
151     listenerStubFactory1.setIgnoreObjectMethods();
152     listenerStubFactory2.setIgnoreObjectMethods();
153     fileTreeModel.removeTreeModelListener(listenerStubFactory1.getStub());
154     fileTreeModel.refresh();
155 
156     listenerStubFactory1.assertNoMoreCalls();
157     listenerStubFactory2.assertSuccess("treeStructureChanged",
158       TreeModelEvent.class);
159     listenerStubFactory2.assertNoMoreCalls();
160 
161     fileTreeModel.valueForPathChanged(rootNode.getPath(), rootNode);
162     final CallData callData2 =
163       listenerStubFactory2.assertSuccess("treeNodesChanged",
164                                          TreeModelEvent.class);
165     final TreeModelEvent event2 = (TreeModelEvent)callData2.getParameters()[0];
166     assertEquals(fileTreeModel, event2.getSource());
167     AssertUtilities.assertArraysEqual(rootNode.getPath().getPath(),
168                                       event2.getPath());
169     listenerStubFactory2.assertNoMoreCalls();
170   }
171 
172   public void testWithFileStructure() throws Exception {
173     final File file1 = new File(getDirectory(), "file1");
174     assertTrue(file1.createNewFile());
175     final File dir1 = new File(getDirectory(), "dir1");
176     assertTrue(dir1.mkdir());
177     final File file2 = new File(dir1, "file2");
178     assertTrue(file2.createNewFile());
179     final File file3 = new File(dir1, "file3");
180     assertTrue(file3.createNewFile());
181 
182     final FileTreeModel fileTreeModel =
183       new FileTreeModel(m_editorModel, m_nullFileFilter, getDirectory());
184     final FileTreeModel fileTreeModel2 =
185       new FileTreeModel(m_editorModel, m_nullFileFilter, getDirectory());
186     fileTreeModel.setRootDirectory(getDirectory());
187     final Node rootNode = (Node)fileTreeModel.getRoot();
188     assertFalse(rootNode.canOpen());
189     assertNull(rootNode.getBuffer());
190 
191     assertEquals(2, fileTreeModel.getChildCount(rootNode));
192     final Node dir1Node = (Node)fileTreeModel.getChild(rootNode, 0);
193     final FileNode file1Node = (FileNode)fileTreeModel.getChild(rootNode, 1);
194     assertEquals(file1.getName(), file1Node.toString());
195     assertTrue(file1Node.canOpen());
196 
197     assertNull(fileTreeModel.getChild(file1Node, 0));
198     assertEquals(0, fileTreeModel.getChildCount(file1Node));
199     assertTrue(fileTreeModel.isLeaf(file1Node));
200     assertFalse(fileTreeModel2.isLeaf(file1Node));
201 
202     assertEquals(-1, fileTreeModel.getIndexOfChild(file1Node, file1Node));
203     assertEquals(0, fileTreeModel.getIndexOfChild(rootNode, dir1Node));
204     assertEquals(1, fileTreeModel.getIndexOfChild(rootNode, file1Node));
205     assertEquals(-1, fileTreeModel2.getIndexOfChild(rootNode, file1Node));
206 
207     final FileNode file3Node = (FileNode)fileTreeModel.getChild(dir1Node, 1);
208     assertEquals(1, fileTreeModel.getIndexOfChild(dir1Node, file3Node));
209   }
210 
211   public void testRefreshAndFindNode() throws Exception {
212     final FileTreeModel fileTreeModel =
213       new FileTreeModel(m_editorModel, m_nullFileFilter, getDirectory());
214     fileTreeModel.setRootDirectory(getDirectory());
215     final Node rootNode = (Node)fileTreeModel.getRoot();
216 
217     final File dir1 = new File(getDirectory(), "dir1");
218 
219     fileTreeModel.refresh();
220     assertNull(fileTreeModel.findNode(dir1));
221 
222     assertTrue(dir1.mkdir());
223     final File dir2 = new File(getDirectory(), "dir2");
224     assertTrue(dir2.mkdir());
225 
226     fileTreeModel.refresh();
227     assertNotNull(fileTreeModel.findNode(dir1));
228     fileTreeModel.refresh();
229     assertNotNull(fileTreeModel.findNode(dir1));
230     assertTrue(dir1.delete());
231     assertNotNull(fileTreeModel.findNode(dir1));
232     fileTreeModel.refresh();
233     assertNull(fileTreeModel.findNode(dir1));
234     assertTrue(dir1.mkdir());
235     assertTrue(dir2.delete());
236 
237     final File file1 = new File(getDirectory(), "file1");
238     assertTrue(file1.createNewFile());
239     final File file2 = new File(dir1, "file2");
240     assertTrue(file2.createNewFile());
241     final File file3 = new File(dir1, "file3");
242     assertTrue(file3.createNewFile());
243 
244     final Node dir1Node = fileTreeModel.findNode(dir1);
245     assertEquals(dir1Node, fileTreeModel.getChild(rootNode, 0));
246 
247     final FileNode file3Node = (FileNode)fileTreeModel.findNode(file3);
248     assertSame(file3Node, fileTreeModel.getChild(dir1Node, 1));
249     assertSame(file3Node, fileTreeModel.findNode(file3));
250 
251     final RandomStubFactory<TreeModelListener> listenerStubFactory =
252       RandomStubFactory.create(TreeModelListener.class);
253     fileTreeModel.addTreeModelListener(listenerStubFactory.getStub());
254 
255     final File dir3 = new File(dir1, "dir3");
256     final File file4 = new File(dir3, "file4");
257     assertNull(fileTreeModel.findNode(file4));
258 
259     listenerStubFactory.assertNoMoreCalls();
260 
261     assertTrue(dir3.mkdir());
262     assertTrue(file4.createNewFile());
263     final FileNode file4Node = (FileNode)fileTreeModel.findNode(file4);
264 
265     final CallData callData =
266       listenerStubFactory.assertSuccess("treeStructureChanged",
267                                         TreeModelEvent.class);
268     assertEquals("treeStructureChanged", callData.getMethodName());
269     AssertUtilities.assertArraysEqual(new Class[] { TreeModelEvent.class, },
270       callData.getParameterTypes());
271     final TreeModelEvent event = (TreeModelEvent)callData.getParameters()[0];
272     assertEquals(fileTreeModel, event.getSource());
273     AssertUtilities.assertArraysEqual(
274       dir1Node.getPath().getPath(),
275       event.getPath());
276     listenerStubFactory.assertNoMoreCalls();
277 
278     assertEquals(file4, file4Node.getFile());
279   }
280 
281   public void testFindFileNode() throws Exception {
282     final File file1 = new File(getDirectory(), "file1");
283     assertTrue(file1.createNewFile());
284 
285     final FileTreeModel fileTreeModel =
286       new FileTreeModel(m_editorModel, m_nullFileFilter, getDirectory());
287     fileTreeModel.setRootDirectory(getDirectory());
288     final FileNode file1Node = (FileNode)fileTreeModel.findNode(file1);
289 
290     final RandomStubFactory<Buffer> bufferStubFactory1 =
291       RandomStubFactory.create(Buffer.class);
292     final Buffer buffer1 = bufferStubFactory1.getStub();
293     final RandomStubFactory<Buffer> bufferStubFactory2 =
294       RandomStubFactory.create(Buffer.class);
295     final Buffer buffer2 = bufferStubFactory2.getStub();
296 
297     file1Node.setBuffer(buffer1);
298     assertSame(buffer1, file1Node.getBuffer());
299     assertEquals(file1Node, fileTreeModel.findFileNode(buffer1));
300     assertNull(fileTreeModel.findFileNode(buffer2));
301 
302     file1Node.setBuffer(buffer2);
303     assertNull(fileTreeModel.findFileNode(buffer1));
304     assertEquals(file1Node, fileTreeModel.findFileNode(buffer2));
305   }
306 
307   public void testRefreshChangedDirectoriesListener() throws Exception {
308     final File dir1 = new File(getDirectory(), "dir1");
309     assertTrue(dir1.mkdir());
310     final File file1 = new File(getDirectory(), "file1");
311     assertTrue(file1.createNewFile());
312     final File file2 = new File(dir1, "file2");
313     assertTrue(file2.createNewFile());
314     final File file3 = new File(dir1, "file3");
315     assertTrue(file3.createNewFile());
316 
317     final FileTreeModel fileTreeModel =
318       new FileTreeModel(m_editorModel, m_nullFileFilter, getDirectory());
319     fileTreeModel.setRootDirectory(getDirectory());
320 
321     final RandomStubFactory<TreeModelListener> listenerStubFactory =
322       RandomStubFactory.create(TreeModelListener.class);
323     final TreeModelListener listener =
324       listenerStubFactory.getStub();
325     fileTreeModel.addTreeModelListener(listener);
326 
327     final FileChangeWatcher.FileChangedListener filesChangedListener =
328       fileTreeModel.new RefreshChangedDirectoriesListener();
329 
330     filesChangedListener.filesChanged(new File[0]);
331     listenerStubFactory.assertNoMoreCalls();
332 
333     filesChangedListener.filesChanged(new File[] { file2, dir1, });
334     listenerStubFactory.assertSuccess("treeStructureChanged",
335                                       TreeModelEvent.class);
336   }
337 }