KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > activemq > CombinationTestSupport


1 /**
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one or more
4  * contributor license agreements. See the NOTICE file distributed with
5  * this work for additional information regarding copyright ownership.
6  * The ASF licenses this file to You under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with
8  * the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package org.apache.activemq;
19
20 import java.lang.reflect.Field JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22 import java.lang.reflect.Modifier JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Arrays JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.LinkedHashSet JavaDoc;
29 import java.util.LinkedList JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32
33 import junit.framework.Test;
34 import junit.framework.TestSuite;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38
39 /**
40  * Poor mans way of getting JUnit to run a test case through a few different
41  * combinations of options.
42  *
43  *
44  * Usage: If you have a test case called testFoo what you want to run through a
45  * few combinations, of of values for the attributes age and color, you would
46  * something like: <code>
47  * public void initCombosForTestFoo() {
48  * addCombinationValues( "age", new Object[]{ new Integer(21), new Integer(30) } );
49  * addCombinationValues( "color", new Object[]{"blue", "green"} );
50  * }
51  * </code>
52  *
53  * The testFoo test case would be run for each possible combination of age and
54  * color that you setup in the initCombosForTestFoo method. Before each combination is
55  * run, the age and color fields of the test class are set to one of the values
56  * defined. This is done before the normal setUp method is called.
57  *
58  * If you want the test combinations to show up as separate test runs in the
59  * JUnit reports, add a suite method to your test case similar to:
60  *
61  * <code>
62  * public static Test suite() {
63  * return suite(FooTest.class);
64  * }
65  * </code>
66  *
67  * @version $Revision: 1.5 $
68  */

