001: package abbot.tester;
002:
003: import abbot.WaitTimedOutError;
004:
005: import java.awt.event.ActionEvent;
006:
007: import java.awt.*;
008: import java.awt.event.ActionListener;
009:
010: import javax.swing.*;
011: import javax.swing.tree.*;
012:
013: import junit.extensions.abbot.ComponentTestFixture;
014: import junit.extensions.abbot.RepeatHelper;
015:
016: /** Unit test to verify the JTreeTester class.<p> */
017: // TODO add test for lazy-loading children, i.e. load on node select
018: public class JTreeTesterTest extends ComponentTestFixture {
019:
020: private JTreeTester tester;
021: private JTree tree;
022: private JScrollPane scrollPane;
023:
024: protected void setUp() {
025: DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
026: DefaultMutableTreeNode parent, child, leaf;
027: int COUNT = 5;
028: for (int i = 0; i < COUNT; i++) {
029: parent = new DefaultMutableTreeNode("parent " + i);
030: root.add(parent);
031: for (int j = 0; j < COUNT; j++) {
032: child = new DefaultMutableTreeNode("child " + j);
033: parent.add(child);
034: for (int k = 0; k < COUNT; k++) {
035: leaf = new DefaultMutableTreeNode("leaf " + k,
036: false);
037: child.add(leaf);
038: }
039: }
040: }
041: tree = new JTree(root);
042: scrollPane = new JScrollPane(tree);
043: tester = new JTreeTester();
044: }
045:
046: public void testFindPathForStringPath() {
047: TreePath stringPath = new TreePath(new String[] { "root",
048: "parent 2", "child 2" });
049: TreePath path = JTreeLocation
050: .findMatchingPath(tree, stringPath);
051: assertNotNull("Couldn't convert path", path);
052: assertEquals("Wrong path", "[root, parent 2, child 2]", path
053: .toString());
054: }
055:
056: // FIXME sporadic linux (1.4.2) failures
057: public void testMakeVisibleWithStringPath() {
058: showFrame(scrollPane);
059: TreePath stringPath = new TreePath(new String[] { "root",
060: "parent 4", "child 3" });
061: tester.actionMakeVisible(tree, stringPath);
062: TreePath path = JTreeLocation
063: .findMatchingPath(tree, stringPath);
064: assertTrue("Path not visible", tree.isVisible(path));
065: }
066:
067: public void testMakeVisibleWithRealPath() {
068: TreePath stringPath = new TreePath(new String[] { "root",
069: "parent 4", "child 3", "leaf 1" });
070: TreePath path = JTreeLocation
071: .findMatchingPath(tree, stringPath);
072: tester.actionMakeVisible(tree, path);
073: assertTrue("Path not visible", tree.isVisible(path));
074: }
075:
076: public void testMakeVisibleWithHiddenRoot() {
077: tree.setRootVisible(false);
078: tester.actionWaitForIdle();
079: TreePath stringPath = new TreePath(new String[] { "parent 2",
080: "child 1", "leaf 2" });
081: TreePath path = JTreeLocation
082: .findMatchingPath(tree, stringPath);
083: tester.actionMakeVisible(tree, path);
084: assertTrue("Path not visible", tree.isVisible(path));
085: }
086:
087: public void testMakeVisibleMissingPath() {
088: showFrame(scrollPane);
089: TreePath stringPath = new TreePath(new String[] { "root",
090: "parent 4", "child x" });
091: try {
092: tester.actionMakeVisible(tree, stringPath);
093: fail("Should throw an exception when path doesn't match");
094: } catch (LocationUnavailableException e) {
095: }
096: }
097:
098: public void testSelectPath() {
099: showFrame(scrollPane);
100: // Select using tree location path
101: TreePath stringPath = new TreePath(new String[] { "root",
102: "parent 2", "child 2" });
103: TreePath path = JTreeLocation
104: .findMatchingPath(tree, stringPath);
105: assertNotNull("Couldn't convert path", path);
106:
107: tester.actionSelectRow(tree, new JTreeLocation(stringPath));
108: TreePath[] paths = tree.getSelectionPaths();
109: assertTrue("Paths not visible", tree.isVisible(path));
110: assertTrue("No paths selected", paths != null);
111: assertEquals("Too many selected", 1, paths.length);
112: assertEquals("Wrong path selected", stringPath.toString(),
113: paths[0].toString());
114: }
115:
116: public void testSelectPathHiddenRoot() {
117: showFrame(scrollPane);
118: // root is optional if it is hidden
119: TreePath stringPath = new TreePath(new String[] { "root",
120: "parent 2", "child 2" });
121: TreePath stringPath2 = new TreePath(new String[] { "parent 2",
122: "child 1" });
123: tree.setRootVisible(false);
124: TreePath path = JTreeLocation
125: .findMatchingPath(tree, stringPath);
126: assertNotNull("Couldn't convert path", path);
127:
128: tester.actionSelectRow(tree, new JTreeLocation(stringPath));
129: TreePath[] paths = tree.getSelectionPaths();
130: assertTrue("Paths not visible", tree.isVisible(path));
131: assertTrue("No paths selected", paths != null);
132: assertEquals("Too many selected", 1, paths.length);
133: assertEquals("Wrong path selected", stringPath.toString(),
134: paths[0].toString());
135:
136: path = JTreeLocation.findMatchingPath(tree, stringPath2);
137: tester.actionSelectRow(tree, new JTreeLocation(stringPath2));
138: paths = tree.getSelectionPaths();
139: assertTrue("Paths not visible", tree.isVisible(path));
140: assertTrue("No paths selected", paths != null);
141: assertEquals("Too many selected", 1, paths.length);
142: assertEquals("Wrong path selected",
143: "[root, parent 2, child 1]", paths[0].toString());
144: }
145:
146: public void testSelectRow() {
147: int row = 1;
148: showFrame(scrollPane);
149: tester.actionSelectRow(tree, new JTreeLocation(row));
150: TreePath[] paths = tree.getSelectionPaths();
151: assertTrue("No paths selected", paths != null);
152: assertEquals("Wrong row count selected", 1, paths.length);
153: assertEquals("Wrong row selected", tree.getPathForRow(row),
154: paths[0]);
155: }
156:
157: public void testSelectInvisibleRow() {
158: showFrame(scrollPane);
159: try {
160: tester.actionSelectRow(tree, new JTreeLocation(200));
161: fail("Should not successfully select an unavailable row");
162: } catch (ActionFailedException e) {
163: }
164: }
165:
166: public void testToggleRow() {
167: int row = 2;
168: showFrame(scrollPane);
169: tester.actionToggleRow(tree, new JTreeLocation(row));
170: assertTrue("Node should have expanded", tree.isExpanded(row));
171: // Avoid the next action being interpreted as the same click
172: tester.delay(500);
173: tester.actionToggleRow(tree, new JTreeLocation(row));
174: assertTrue("Node should not still be expanded", !tree
175: .isExpanded(row));
176: }
177:
178: public void testGetLocation() {
179: showFrame(tree, new Dimension(200, 450));
180: // position in expand control
181: Rectangle rect = tree.getRowBounds(1);
182: Point expansion = new Point(rect.x / 2, rect.y + rect.height
183: / 2);
184: tester.actionClick(tree, new JTreeLocation(expansion));
185: assertTrue("Node should have expanded", tree.isExpanded(1));
186: ComponentLocation loc = tester.getLocation(tree, expansion);
187: Point where = loc.getPoint(tree);
188: assertTrue("Row expansion click should designate row", rect
189: .contains(where));
190:
191: Point midRow = new Point(rect.x + rect.width / 2, rect.y
192: + rect.height / 2);
193: loc = tester.getLocation(tree, midRow);
194: where = loc.getPoint(tree);
195: assertTrue("Mid-row click should designate row", rect
196: .contains(where));
197:
198: rect = tree.getRowBounds(tree.getRowCount() - 1);
199: Point belowTree = new Point(rect.x + rect.width / 2, rect.y
200: + rect.height + 10);
201: loc = tester.getLocation(tree, belowTree);
202: where = loc.getPoint(tree);
203: assertEquals("Point outside tree should store raw point",
204: belowTree, where);
205: }
206:
207: static int count = 0;
208:
209: public void testConvertPathToStringPath() {
210: class Foo {
211: }
212: DefaultMutableTreeNode root = new DefaultMutableTreeNode(
213: new Foo());
214: DefaultMutableTreeNode parent = new DefaultMutableTreeNode(
215: new Foo());
216: DefaultMutableTreeNode child = new DefaultMutableTreeNode(
217: new Foo());
218: root.add(parent);
219: parent.add(child);
220: JTree tree = new JTree(root);
221: TreePath path = new TreePath(
222: new Object[] { root, parent, child });
223: TreePath strPath = JTreeTester.pathToStringPath(tree, path);
224: assertNull("Should not use default toString() value as path: "
225: + strPath, strPath);
226:
227: count = 0;
228: class Bar {
229: private int id = count++;
230:
231: public String toString() {
232: return String.valueOf(id);
233: }
234: }
235: root = new DefaultMutableTreeNode(new Bar());
236: parent = new DefaultMutableTreeNode(new Bar());
237: child = new DefaultMutableTreeNode(new Bar());
238: root.add(parent);
239: parent.add(child);
240: tree = new JTree(root);
241: showFrame(new JScrollPane(tree));
242: path = new TreePath(new Object[] { root, parent, child });
243: assertEquals("Path should be stringifiable", "[0, 1, 2]",
244: JTreeTester.pathToStringPath(tree, path).toString());
245: }
246:
247: public void testAssertPathExists() {
248: TreePath path = new TreePath(new String[] { "root", "parent 3",
249: "child 1", });
250: assertTrue("Path should exist", tester.assertPathExists(tree,
251: path));
252: path = new TreePath(new String[] { "root", "parent 2",
253: "child y", });
254: assertFalse("Path should not exist", tester.assertPathExists(
255: tree, path, 0, false)); // Use short time out version
256: assertTrue("Path should not exist", tester.assertPathExists(
257: tree, path, true));
258: }
259:
260: public void testLazyLoading() {
261:
262: final DefaultMutableTreeNode root = new DefaultMutableTreeNode(
263: "root");
264: final TreePath path = new TreePath(new String[] { "root",
265: "parent", "child" });
266: final TreePath path2 = new TreePath(new String[] { "root",
267: "parent", "child2" });
268: final JTree lazyTree = new JTree(root);
269: showFrame(lazyTree, new Dimension(200, 450));
270:
271: // Lazily add children to the tree to check that lazy loading is working
272: // properly
273: //
274:
275: final Timer timer = new Timer(2000, new ActionListener() {
276: DefaultMutableTreeNode last = root;
277: int counter = 1;
278:
279: public void actionPerformed(ActionEvent e) {
280:
281: DefaultMutableTreeNode next;
282:
283: if (counter == path.getPathCount()) {
284: next = new DefaultMutableTreeNode(path2
285: .getPathComponent(2));
286: ((DefaultMutableTreeNode) last.getParent())
287: .add(next);
288: } else {
289: next = new DefaultMutableTreeNode(path
290: .getPathComponent(counter));
291: last.add(next);
292: }
293:
294: lazyTree.setModel(new DefaultTreeModel(root, false));
295:
296: counter++;
297: last = next;
298: if (counter > path.getPathCount()) {
299: ((Timer) e.getSource()).stop();
300: ;
301: }
302: }
303: });
304:
305: timer.start();
306:
307: // Test for delayed expansion
308:
309: tester.actionSelectRow(lazyTree, new JTreeLocation(path));
310:
311: // Test for delayed addition
312:
313: tester.actionSelectRow(lazyTree, new JTreeLocation(path2));
314:
315: }
316:
317: /**
318: * Ensure that we don't see null pointer exceptions when recording with
319: * abbot for poorley implemented renders and model.
320: */
321:
322: public void testDumbRenderer() {
323:
324: class DumbRenderer extends Component implements
325: TreeCellRenderer {
326:
327: public Component getTreeCellRendererComponent(JTree tree,
328: Object value, boolean selected, boolean expanded,
329: boolean leaf, int row, boolean hasFocus) {
330: return this ;
331: }
332: }
333:
334: class DumbObject {
335: public DumbObject(String obj) {
336:
337: }
338: }
339:
340: DefaultMutableTreeNode root = new DefaultMutableTreeNode(
341: new DumbObject("root"));
342: DefaultMutableTreeNode child1 = new DefaultMutableTreeNode(
343: new DumbObject("child 1"));
344: DefaultMutableTreeNode child2 = new DefaultMutableTreeNode(
345: new DumbObject("child 2"));
346: root.add(child1);
347: root.add(child2);
348:
349: tree = new JTree(root);
350: tree.setCellRenderer(new DumbRenderer());
351:
352: assertEquals("Must not return null in simple first child case",
353: JTreeTester.valueToString(tree, new TreePath(
354: new Object[] { root, child1 })), "[0]");
355:
356: assertEquals(
357: "Must not return null in simple second child case",
358: JTreeTester.valueToString(tree, new TreePath(
359: new Object[] { root, child2 })), "[1]");
360: }
361:
362: /**
363: * Ensure that we try to use a "getText" method for non JLabel renderers
364: */
365:
366: public void testGetTextRenderer() {
367:
368: class OtherObject {
369:
370: public String _obj;
371:
372: public OtherObject(String obj) {
373: _obj = obj;
374: }
375: }
376:
377: class OtherRenderer extends JTextField implements
378: TreeCellRenderer {
379:
380: public Component getTreeCellRendererComponent(JTree tree,
381: Object value, boolean selected, boolean expanded,
382: boolean leaf, int row, boolean hasFocus) {
383: DefaultMutableTreeNode n = (DefaultMutableTreeNode) value;
384: setText(((OtherObject) n.getUserObject())._obj);
385: return this ;
386: }
387: }
388:
389: DefaultMutableTreeNode root = new DefaultMutableTreeNode(
390: new OtherObject("root"));
391: DefaultMutableTreeNode child1 = new DefaultMutableTreeNode(
392: new OtherObject("child 1"));
393: DefaultMutableTreeNode child2 = new DefaultMutableTreeNode(
394: new OtherObject("child 2"));
395: root.add(child1);
396: root.add(child2);
397:
398: tree = new JTree(root);
399: tree.setCellRenderer(new OtherRenderer());
400:
401: assertEquals(
402: "Must return the correct child text for non JLabel renderers",
403: JTreeTester.valueToString(tree, new TreePath(
404: new Object[] { root, child1 })), "child 1");
405:
406: assertEquals(
407: "Must return the correct child text for non JLabel renderers",
408: JTreeTester.valueToString(tree, new TreePath(
409: new Object[] { root, child2 })), "child 2");
410: }
411:
412: /** Create a new test case with the given name. */
413: public JTreeTesterTest(String name) {
414: super (name);
415: }
416:
417: public static void main(String[] args) {
418: RepeatHelper.runTests(args, JTreeTesterTest.class);
419: }
420: }
|