1 | /* |
---|
2 | * This program is free software; you can redistribute it and/or modify |
---|
3 | * it under the terms of the GNU General Public License as published by |
---|
4 | * the Free Software Foundation; either version 2 of the License, or |
---|
5 | * (at your option) any later version. |
---|
6 | * |
---|
7 | * This program is distributed in the hope that it will be useful, |
---|
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
10 | * GNU General Public License for more details. |
---|
11 | * |
---|
12 | * You should have received a copy of the GNU General Public License |
---|
13 | * along with this program; if not, write to the Free Software |
---|
14 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
15 | */ |
---|
16 | |
---|
17 | /* |
---|
18 | * WekaTestSuite.java |
---|
19 | * Copyright (C) 2005 University of Waikato, Hamilton, New Zealand |
---|
20 | * |
---|
21 | */ |
---|
22 | |
---|
23 | package weka.test; |
---|
24 | |
---|
25 | import weka.core.ClassDiscovery; |
---|
26 | import weka.gui.GenericPropertiesCreator; |
---|
27 | |
---|
28 | import java.util.Collections; |
---|
29 | import java.util.StringTokenizer; |
---|
30 | import java.util.Vector; |
---|
31 | |
---|
32 | import junit.framework.Test; |
---|
33 | import junit.framework.TestSuite; |
---|
34 | |
---|
35 | /** |
---|
36 | * Extends the standard TestSuite class wtih some additional methods for |
---|
37 | * automatic generation of a series of tests. |
---|
38 | * |
---|
39 | * @author FracPete (fracpete at waikato dot ac dot nz) |
---|
40 | * @version $Revision: 1.5 $ |
---|
41 | * @see GenericPropertiesCreator |
---|
42 | * @see ClassDiscovery |
---|
43 | */ |
---|
44 | public class WekaTestSuite |
---|
45 | extends TestSuite { |
---|
46 | |
---|
47 | /** |
---|
48 | * checks whether the classname is a valid one, i.e., from a public class |
---|
49 | * |
---|
50 | * @param classname the classname to check |
---|
51 | * @return whether the classname is a valid one |
---|
52 | */ |
---|
53 | protected static boolean isValidClassname(String classname) { |
---|
54 | return (classname.indexOf("$") == -1); |
---|
55 | } |
---|
56 | |
---|
57 | /** |
---|
58 | * determines all the classes derived from the given superclass in the |
---|
59 | * specified packages |
---|
60 | * |
---|
61 | * @param superclass the class to find subclasses for |
---|
62 | * @param pacakges the packages to search in for subclasses |
---|
63 | * @return the classes that were found |
---|
64 | */ |
---|
65 | protected static Vector getClassnames(String superclass, Vector packages) { |
---|
66 | Vector result; |
---|
67 | Vector names; |
---|
68 | int i; |
---|
69 | int n; |
---|
70 | |
---|
71 | result = new Vector(); |
---|
72 | |
---|
73 | for (i = 0; i < packages.size(); i++) { |
---|
74 | names = ClassDiscovery.find(superclass, (String) packages.get(i)); |
---|
75 | for (n = 0; n < names.size(); n++) { |
---|
76 | // skip non-public classes |
---|
77 | if (isValidClassname((String) names.get(n))) |
---|
78 | result.add(names.get(n)); |
---|
79 | } |
---|
80 | } |
---|
81 | |
---|
82 | return result; |
---|
83 | } |
---|
84 | |
---|
85 | /** |
---|
86 | * returns a Vector with all the classnames of the specified property in |
---|
87 | * the GenericPropertiesCreator. |
---|
88 | * |
---|
89 | * @param property the property to get the classnames for |
---|
90 | * @return the classnames of the given property |
---|
91 | * @see GenericPropertiesCreator |
---|
92 | */ |
---|
93 | protected static Vector getClassnames(String property) { |
---|
94 | GenericPropertiesCreator gpc; |
---|
95 | String classes; |
---|
96 | Vector result; |
---|
97 | StringTokenizer tok; |
---|
98 | String classname; |
---|
99 | |
---|
100 | result = new Vector(); |
---|
101 | |
---|
102 | try { |
---|
103 | gpc = new GenericPropertiesCreator(); |
---|
104 | gpc.execute(false); |
---|
105 | |
---|
106 | classes = gpc.getOutputProperties().getProperty(property); |
---|
107 | tok = new StringTokenizer(classes, ","); |
---|
108 | |
---|
109 | while (tok.hasMoreTokens()) { |
---|
110 | classname = tok.nextToken(); |
---|
111 | // skip non-public classes |
---|
112 | if (isValidClassname(classname)) |
---|
113 | result.add(classname); |
---|
114 | } |
---|
115 | } |
---|
116 | catch (Exception e) { |
---|
117 | e.printStackTrace(); |
---|
118 | } |
---|
119 | |
---|
120 | return result; |
---|
121 | } |
---|
122 | |
---|
123 | /** |
---|
124 | * generates a Test class name for a given "regular" class |
---|
125 | * |
---|
126 | * @param classname the class to generate the Test class name for |
---|
127 | * @return the classname of the test |
---|
128 | */ |
---|
129 | protected static String getTestClassname(String classname) { |
---|
130 | if (!classname.endsWith("Test")) |
---|
131 | return classname + "Test"; |
---|
132 | else |
---|
133 | return classname; |
---|
134 | } |
---|
135 | |
---|
136 | /** |
---|
137 | * returns the test class if it exists, for the given class, otherwise |
---|
138 | * null |
---|
139 | * |
---|
140 | * @param classname the class to retrieve the Test class for |
---|
141 | * @return non-null, if the Test class exists |
---|
142 | */ |
---|
143 | protected static Class testClassFor(String classname) { |
---|
144 | Class result; |
---|
145 | |
---|
146 | result = null; |
---|
147 | |
---|
148 | try { |
---|
149 | result = Class.forName(getTestClassname(classname)); |
---|
150 | } |
---|
151 | catch (Exception e) { |
---|
152 | // ignore it |
---|
153 | } |
---|
154 | |
---|
155 | return result; |
---|
156 | } |
---|
157 | |
---|
158 | /** |
---|
159 | * tries to find Test classes for all the given classnames, if successful |
---|
160 | * they're added to the Test |
---|
161 | * |
---|
162 | * @param classnames the classnames to get |
---|
163 | */ |
---|
164 | protected static TestSuite addAll(Vector classnames) { |
---|
165 | int i; |
---|
166 | Class tc; |
---|
167 | TestSuite result; |
---|
168 | |
---|
169 | result = new TestSuite(); |
---|
170 | |
---|
171 | for (i = 0; i < classnames.size(); i++) { |
---|
172 | tc = testClassFor((String) classnames.get(i)); |
---|
173 | if (tc != null) |
---|
174 | result.addTest(new TestSuite(tc)); |
---|
175 | } |
---|
176 | |
---|
177 | return result; |
---|
178 | } |
---|
179 | |
---|
180 | /** |
---|
181 | * adds all Tests for classes that are available via the |
---|
182 | * GenericPropertiesCreator's property to the Test and returns that |
---|
183 | * |
---|
184 | * @param property the GPC property to add all the classes to the Test |
---|
185 | * @return the generated Test |
---|
186 | * @see GenericPropertiesCreator |
---|
187 | */ |
---|
188 | public static TestSuite addAll(String property) { |
---|
189 | return addAll(getClassnames(property)); |
---|
190 | } |
---|
191 | |
---|
192 | /** |
---|
193 | * adds all available Tests for a given superclass and the packages to |
---|
194 | * check in |
---|
195 | * |
---|
196 | * @param superclass the superclass to find tests of subclasses for |
---|
197 | * @param packages the packages (strings) to search in |
---|
198 | * @return the generated Test |
---|
199 | */ |
---|
200 | public static TestSuite addAll(String superclass, Vector packages) { |
---|
201 | return addAll(getClassnames(superclass, packages)); |
---|
202 | } |
---|
203 | |
---|
204 | /** |
---|
205 | * determines all the test classes that are missing for the given |
---|
206 | * classnames. |
---|
207 | * |
---|
208 | * @param classnames the classnames that are to be checked |
---|
209 | * @return the missing Test classes |
---|
210 | */ |
---|
211 | protected static Vector getMissing(Vector classnames) { |
---|
212 | int i; |
---|
213 | Vector result; |
---|
214 | |
---|
215 | result = new Vector(); |
---|
216 | |
---|
217 | for (i = 0; i < classnames.size(); i++) { |
---|
218 | if (testClassFor((String) classnames.get(i)) == null) |
---|
219 | result.add(getTestClassname((String) classnames.get(i))); |
---|
220 | } |
---|
221 | |
---|
222 | return result; |
---|
223 | } |
---|
224 | |
---|
225 | /** |
---|
226 | * determines all the test classes that are missing for the given |
---|
227 | * GenericPropertiesCreator's property's elements |
---|
228 | * |
---|
229 | * @param property the GPC property to determine the missing Tests for |
---|
230 | * @return the classnames of the missing Tests |
---|
231 | */ |
---|
232 | public static Vector getMissing(String property) { |
---|
233 | return getMissing(getClassnames(property)); |
---|
234 | } |
---|
235 | |
---|
236 | /** |
---|
237 | * determines all the test classes of subclasses that are missing for the |
---|
238 | * given superclass and packages to look in for |
---|
239 | * |
---|
240 | * @param superclass the superclass to check for tests of derived classes |
---|
241 | * @param packages the packages to search in |
---|
242 | * @return the classnames of the missing Tests |
---|
243 | */ |
---|
244 | public static Vector getMissing(String superclass, Vector packages) { |
---|
245 | return getMissing(getClassnames(superclass, packages)); |
---|
246 | } |
---|
247 | |
---|
248 | /** |
---|
249 | * outputs the missing Test classes (if any) and returns the given TestSuite |
---|
250 | * |
---|
251 | * @param t the generated test suite, is only passed through |
---|
252 | * @param missing the missing test classes, if any |
---|
253 | * @return the previously generate test suite |
---|
254 | */ |
---|
255 | protected static Test suite(Test t, Vector missing) { |
---|
256 | if (missing.size() > 0) { |
---|
257 | Collections.sort(missing); |
---|
258 | |
---|
259 | System.out.println("Missing Test classes:"); |
---|
260 | for (int i = 0; i < missing.size(); i++) |
---|
261 | System.out.println("- " + missing.get(i)); |
---|
262 | System.out.println(); |
---|
263 | } |
---|
264 | |
---|
265 | return t; |
---|
266 | } |
---|
267 | |
---|
268 | /** |
---|
269 | * Generates a TestSuite for the given GenericPropertiesCreator property |
---|
270 | * and returns it. Potentially missing test classes are output. |
---|
271 | * |
---|
272 | * @param property the GPC property to generate a test suite from |
---|
273 | * @return the generated test suite |
---|
274 | */ |
---|
275 | public static Test suite(String property) { |
---|
276 | return suite(addAll(property), getMissing(property)); |
---|
277 | } |
---|
278 | |
---|
279 | /** |
---|
280 | * Generates a TestSuite for all the Test class of subclasses of the given |
---|
281 | * superclasses. The given package names are used in the search. |
---|
282 | * Potentially missing test classes are output. |
---|
283 | * |
---|
284 | * @param superclass the class to generate the test suite for |
---|
285 | * @param packages the packages to look for test classes |
---|
286 | * @return the generated test suite |
---|
287 | */ |
---|
288 | public static Test suite(String superclass, Vector packages) { |
---|
289 | return suite(addAll(superclass, packages), getMissing(superclass, packages)); |
---|
290 | } |
---|
291 | } |
---|