69 public abstract class CombinationTestSupport extends AutoFailTestSupport {
70
71     protected static final Log log = LogFactory.getLog(CombinationTestSupport.class);
72     
73     private HashMap JavaDoc comboOptions = new HashMap JavaDoc();
74     private boolean combosEvaluated;
75     private Map JavaDoc options;
76
77     static class ComboOption {
78         final String JavaDoc attribute;
79         final LinkedHashSet JavaDoc values = new LinkedHashSet JavaDoc();
80
81         public ComboOption(String JavaDoc attribute, Collection JavaDoc options) {
82             this.attribute = attribute;
83             this.values.addAll(options);
84         }
85     }
86
87     public void addCombinationValues(String JavaDoc attribute, Object JavaDoc[] options) {
88         ComboOption co = (ComboOption) this.comboOptions.get(attribute);
89         if (co == null) {
90             this.comboOptions.put(attribute, new ComboOption(attribute, Arrays.asList(options)));
91         } else {
92             co.values.addAll(Arrays.asList(options));
93         }
94     }
95
96     public void runBare() throws Throwable JavaDoc {
97         if (combosEvaluated) {
98             super.runBare();
99         } else {
100             CombinationTestSupport[] combinations = getCombinations();
101             for (int i = 0; i < combinations.length; i++) {
102                 CombinationTestSupport test = combinations[i];
103                 log.info("Running " + test.getName());
104                 test.runBare();
105             }
106         }
107     }
108
109     private void setOptions(Map JavaDoc options) throws NoSuchFieldException JavaDoc, IllegalAccessException JavaDoc {
110         this.options = options;
111         for (Iterator JavaDoc iterator = options.keySet().iterator(); iterator.hasNext();) {
112             String JavaDoc attribute = (String JavaDoc) iterator.next();
113             Object JavaDoc value = options.get(attribute);
114             try {
115                 Field JavaDoc field = getClass().getField(attribute);
116                 field.set(this, value);
117             } catch (Throwable JavaDoc e) {
118                 log.info("Could not set field '" + attribute + "' to value '" + value
119                         + "', make sure the field exists and is public.");
120             }
121         }
122     }
123
124     private CombinationTestSupport[] getCombinations() {
125         try {
126             Method JavaDoc method = getClass().getMethod("initCombos", null);
127             method.invoke(this, null);
128         } catch (Throwable JavaDoc e) {
129         }
130         
131         String JavaDoc name = getName();
132         String JavaDoc comboSetupMethodName = "initCombosFor" + Character.toUpperCase(name.charAt(0)) + name.substring(1);
133         try {
134             Method JavaDoc method = getClass().getMethod(comboSetupMethodName, null);
135             method.invoke(this, null);
136         } catch (Throwable JavaDoc e) {
137         }
138
139         try {
140             ArrayList JavaDoc expandedOptions = new ArrayList JavaDoc();
141             expandCombinations(new ArrayList JavaDoc(comboOptions.values()), expandedOptions);
142     
143             if (expandedOptions.isEmpty()) {
144                 combosEvaluated = true;
145                 return new CombinationTestSupport[] { this };
146             } else {
147     
148                 ArrayList JavaDoc result = new ArrayList JavaDoc();
149                 // Run the test case for each possible combination
150
for (Iterator JavaDoc iter = expandedOptions.iterator(); iter.hasNext();) {
151                     CombinationTestSupport combo = (CombinationTestSupport) TestSuite.createTest(getClass(), getName());
152                     combo.combosEvaluated = true;
153                     combo.setOptions((Map JavaDoc) iter.next());
154                     result.add(combo);
155                 }
156     
157                 CombinationTestSupport rc[] = new CombinationTestSupport[result.size()];
158                 result.toArray(rc);
159                 return rc;
160             }
161         } catch (Throwable JavaDoc e) {
162             combosEvaluated = true;
163             return new CombinationTestSupport[] { this };
164         }
165
166     }
167
168     private void expandCombinations(List JavaDoc optionsLeft, List JavaDoc expandedCombos) {
169         if (!optionsLeft.isEmpty()) {
170             HashMap JavaDoc map;
171             if (comboOptions.size() == optionsLeft.size()) {
172                 map = new HashMap JavaDoc();
173                 expandedCombos.add(map);
174             } else {
175                 map = (HashMap JavaDoc) expandedCombos.get(expandedCombos.size() - 1);
176             }
177
178             LinkedList JavaDoc l = new LinkedList JavaDoc(optionsLeft);
179             ComboOption comboOption = (ComboOption) l.removeLast();
180             int i = 0;
181             for (Iterator JavaDoc iter = comboOption.values.iterator(); iter.hasNext();) {
182                 Object JavaDoc value = (Object JavaDoc) iter.next();
183                 if (i != 0) {
184                     map = new HashMap JavaDoc(map);
185                     expandedCombos.add(map);
186                 }
187                 map.put(comboOption.attribute, value);
188                 expandCombinations(l, expandedCombos);
189                 i++;
190             }
191         }
192     }
193
194     public static Test suite(Class JavaDoc clazz) {
195         TestSuite suite = new TestSuite();
196
197         ArrayList JavaDoc names = new ArrayList JavaDoc();
198         Method JavaDoc[] methods = clazz.getMethods();
199         for (int i = 0; i < methods.length; i++) {
200             String JavaDoc name = methods[i].getName();
201             if (names.contains(name) || !isPublicTestMethod(methods[i]))
202                 continue;
203             names.add(name);
204             Test test = TestSuite.createTest(clazz, name);
205             if (test instanceof CombinationTestSupport) {
206                 CombinationTestSupport[] combinations = ((CombinationTestSupport) test).getCombinations();
207                 for (int j = 0; j < combinations.length; j++) {
208                     suite.addTest(combinations[j]);
209                 }
210             } else {
211                 suite.addTest(test);
212             }
213         }
214         return suite;
215     }
216
217     static private boolean isPublicTestMethod(Method JavaDoc m) {
218         return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
219     }
220
221     static private boolean isTestMethod(Method JavaDoc m) {
222         String JavaDoc name = m.getName();
223         Class JavaDoc[] parameters = m.getParameterTypes();
224         Class JavaDoc returnType = m.getReturnType();
225         return parameters.length == 0 && name.startsWith("test") && returnType.equals(Void.TYPE);
226     }
227
228     public String JavaDoc getName() {
229         if (options != null) {
230             return super.getName() + " " + options;
231         }
232         return super.getName();
233     }
234 }
235
Popular Tags