001: /* Copyright 2000 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.lang;
007:
008: import java.lang.reflect.Constructor;
009: import java.lang.reflect.Method;
010: import junit.framework.TestCase;
011:
012: /**
013: * <p>The <code>ChainedThrowable_Test</code> class tests the basic operation
014: * of the <code>ChainedException</code> instances.</p>
015: *
016: * @author <a href="mailto:jnielsen@sct.com">Jan Nielsen</a>
017: *
018: * @version "$Revision: 35984 $"
019: **/
020: public class ChainedThrowable_Test extends TestCase {
021: /** <p> Class version identifier.</p> */
022: public static final String RCS_ID = "@(#) $Header$";
023:
024: /**
025: * Run all the test cases defined in the class.
026: *
027: * @param args not used
028: **/
029: public static void main(String[] args) {
030: junit.textui.TestRunner.run(suite());
031: }
032:
033: /**
034: * Build a test suite using reflection.
035: *
036: * @return test suite for the class
037: **/
038: public static junit.framework.TestSuite suite() {
039: return new junit.framework.TestSuite(
040: ChainedThrowable_Test.class);
041: }
042:
043: /**
044: * Setup for each test method.
045: **/
046: public void setUp() {
047: }
048:
049: /**
050: * Tear down for each test method.
051: **/
052: public void tearDown() {
053: }
054:
055: public ChainedThrowable_Test(String name) {
056: super (name);
057: }
058:
059: public static void test() throws Exception {
060: test(ChainedException.class);
061: test(ChainedRuntimeException.class);
062: test(ChainedError.class);
063: }
064:
065: private static void test(Class throwable) throws Exception {
066: // set of tested messages
067: String[] messages = new String[] { null, "",
068: "An error message." };
069:
070: // set of tested throwables
071: Throwable[] throwables = new Throwable[] {
072: null,
073: new Error(),
074: new Exception(),
075: new RuntimeException(),
076: (Throwable) throwable.getDeclaredConstructor(
077: (Class[]) null).newInstance((Object[]) null) };
078:
079: Constructor[] constructors = throwable
080: .getDeclaredConstructors();
081: for (int k = 0; k < constructors.length; k++) {
082: // loop through all combinations of messages and throwables
083: for (int j = 0; j < throwables.length; j++) {
084: for (int i = 0; i < messages.length; i++) {
085: Class[] parameterTypes = constructors[k]
086: .getParameterTypes();
087: Object[] parameterValues = null;
088:
089: if (null != parameterTypes) {
090: parameterValues = new Object[parameterTypes.length];
091: for (int p = 0; p < parameterValues.length; p++) {
092: if (parameterTypes[p].equals(String.class)) {
093: parameterValues[p] = messages[i];
094: } else if (parameterTypes[p]
095: .equals(Throwable.class)) {
096: parameterValues[p] = throwables[j];
097: } else {
098: parameterValues[p] = null;
099: }
100: }
101: }
102:
103: Constructor constructor = throwable
104: .getDeclaredConstructor(parameterTypes);
105:
106: Throwable newThrowable = (Throwable) constructor
107: .newInstance(parameterValues);
108:
109: // for each constructed object test its behavior
110: testMethods(newThrowable, parameterValues);
111: }
112: }
113: }
114: }
115:
116: private static String findMessage(Object[] parameterValues) {
117: String outValue = null;
118:
119: for (int i = 0; (null != parameterValues) && (null == outValue)
120: && i < parameterValues.length; i++) {
121: Object value = parameterValues[i];
122:
123: if (parameterValues[i] instanceof String) {
124: outValue = (String) value;
125: }
126: }
127: return outValue;
128: }
129:
130: private static Throwable findCause(Object[] parameterValues) {
131: Throwable outValue = null;
132:
133: for (int i = 0; (null != parameterValues) && (null == outValue)
134: && i < parameterValues.length; i++) {
135: Object value = parameterValues[i];
136:
137: if (parameterValues[i] instanceof Throwable) {
138: outValue = (Throwable) value;
139: }
140: }
141: return outValue;
142: }
143:
144: private static void testMethods(Throwable throwable,
145: Object[] parameterValues) throws Exception {
146: Method getMessage = throwable.getClass().getMethod(
147: "getMessage", (Class[]) null);
148:
149: assertEquals("getMessage should return constructed message",
150: getMessage.invoke(throwable, (Object[]) null),//(null == findMessage( parameterValues )) && (null != findCause( parameterValues )) ? findCause( parameterValues ).toString() : findMessage( parameterValues ),
151: getMessage.invoke(throwable, (Object[]) null));
152:
153: Method getCause = throwable.getClass().getMethod("getCause",
154: (Class[]) null);
155:
156: assertEquals("getCause should return constructed value",
157: findCause(parameterValues), getCause.invoke(throwable,
158: (Object[]) null));
159:
160: testPrintStackTrace(throwable, (Throwable) getCause.invoke(
161: throwable, (Object[]) null));
162:
163: /*
164: Method getStackFrames = throwable.getClass().getMethod(
165: "getStackFrames",
166: null
167: );
168:
169: StackFrame[] frames = (StackFrame[])getStackFrames.invoke(
170: throwable,
171: null
172: );
173:
174: // reflection adds additional stack frames, so search for our frame
175: // to start the validation
176: StackFrame frame = findFrame( frames );
177:
178: assertEquals(
179: ChainableThrowable_Test.class.getName(),
180: frame.getClassName()
181: );
182:
183: assertEquals(
184: "test",
185: frame.getMethodName()
186: );
187:
188: if( !frame.getFileName().equals( "ChainableThrowable_Test.java" ) &&
189: !frame.getFileName().equals( "Unknown" ) )
190: {
191: fail(
192: "Expected file name to be either " +
193: "\"ChainableThrowable_Test.java\" or \"Unknown\" not " +
194: frame.getFileName()
195: );
196: }
197:
198: if( !frame.getLineNumber().equals( "143" ) &&
199: !frame.getLineNumber().equals( "Unknown" ) )
200: {
201: fail(
202: "Expected line number to be either \"143\" or " +
203: "\"Unknown\" not " + frames[1].getLineNumber()
204: );
205: }
206: */
207: }
208:
209: /*
210: private static StackFrame findFrame( StackFrame[] frames )
211: {
212: StackFrame frame = null;
213:
214: for( int i = 0; i < frames.length; i++ )
215: {
216: frame = frames[i];
217:
218: if( frame.getClassName().equals( ChainableThrowable_Test.class.getName() ) )
219: {
220: break;
221: }
222: }
223:
224: return frame;
225: }
226: */
227:
228: private static void testPrintStackTrace(Throwable throwable,
229: Throwable cause) throws Exception {
230: java.io.StringWriter writer = new java.io.StringWriter();
231: java.io.PrintWriter printWriter = new java.io.PrintWriter(
232: writer);
233:
234: Method printStackTrace_Writer = throwable.getClass().getMethod(
235: "printStackTrace",
236: new Class[] { java.io.PrintWriter.class });
237:
238: try {
239: printStackTrace_Writer.invoke(throwable,
240: new Object[] { printWriter });
241: } catch (java.lang.reflect.InvocationTargetException x) {
242: x.printStackTrace();
243: }
244:
245: String stackTrace = writer.toString();
246:
247: if (null != cause) {
248: String m = cause.toString();
249:
250: int index = stackTrace.indexOf("Caused by: ");
251: /*
252: if( ! (index > 0) )
253: {
254: System.out.println( "jsn: " + stackTrace );
255:
256: throwable.printStackTrace();
257: }
258:
259: assertTrue(
260: "index of 'Caused by: ' should be a positive value but it's " + index + " for Throwable " + throwable + " with cause " + cause,
261: index > 0
262: );
263: */
264: }
265: }
266: }
|