1 /*
2 * ========================================================================
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * ========================================================================
20 */
21 package org.apache.cactus.internal.util;
22
23 import java.lang.reflect.Method;
24 import java.lang.reflect.Modifier;
25
26 import junit.framework.Test;
27
28 import org.apache.cactus.Request;
29
30 /**
31 * Utilities to check TestCase implementation.
32 * @version $Id: TestCaseImplementChecker.java 238991 2004-05-22 11:34:50Z vmassol $
33 */
34 public final class TestCaseImplementChecker
35 {
36 /**
37 * Default constructor that requires that
38 * {@link #setConfiguration(Configuration)} be called before the methods
39 * requiring a configuration object.
40 *
41 */
42 private TestCaseImplementChecker()
43 {
44 }
45
46 /**
47 * Check if the Test to run is properly implemented or not.
48 * @param theTest the test to check
49 * @throws TestCaseImplementError if has no name
50 */
51 public static void checkTestName(Test theTest)
52 throws TestCaseImplementError
53 {
54 if (theTest == null)
55 {
56 return;
57 }
58
59 if (JUnitVersionHelper.getTestCaseName(theTest) == null)
60 {
61 throw new TestCaseImplementError("No test name found. The test ["
62 + theTest.getClass().getName()
63 + "] is not properly implemented.");
64 }
65 }
66
67 /**
68 * @param theNum the number
69 * @return a numeric expresion of theNum
70 */
71 private static String numeric(int theNum)
72 {
73 switch(theNum)
74 {
75 case 1: return "1st";
76 case 2: return "2nd";
77 case 3: return "3rd";
78 default: return (theNum + "th");
79 }
80 }
81
82 /**
83 * @param theMethod the method to check
84 * @param theType the expected return type
85 * @throws TestCaseImplementError if the return-type is not the one expected
86 */
87 private static void checkReturnType(Method theMethod, Class theType)
88 throws TestCaseImplementError
89 {
90 if (!theMethod.getReturnType().equals(theType))
91 {
92 throw new TestCaseImplementError("The method ["
93 + theMethod.getName()
94 + "] should return " + theType
95 + " and not [" + theMethod.getReturnType().getName()
96 + "]");
97 }
98 }
99
100 /**
101 * @param theMethod the method to test
102 * @throws TestCaseImplementError if the method is not public
103 */
104 private static void isPublic(Method theMethod)
105 throws TestCaseImplementError
106 {
107 if (!Modifier.isPublic(theMethod.getModifiers()))
108 {
109 throw new TestCaseImplementError("The method ["
110 + theMethod.getName()
111 + "] should be declared public");
112 }
113 }
114
115 /**
116 * @param theMethod the method to check
117 * @param theParams the expected parameters for the method
118 * @throws TestCaseImplementError if the number of parameter is not same as
119 * that of expected
120 */
121 private static void checkParameterCount(Method theMethod, Class[] theParams)
122 throws TestCaseImplementError
123 {
124 Class[] parameters = theMethod.getParameterTypes();
125 if (parameters.length != theParams.length)
126 {
127 throw new TestCaseImplementError("The method ["
128 + theMethod.getName()
129 + "] must have " + theParams.length + " parameter(s), "
130 + "but " + parameters.length + " parameter(s) were found");
131 }
132 }
133
134 /**
135 * @param theMethod the method to check
136 * @param theParams the expected parameters for the method
137 * @throws TestCaseImplementError if the number and type of parameter
138 * are not same as those of expected
139 */
140 private static void checkParameterTypes(Method theMethod, Class[] theParams)
141 throws TestCaseImplementError
142 {
143 checkParameterCount(theMethod, theParams);
144
145 Class[] parameters = theMethod.getParameterTypes();
146 for (int i = 0; i < parameters.length; i++)
147 {
148 Class expected = theParams[i];
149 Class actual = parameters[i];
150 if (!expected.isAssignableFrom(actual))
151 {
152 throw new TestCaseImplementError("The method ["
153 + theMethod.getName()
154 + "] must accept [" + expected.getName() + "] as "
155 + numeric(i + 1)
156 + " parameter, but found a ["
157 + actual.getName() + "] parameter instead");
158 }
159 }
160 }
161
162 /**
163 * Check if the method is suitable for a test/begin/end method.
164 * @param theMethod the method to check
165 * @throws TestCaseImplementError if the method is not suitable
166 * for Cactus test method
167 */
168 private static void checkAsCactusMethod(Method theMethod)
169 throws TestCaseImplementError
170 {
171 checkReturnType(theMethod, Void.TYPE);
172 isPublic(theMethod);
173 }
174
175 /**
176 * Check if the method is suitable for a begin method.
177 * Throws <code>AssertionFailedError</code> if at least one of following
178 * conditions is failed:
179 * <ul>
180 * <li>return type of the method is void</li>
181 * <li>the method is public</li>
182 * <li>the method accept a parameter of type <code>Request</code></li>
183 * </ul>
184 * @param theMethod the method to check
185 * @throws TestCaseImplementError if the method is not suitable
186 * for Cactus begin method
187 */
188 public static void checkAsBeginMethod(Method theMethod)
189 throws TestCaseImplementError
190 {
191 checkAsCactusMethod(theMethod);
192 checkParameterTypes(theMethod, new Class[]{Request.class});
193 }
194
195 /**
196 * Check if the method is suitable for a end method.
197 * Throws <code>AssertionFailedError</code> if at least one of following
198 * conditions is failed:
199 * <ul>
200 * <li>return type of the method is void</li>
201 * <li>the method is public</li>
202 * <li>the method accept one parameter</li>
203 * </ul>
204 * @param theMethod the method to check
205 * @throws TestCaseImplementError if the method is not suitable
206 * for Cactus end method
207 */
208 public static void checkAsEndMethod(Method theMethod)
209 throws TestCaseImplementError
210 {
211 checkAsCactusMethod(theMethod);
212 checkParameterCount(theMethod, new Class[]{Object.class});
213 }
214 }