package junit.swingui; import java.util.*; import javax.swing.event.*; import javax.swing.tree.*; import junit.extensions.TestDecorator; import junit.framework.*; /** * A tree model for a Test. */ class TestTreeModel implements TreeModel { private Test fRoot; private Vector fModelListeners= new Vector(); private Hashtable fFailures= new Hashtable(); private Hashtable fErrors= new Hashtable(); private Hashtable fRunTests= new Hashtable(); /** * Constructs a tree model with the given test as its root. */ public TestTreeModel(Test root) { super(); fRoot= root; } /** * adds a TreeModelListener */ public void addTreeModelListener(TreeModelListener l) { if (!fModelListeners.contains(l)) fModelListeners.addElement(l); } /** * Removes a TestModelListener */ public void removeTreeModelListener(TreeModelListener l) { fModelListeners.removeElement(l); } /** * Finds the path to a test. Returns the index of the test in its * parent test suite. */ public int findTest(Test target, Test node, Vector path) { if (target.equals(node)) return 0; TestSuite suite= isTestSuite(node); for (int i= 0; i < getChildCount(node); i++) { Test t= suite.testAt(i); int index= findTest(target, t, path); if (index >= 0) { path.insertElementAt(node, 0); if (path.size() == 1) return i; return index; } } return -1; } /** * Fires a node changed event */ public void fireNodeChanged(TreePath path, int index) { int[] indices= {index}; Object[] changedChildren= {getChild(path.getLastPathComponent(), index)}; TreeModelEvent event= new TreeModelEvent(this, path, indices, changedChildren); Enumeration e= fModelListeners.elements(); while (e.hasMoreElements()) { TreeModelListener l= (TreeModelListener) e.nextElement(); l.treeNodesChanged(event); } } /** * Gets the test at the given index */ public Object getChild(Object parent, int index) { TestSuite suite= isTestSuite(parent); if (suite != null) return suite.testAt(index); return null; } /** * Gets the number of tests. */ public int getChildCount(Object parent) { TestSuite suite= isTestSuite(parent); if (suite != null) return suite.testCount(); return 0; } /** * Gets the index of a test in a test suite */ public int getIndexOfChild(Object parent, Object child) { TestSuite suite= isTestSuite(parent); if (suite != null) { int i= 0; for (Enumeration e= suite.tests(); e.hasMoreElements(); i++) { if (child.equals((Test)e.nextElement())) return i; } } return -1; } /** * Returns the root of the tree */ public Object getRoot() { return fRoot; } /** * Tests if the test is a leaf. */ public boolean isLeaf(Object node) { return isTestSuite(node) == null; } /** * Tests if the node is a TestSuite. */ TestSuite isTestSuite(Object node) { if (node instanceof TestSuite) return (TestSuite)node; if (node instanceof TestDecorator) { Test baseTest= ((TestDecorator)node).getTest(); return isTestSuite(baseTest); } return null; } /** * Called when the value of the model object was changed in the view */ public void valueForPathChanged(TreePath path, Object newValue) { // we don't support direct editing of the model System.out.println("TreeModel.valueForPathChanged: not implemented"); } /** * Remembers a test failure */ void addFailure(Test t) { fFailures.put(t, t); } /** * Remembers a test error */ void addError(Test t) { fErrors.put(t, t); } /** * Remembers that a test was run */ void addRunTest(Test t) { fRunTests.put(t, t); } /** * Returns whether a test was run */ boolean wasRun(Test t) { return fRunTests.get(t) != null; } /** * Tests whether a test was an error */ boolean isError(Test t) { return (fErrors != null) && fErrors.get(t) != null; } /** * Tests whether a test was a failure */ boolean isFailure(Test t) { return (fFailures != null) && fFailures.get(t) != null; } /** * Resets the test results */ void resetResults() { fFailures= new Hashtable(); fRunTests= new Hashtable(); fErrors= new Hashtable(); } }