1package junit.swingui;
2
3import java.util.Enumeration;
4import java.util.Hashtable;
5import java.util.Vector;
6
7import javax.swing.event.TreeModelEvent;
8import javax.swing.event.TreeModelListener;
9import javax.swing.tree.TreeModel;
10import javax.swing.tree.TreePath;
11
12import junit.extensions.TestDecorator;
13import junit.framework.Test;
14import junit.framework.TestSuite;
15
16/**
17 * A tree model for a Test.
18 */
19class TestTreeModel implements TreeModel {
20	private Test fRoot;
21	private Vector fModelListeners= new Vector();
22	private Hashtable fFailures= new Hashtable();
23	private Hashtable fErrors= new Hashtable();
24	private Hashtable fRunTests= new Hashtable();
25
26	/**
27	 * Constructs a tree model with the given test as its root.
28	 */
29	public TestTreeModel(Test root) {
30		super();
31		fRoot= root;
32	}
33
34	/**
35	 * adds a TreeModelListener
36	 */
37	public void addTreeModelListener(TreeModelListener l) {
38		if (!fModelListeners.contains(l))
39			fModelListeners.addElement(l);
40	}
41	/**
42	 * Removes a TestModelListener
43	 */
44	public void removeTreeModelListener(TreeModelListener l) {
45		fModelListeners.removeElement(l);
46	}
47	/**
48	 * Finds the path to a test. Returns the index of the test in its
49	 * parent test suite.
50	 */
51	public int findTest(Test target, Test node, Vector path) {
52		if (target.equals(node))
53			return 0;
54
55		TestSuite suite= isTestSuite(node);
56		for (int i= 0; i < getChildCount(node); i++) {
57			Test t= suite.testAt(i);
58			int index= findTest(target, t, path);
59			if (index >= 0) {
60				path.insertElementAt(node, 0);
61				if (path.size() == 1)
62					return i;
63				return index;
64			}
65		}
66		return -1;
67	}
68	/**
69	 * Fires a node changed event
70	 */
71	public void fireNodeChanged(TreePath path, int index) {
72		int[] indices= {index};
73		Object[] changedChildren= {getChild(path.getLastPathComponent(), index)};
74		TreeModelEvent event= new TreeModelEvent(this, path, indices, changedChildren);
75
76		Enumeration e= fModelListeners.elements();
77		while (e.hasMoreElements()) {
78			TreeModelListener l= (TreeModelListener) e.nextElement();
79			l.treeNodesChanged(event);
80		}
81	}
82	/**
83	 * Gets the test at the given index
84	 */
85	public Object getChild(Object parent, int index) {
86		TestSuite suite= isTestSuite(parent);
87		if (suite != null)
88			return suite.testAt(index);
89		return null;
90	}
91	/**
92	 * Gets the number of tests.
93	 */
94	public int getChildCount(Object parent) {
95		TestSuite suite= isTestSuite(parent);
96		if (suite != null)
97			return suite.testCount();
98		return 0;
99	}
100	/**
101	 * Gets the index of a test in a test suite
102	 */
103	public int getIndexOfChild(Object parent, Object child) {
104		TestSuite suite= isTestSuite(parent);
105		if (suite != null) {
106			int i= 0;
107			for (Enumeration e= suite.tests(); e.hasMoreElements(); i++) {
108				if (child.equals(e.nextElement()))
109					return i;
110			}
111		}
112		return -1;
113	}
114	/**
115	 * Returns the root of the tree
116	 */
117	public Object getRoot() {
118		return fRoot;
119	}
120	/**
121	 * Tests if the test is a leaf.
122	 */
123	public boolean isLeaf(Object node) {
124		return isTestSuite(node) == null;
125	}
126	/**
127	 * Tests if the node is a TestSuite.
128	 */
129	TestSuite isTestSuite(Object node) {
130		if (node instanceof TestSuite)
131			return (TestSuite)node;
132		if (node instanceof TestDecorator) {
133			Test baseTest= ((TestDecorator)node).getTest();
134			return isTestSuite(baseTest);
135		}
136		return null;
137	}
138
139	/**
140	 * Called when the value of the model object was changed in the view
141	 */
142	public void valueForPathChanged(TreePath path, Object newValue) {
143		// we don't support direct editing of the model
144		System.out.println("TreeModel.valueForPathChanged: not implemented");
145	}
146	/**
147	 * Remembers a test failure
148	 */
149	void addFailure(Test t) {
150		fFailures.put(t, t);
151	}
152	/**
153	 * Remembers a test error
154	 */
155	void addError(Test t) {
156		fErrors.put(t, t);
157	}
158	/**
159	 * Remembers that a test was run
160	 */
161	void addRunTest(Test t) {
162		fRunTests.put(t, t);
163	}
164	/**
165	 * Returns whether a test was run
166	 */
167	boolean wasRun(Test t) {
168		return fRunTests.get(t) != null;
169	}
170	/**
171	 * Tests whether a test was an error
172	 */
173	boolean isError(Test t) {
174		return (fErrors != null) && fErrors.get(t) != null;
175	}
176	/**
177	 * Tests whether a test was a failure
178	 */
179	boolean isFailure(Test t) {
180		return (fFailures != null) && fFailures.get(t) != null;
181	}
182	/**
183	 * Resets the test results
184	 */
185	void resetResults() {
186		fFailures= new Hashtable();
187		fRunTests= new Hashtable();
188		fErrors= new Hashtable();
189	}
190}