001: /*
002: * ========================================================================
003: *
004: * Copyright 2004 The Apache Software Foundation.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: * ========================================================================
019: */
020: package org.apache.cactus.internal.util;
021:
022: import java.lang.reflect.Method;
023: import java.lang.reflect.Modifier;
024:
025: import junit.framework.Test;
026:
027: import org.apache.cactus.Request;
028:
029: /**
030: * Utilities to check TestCase implementation.
031: * @version $Id: TestCaseImplementChecker.java 238991 2004-05-22 11:34:50Z vmassol $
032: */
033: public final class TestCaseImplementChecker {
034: /**
035: * Default constructor that requires that
036: * {@link #setConfiguration(Configuration)} be called before the methods
037: * requiring a configuration object.
038: *
039: */
040: private TestCaseImplementChecker() {
041: }
042:
043: /**
044: * Check if the Test to run is properly implemented or not.
045: * @param theTest the test to check
046: * @throws TestCaseImplementError if has no name
047: */
048: public static void checkTestName(Test theTest)
049: throws TestCaseImplementError {
050: if (theTest == null) {
051: return;
052: }
053:
054: if (JUnitVersionHelper.getTestCaseName(theTest) == null) {
055: throw new TestCaseImplementError(
056: "No test name found. The test ["
057: + theTest.getClass().getName()
058: + "] is not properly implemented.");
059: }
060: }
061:
062: /**
063: * @param theNum the number
064: * @return a numeric expresion of theNum
065: */
066: private static String numeric(int theNum) {
067: switch (theNum) {
068: case 1:
069: return "1st";
070: case 2:
071: return "2nd";
072: case 3:
073: return "3rd";
074: default:
075: return (theNum + "th");
076: }
077: }
078:
079: /**
080: * @param theMethod the method to check
081: * @param theType the expected return type
082: * @throws TestCaseImplementError if the return-type is not the one expected
083: */
084: private static void checkReturnType(Method theMethod, Class theType)
085: throws TestCaseImplementError {
086: if (!theMethod.getReturnType().equals(theType)) {
087: throw new TestCaseImplementError("The method ["
088: + theMethod.getName() + "] should return "
089: + theType + " and not ["
090: + theMethod.getReturnType().getName() + "]");
091: }
092: }
093:
094: /**
095: * @param theMethod the method to test
096: * @throws TestCaseImplementError if the method is not public
097: */
098: private static void isPublic(Method theMethod)
099: throws TestCaseImplementError {
100: if (!Modifier.isPublic(theMethod.getModifiers())) {
101: throw new TestCaseImplementError("The method ["
102: + theMethod.getName()
103: + "] should be declared public");
104: }
105: }
106:
107: /**
108: * @param theMethod the method to check
109: * @param theParams the expected parameters for the method
110: * @throws TestCaseImplementError if the number of parameter is not same as
111: * that of expected
112: */
113: private static void checkParameterCount(Method theMethod,
114: Class[] theParams) throws TestCaseImplementError {
115: Class[] parameters = theMethod.getParameterTypes();
116: if (parameters.length != theParams.length) {
117: throw new TestCaseImplementError("The method ["
118: + theMethod.getName() + "] must have "
119: + theParams.length + " parameter(s), " + "but "
120: + parameters.length + " parameter(s) were found");
121: }
122: }
123:
124: /**
125: * @param theMethod the method to check
126: * @param theParams the expected parameters for the method
127: * @throws TestCaseImplementError if the number and type of parameter
128: * are not same as those of expected
129: */
130: private static void checkParameterTypes(Method theMethod,
131: Class[] theParams) throws TestCaseImplementError {
132: checkParameterCount(theMethod, theParams);
133:
134: Class[] parameters = theMethod.getParameterTypes();
135: for (int i = 0; i < parameters.length; i++) {
136: Class expected = theParams[i];
137: Class actual = parameters[i];
138: if (!expected.isAssignableFrom(actual)) {
139: throw new TestCaseImplementError("The method ["
140: + theMethod.getName() + "] must accept ["
141: + expected.getName() + "] as " + numeric(i + 1)
142: + " parameter, but found a ["
143: + actual.getName() + "] parameter instead");
144: }
145: }
146: }
147:
148: /**
149: * Check if the method is suitable for a test/begin/end method.
150: * @param theMethod the method to check
151: * @throws TestCaseImplementError if the method is not suitable
152: * for Cactus test method
153: */
154: private static void checkAsCactusMethod(Method theMethod)
155: throws TestCaseImplementError {
156: checkReturnType(theMethod, Void.TYPE);
157: isPublic(theMethod);
158: }
159:
160: /**
161: * Check if the method is suitable for a begin method.
162: * Throws <code>AssertionFailedError</code> if at least one of following
163: * conditions is failed:
164: * <ul>
165: * <li>return type of the method is void</li>
166: * <li>the method is public</li>
167: * <li>the method accept a parameter of type <code>Request</code></li>
168: * </ul>
169: * @param theMethod the method to check
170: * @throws TestCaseImplementError if the method is not suitable
171: * for Cactus begin method
172: */
173: public static void checkAsBeginMethod(Method theMethod)
174: throws TestCaseImplementError {
175: checkAsCactusMethod(theMethod);
176: checkParameterTypes(theMethod, new Class[] { Request.class });
177: }
178:
179: /**
180: * Check if the method is suitable for a end method.
181: * Throws <code>AssertionFailedError</code> if at least one of following
182: * conditions is failed:
183: * <ul>
184: * <li>return type of the method is void</li>
185: * <li>the method is public</li>
186: * <li>the method accept one parameter</li>
187: * </ul>
188: * @param theMethod the method to check
189: * @throws TestCaseImplementError if the method is not suitable
190: * for Cactus end method
191: */
192: public static void checkAsEndMethod(Method theMethod)
193: throws TestCaseImplementError {
194: checkAsCactusMethod(theMethod);
195: checkParameterCount(theMethod, new Class[] { Object.class });
196: }
197: }
|