001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.lang.exception;
018:
019: import java.io.ByteArrayOutputStream;
020: import java.io.PrintStream;
021: import java.io.PrintWriter;
022:
023: import junit.framework.TestCase;
024:
025: /**
026: * Tests implementations of the org.apache.commons.lang.exception.Nestable
027: * interface.
028: *
029: * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
030: * @version $Id: AbstractNestableTestCase.java 437554 2006-08-28 06:21:41Z bayard $
031: */
032: public abstract class AbstractNestableTestCase extends TestCase {
033:
034: /**
035: * Constructs an instance of
036: * <code>AbstractNestableTestCase</code>.
037: *
038: * @param name the test name
039: */
040: public AbstractNestableTestCase(String name) {
041: super (name);
042: }
043:
044: /**
045: * Tests the getCause() operation.
046: */
047: public void testGetCause() {
048: Nestable ne1 = getNestable();
049: assertNull("nestable exception() cause is null", ne1.getCause());
050:
051: Nestable ne2 = getNestable("ne2");
052: assertNull("nestable exception(\"ne2\") cause is null", ne2
053: .getCause());
054:
055: Nestable ne3 = getNestable(getThrowable("ne3 exception"));
056: assertNotNull(
057: "nestable exception(Throwable(\"ne3 exception\") cause is not null",
058: ne3.getCause());
059: assertTrue(
060: "nestable exception(Throwable(\"ne3 exception\") cause message == ne3 exception",
061: ne3.getCause().getMessage().equals("ne3 exception"));
062:
063: Nestable ne4 = getNestable("ne4", getThrowable("ne4 exception"));
064: assertNotNull(
065: "nestable exception(\"ne4\", Throwable(\"ne4 exception\") cause is not null",
066: ne4.getCause());
067:
068: Nestable ne5 = getNestable("ne5", (Throwable) null);
069: assertNull("nestable exception(\"ne5\", null) cause is null",
070: ne5.getCause());
071:
072: Nestable ne6 = getNestable(null, getThrowable("ne6 exception"));
073: assertNotNull(
074: "nestable exception(null, Throwable(\"ne6 exception\") cause is not null",
075: ne6.getCause());
076: }
077:
078: /**
079: * Tests the getThrowableCount() operation.
080: */
081: public void testGetThrowableCount() {
082: Nestable ne1 = getNestable();
083: assertEquals("ne1 throwable count", 1, ne1.getThrowableCount());
084:
085: Nestable ne2 = getNestable("ne2");
086: assertEquals("ne2 throwable count", 1, ne2.getThrowableCount());
087:
088: Nestable ne3 = getNestable(getThrowable("ne3 exception"));
089: assertEquals("ne3 throwable count", 2, ne3.getThrowableCount());
090:
091: Nestable ne4 = getNestable("ne4", getThrowable("ne4 exception"));
092: assertEquals("ne4 throwable count", 2, ne4.getThrowableCount());
093:
094: Nestable ne5 = getNestable("ne5", (Throwable) null);
095: assertEquals("ne 5 throwable count", 1, ne5.getThrowableCount());
096:
097: Nestable ne6 = getNestable(null, getThrowable("ne6 exception"));
098: assertEquals("ne 6 throwable count", 2, ne6.getThrowableCount());
099:
100: Nestable ne7 = getNestable("ne7o", getNestable("ne7i",
101: getThrowable("ne7 exception")));
102: assertEquals("ne 7 throwable count", 3, ne7.getThrowableCount());
103:
104: Nestable ne8 = getNestable("level 1", getNestable("level 2",
105: getNestable(getNestable("level 4",
106: getThrowable("level 5")))));
107: assertEquals("ne 8 throwable count", 5, ne8.getThrowableCount());
108: }
109:
110: /**
111: * Tests the getMessage() operation.
112: */
113: public void testGetMessage() {
114: Nestable ne1 = getNestable();
115: assertNull("nestable exception() message is null", ne1
116: .getMessage());
117:
118: Nestable ne2 = getNestable("ne2");
119: assertNotNull(
120: "nestable exception(\"ne2\") message is not null", ne2
121: .getMessage());
122: assertEquals("nestable exception(\"ne2\") message == ne2", ne2
123: .getMessage(), "ne2");
124:
125: Nestable ne3 = getNestable(getThrowable("ne3 exception"));
126: assertNotNull(
127: "nestable exception(Throwable(\"ne3 exception\") message is not null",
128: ne3.getMessage());
129: assertEquals(
130: "nestable exception(Throwable(\"ne3 exception\") message equals cause.toString()",
131: ne3.getMessage(), ne3.getCause().toString());
132:
133: Nestable ne4 = getNestable("ne4", getThrowable("ne4 exception"));
134: assertNotNull(
135: "nestable exception(\"ne4\", Throwable(\"ne4 exception\") message is not null",
136: ne4.getMessage());
137: assertEquals(
138: "nestable exception(\"ne4\", Throwable(\"ne4 exception\") message == ne4",
139: ne4.getMessage(), "ne4");
140:
141: Nestable ne5 = getNestable("ne5", (Throwable) null);
142: assertNotNull(
143: "nestable exception(\"ne5\", null) message is not null",
144: ne5.getMessage());
145: assertEquals(
146: "nestable exception(\"ne5\", null) message == ne5", ne5
147: .getMessage(), "ne5");
148:
149: Throwable t6 = getThrowable("ne6 exception");
150: Nestable ne6 = getNestable(null, t6);
151: assertNotNull(
152: "nestable exception(null, Throwable(\"ne6 exception\") message is not null",
153: ne6.getMessage());
154: assertEquals(
155: "nestable exception(null, Throwable(\"ne6 exception\") message equals cause.toString()",
156: ne6.getMessage(), ne6.getCause().toString());
157:
158: Nestable ne7 = getNestable("ne7o", getNestable("ne7i",
159: getThrowable("ne7 exception")));
160: assertEquals(
161: "nestable exception(\"ne7o\", getNestable(\"ne7i\", Throwable(\"ne7 exception\"))) message is ne7o: ne7i: ne7 exception",
162: ne7.getMessage(), "ne7o");
163:
164: Nestable ne8 = getNestable();
165: assertNull("nestable exception() message is null", ne8
166: .getMessage());
167:
168: }
169:
170: /**
171: * Tests the getMessage(int) operation.
172: */
173: public void testGetMessageI() {
174: String[] msgs = new String[5];
175: msgs[0] = "level 1";
176: msgs[1] = "level 2";
177: msgs[2] = null;
178: msgs[3] = "level 4";
179: msgs[4] = "level 5";
180: Nestable ne = getNestable(msgs[0],
181: getNestable(msgs[1], getNestable(getNestable(msgs[3],
182: getThrowable(msgs[4])))));
183: for (int i = 0; i < msgs.length; i++) {
184: assertEquals("message " + i, msgs[i], ne.getMessage(i));
185: }
186:
187: // Test for index out of bounds
188: try {
189: String msg = ne.getMessage(-1);
190: fail("getMessage(-1) should have thrown IndexOutOfBoundsException");
191: } catch (IndexOutOfBoundsException ioode) {
192: }
193: try {
194: String msg = ne.getMessage(msgs.length + 100);
195: fail("getMessage(999) should have thrown IndexOutOfBoundsException");
196: } catch (IndexOutOfBoundsException ioode) {
197: }
198: }
199:
200: /**
201: * Tests the getMessages() operation.
202: */
203: public void testGetMessages() {
204: String[] msgs = new String[5];
205: msgs[0] = "level 1";
206: msgs[1] = "level 2";
207: msgs[2] = null;
208: msgs[3] = "level 4";
209: msgs[4] = "level 5";
210: Nestable ne = getNestable(msgs[0],
211: getNestable(msgs[1], getNestable(getNestable(msgs[3],
212: getThrowable(msgs[4])))));
213: String[] nMsgs = ne.getMessages();
214: assertEquals("messages length", msgs.length, nMsgs.length);
215: for (int i = 0; i < nMsgs.length; i++) {
216: assertEquals("message " + i, msgs[i], nMsgs[i]);
217: }
218: }
219:
220: /**
221: * Tests the getThrowable(int) operation.
222: */
223: public void testGetThrowableI() {
224: Nestable n = null;
225: String msgs[] = null;
226: Class[] throwables = null;
227:
228: msgs = new String[2];
229: msgs[0] = null;
230: msgs[1] = "level 2";
231: throwables = new Class[2];
232: throwables[0] = getTester1Class();
233: throwables[1] = getThrowableClass();
234: n = getTester1(getThrowable(msgs[1]));
235: doNestableExceptionGetThrowableI(n, throwables, msgs);
236:
237: msgs = new String[5];
238: msgs[0] = "level 1";
239: msgs[1] = "level 2";
240: msgs[2] = null;
241: msgs[3] = "level 4";
242: msgs[4] = "level 5";
243: throwables = new Class[5];
244: throwables[0] = getTester1Class();
245: throwables[1] = getTester2Class();
246: throwables[2] = getTester1Class();
247: throwables[3] = getTester2Class();
248: throwables[4] = getThrowableClass();
249: n = getTester1(msgs[0], getTester2(msgs[1],
250: getTester1(getTester2(msgs[3], getThrowable(msgs[4])))));
251: doNestableExceptionGetThrowableI(n, throwables, msgs);
252: }
253:
254: private void doNestableExceptionGetThrowableI(Nestable n,
255: Class[] classes, String[] msgs) {
256: Throwable t = null;
257: String msg = null;
258:
259: for (int i = 0; i < classes.length; i++) {
260: t = n.getThrowable(i);
261: assertEquals("throwable class", classes[i], t.getClass());
262: if (Nestable.class.isInstance(t)) {
263: msg = ((Nestable) t).getMessage(0);
264: } else {
265: msg = t.getMessage();
266: }
267: assertEquals("throwable message", msgs[i], msg);
268: }
269:
270: // Test for index out of bounds
271: try {
272: t = n.getThrowable(-1);
273: fail("getThrowable(-1) should have thrown IndexOutOfBoundsException");
274: } catch (IndexOutOfBoundsException ioobe) {
275: }
276: try {
277: t = n.getThrowable(999);
278: fail("getThrowable(999) should have thrown IndexOutOfBoundsException");
279: } catch (IndexOutOfBoundsException ioobe) {
280: }
281: }
282:
283: /**
284: * Tests the getThrowables() operation.
285: */
286: public void testGetThrowables() {
287: Nestable n = null;
288: String msgs[] = null;
289: Class[] throwables = null;
290:
291: msgs = new String[2];
292: msgs[0] = null;
293: msgs[1] = "level 2";
294: throwables = new Class[2];
295: throwables[0] = getTester1Class();
296: throwables[1] = getThrowableClass();
297: n = getTester1(getThrowable(msgs[1]));
298: doNestableExceptionGetThrowables(n, throwables, msgs);
299:
300: msgs = new String[5];
301: msgs[0] = "level 1";
302: msgs[1] = "level 2";
303: msgs[2] = null;
304: msgs[3] = "level 4";
305: msgs[4] = "level 5";
306: throwables = new Class[5];
307: throwables[0] = getTester1Class();
308: throwables[1] = getTester2Class();
309: throwables[2] = getTester1Class();
310: throwables[3] = getTester2Class();
311: throwables[4] = getThrowableClass();
312: n = getTester1(msgs[0], getTester2(msgs[1],
313: getTester1(getTester2(msgs[3], getThrowable(msgs[4])))));
314: doNestableExceptionGetThrowables(n, throwables, msgs);
315: }
316:
317: private void doNestableExceptionGetThrowables(Nestable n,
318: Class[] classes, String[] msgs) {
319: String msg = null;
320:
321: Throwable throwables[] = n.getThrowables();
322: assertEquals("throwables length", classes.length,
323: throwables.length);
324: for (int i = 0; i < classes.length; i++) {
325: assertEquals("throwable class", classes[i], throwables[i]
326: .getClass());
327: Throwable t = throwables[i];
328: if (Nestable.class.isInstance(t)) {
329: msg = ((Nestable) t).getMessage(0);
330: } else {
331: msg = t.getMessage();
332: }
333: assertEquals("throwable message", msgs[i], msg);
334: }
335: }
336:
337: /**
338: * Tests the indexOfThrowable() operation.
339: */
340: public void testIndexOfThrowable() {
341: Nestable n = null;
342: String msgs[] = null;
343: Class[] throwables = null;
344:
345: msgs = new String[5];
346: msgs[0] = "level 1";
347: msgs[1] = "level 2";
348: msgs[2] = null;
349: msgs[3] = "level 4";
350: msgs[4] = "level 5";
351: throwables = new Class[5];
352: throwables[0] = getTester1Class();
353: throwables[1] = getTester2Class();
354: throwables[2] = getTester1Class();
355: throwables[3] = getTester2Class();
356: throwables[4] = getThrowableClass();
357: int[] indexes = { 0, 1, 0, 1, 4 };
358: n = getTester1(msgs[0], getTester2(msgs[1],
359: getTester1(getTester2(msgs[3], getThrowable(msgs[4])))));
360: for (int i = 0; i < throwables.length; i++) {
361: doNestableExceptionIndexOfThrowable(n, throwables[i],
362: indexes[i], msgs[indexes[i]]);
363: }
364: doNestableExceptionIndexOfThrowable(n, getBaseThrowableClass(),
365: 0, msgs[0]);
366: doNestableExceptionIndexOfThrowable(n, java.util.Date.class,
367: -1, null);
368: doNestableExceptionIndexOfThrowable(n, null, -1, null);
369: }
370:
371: private void doNestableExceptionIndexOfThrowable(Nestable n,
372: Class type, int expectedIndex, String expectedMsg) {
373: Throwable t = null;
374:
375: int index = n.indexOfThrowable(type);
376: assertEquals("index of throwable "
377: + (type == null ? "null" : type.getName()),
378: expectedIndex, index);
379: if (expectedIndex > -1) {
380: t = n.getThrowable(index);
381: if (expectedMsg != null) {
382: String msg = null;
383: if (Nestable.class.isInstance(t)) {
384: msg = ((Nestable) t).getMessage(0);
385: } else {
386: msg = t.getMessage();
387: }
388: assertEquals("message of indexed throwable",
389: expectedMsg, msg);
390: }
391: }
392: }
393:
394: /**
395: * Tests the indexOfThrowable(int) operation.
396: */
397: public void testIndexOfThrowableI() {
398: Nestable n = null;
399: String msgs[] = null;
400: Class[] throwables = null;
401:
402: msgs = new String[5];
403: msgs[0] = "level 1";
404: msgs[1] = "level 2";
405: msgs[2] = null;
406: msgs[3] = "level 4";
407: msgs[4] = "level 5";
408: throwables = new Class[5];
409: throwables[0] = getTester1Class();
410: throwables[1] = getTester2Class();
411: throwables[2] = getTester1Class();
412: throwables[3] = getTester2Class();
413: throwables[4] = getThrowableClass();
414: int[] indexes = { 0, 1, 0, 1, 4 };
415: n = getTester1(msgs[0], getTester2(msgs[1],
416: getTester1(getTester2(msgs[3], getThrowable(msgs[4])))));
417: for (int i = 0; i < throwables.length; i++) {
418: doNestableExceptionIndexOfThrowableI(n, throwables[i], 0,
419: indexes[i], msgs[indexes[i]]);
420: }
421: doNestableExceptionIndexOfThrowableI(n, getTester2Class(), 2,
422: 3, msgs[3]);
423: doNestableExceptionIndexOfThrowableI(n, getTester1Class(), 1,
424: 2, msgs[2]);
425: doNestableExceptionIndexOfThrowableI(n, getTester1Class(), 3,
426: -1, null);
427: doNestableExceptionIndexOfThrowableI(n, getTester1Class(), 4,
428: -1, null);
429: doNestableExceptionIndexOfThrowableI(n, getThrowableClass(), 2,
430: 4, msgs[4]);
431: doNestableExceptionIndexOfThrowableI(n, java.util.Date.class,
432: 0, -1, null);
433: doNestableExceptionIndexOfThrowableI(n, null, 0, -1, null);
434:
435: // Test for index out of bounds
436: try {
437: int index = n.indexOfThrowable(getTester1Class(), -1);
438: fail("method should have thrown IndexOutOfBoundsException");
439: } catch (IndexOutOfBoundsException iooob) {
440: }
441: try {
442: int index = n.indexOfThrowable(getTester1Class(), 5);
443: fail("method should have thrown IndexOutOfBoundsException");
444: } catch (IndexOutOfBoundsException iooob) {
445: }
446:
447: }
448:
449: private void doNestableExceptionIndexOfThrowableI(Nestable n,
450: Class type, int fromIndex, int expectedIndex,
451: String expectedMsg) {
452: Throwable t = null;
453:
454: int index = n.indexOfThrowable(type, fromIndex);
455: assertEquals("index of throwable "
456: + (type == null ? "null" : type.getName()),
457: expectedIndex, index);
458: if (expectedIndex > -1) {
459: t = n.getThrowable(index);
460: if (expectedMsg != null) {
461: String msg = null;
462: if (Nestable.class.isInstance(t)) {
463: msg = ((Nestable) t).getMessage(0);
464: } else {
465: msg = t.getMessage();
466: }
467: assertEquals("message of indexed throwable",
468: expectedMsg, msg);
469: }
470: }
471:
472: }
473:
474: /**
475: * Tests the printPartialStackTrace() operation.
476: */
477: public void testPrintPartialStackTrace() {
478: Nestable ne9 = getNestable("ne9", getThrowable("ne9 exception"));
479: ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
480: PrintStream ps2 = new PrintStream(baos2);
481: PrintWriter pw2 = new PrintWriter(ps2, true);
482: ne9.printPartialStackTrace(pw2);
483: String stack2 = baos2.toString();
484: String startsWith = ne9.getClass().getName() + ": ne9";
485: assertTrue("stack trace startsWith == " + startsWith, stack2
486: .startsWith(startsWith));
487: assertEquals("stack trace indexOf rethrown == -1", stack2
488: .indexOf("rethrown"), -1);
489: }
490:
491: /**
492: * Tests the printStackTrace() operation.
493: */
494: public void testPrintStackTrace() {
495: Nestable ne8 = getNestable("ne8", getThrowable("ne8 exception"));
496: ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
497: PrintStream ps1 = new PrintStream(baos1);
498: PrintWriter pw1 = new PrintWriter(ps1, true);
499: ne8.printStackTrace(pw1);
500: String stack1 = baos1.toString();
501: String startsWith = ne8.getClass().getName() + ": ne8";
502: assertTrue("stack trace startsWith == " + startsWith, stack1
503: .startsWith(startsWith));
504: String indexOf = getThrowableClass().getName()
505: + ": ne8 exception";
506: assertTrue("stack trace indexOf " + indexOf + " > -1", stack1
507: .indexOf(indexOf) > -1);
508: }
509:
510: /**
511: * Returns an instance of the <code>Nestable</code> implementation being
512: * tested.
513: *
514: * @return the instance
515: */
516: public abstract Nestable getNestable();
517:
518: /**
519: * Returns an instance of the <code>Nestable</code> implementation being
520: * tested.
521: *
522: * @param n <code>Nestable</code> argument to be provided to the instance
523: * constructor
524: * @return the instance
525: */
526: public abstract Nestable getNestable(Nestable n);
527:
528: /**
529: * Returns an instance of the <code>Nestable</code> implementation being
530: * tested.
531: *
532: * @param msg <code>String</code> argument to be provided to the instance
533: * constructor
534: * @return the instance
535: */
536: public abstract Nestable getNestable(String msg);
537:
538: /**
539: * Returns an instance of the <code>Nestable</code> implementation being
540: * tested.
541: *
542: * @param msg <code>String</code> argument to be provided to the instance
543: * constructor
544: * @param n <code>Nestable</code> argument to be provided to the instance
545: * constructor
546: * @return the instance
547: */
548: public abstract Nestable getNestable(String msg, Nestable n);
549:
550: /**
551: * Returns an instance of the <code>Nestable</code> implementation being
552: * tested.
553: *
554: * @param msg <code>String</code> argument to be provided to the instance
555: * constructor
556: * @param t <code>Throwable</code> argument to be provided to the instance
557: * constructor
558: * @return the instance
559: */
560: public abstract Nestable getNestable(String msg, Throwable t);
561:
562: /**
563: * Returns an instance of the <code>Nestable</code> implementation being
564: * tested.
565: *
566: * @param t <code>Throwable</code> argument to be provided to the instance
567: * constructor
568: * @return the instance
569: */
570: public abstract Nestable getNestable(Throwable t);
571:
572: /**
573: * Returns an instance of a <code>Throwable</code> to be used in
574: * constructing instances of the <code>Nestable</code> implementation being
575: * tested.
576: *
577: * @param msg <code>String</code> argument to be provided to the instance
578: * constructor
579: * @return the instance
580: */
581: public abstract Throwable getThrowable(String msg);
582:
583: /**
584: * Returns an instance of one tester <code>Nestable</code> implementation.
585: *
586: * @param n <code>Nestable</code> argument to be provided to the instance
587: * constructor
588: * @return the instance
589: */
590: public abstract Nestable getTester1(Nestable n);
591:
592: /**
593: * Returns an instance of one tester <code>Nestable</code> implementation.
594: *
595: * @param t <code>Throwable</code> argument to be provided to the instance
596: * constructor
597: * @return the instance
598: */
599: public abstract Nestable getTester1(Throwable t);
600:
601: /**
602: * Returns an instance of one tester <code>Nestable</code> implementation.
603: *
604: * @param msg <code>String</code> argument to be provided to the instance
605: * constructor
606: * @param n <code>Nestable</code> argument to be provided to the instance
607: * constructor
608: * @return the instance
609: */
610: public abstract Nestable getTester1(String msg, Nestable n);
611:
612: /**
613: * Returns an instance of one tester <code>Nestable</code> implementation.
614: *
615: * @param msg <code>String</code> argument to be provided to the instance
616: * constructor
617: * @param t <code>Throwable</code> argument to be provided to the instance
618: * constructor
619: * @return the instance
620: */
621: public abstract Nestable getTester1(String msg, Throwable t);
622:
623: /**
624: * Returns an instance of a second tester <code>Nestable</code>
625: * implementation.
626: *
627: * @param msg <code>String</code> argument to be provided to the instance
628: * constructor
629: * @param n <code>Nestable</code> argument to be provided to the instance
630: * constructor
631: * @return the instance
632: */
633: public abstract Nestable getTester2(String msg, Nestable n);
634:
635: /**
636: * Returns an instance of a second tester <code>Nestable</code>
637: * implementation.
638: *
639: * @param msg <code>String</code> argument to be provided to the instance
640: * constructor
641: * @param t <code>Throwable</code> argument to be provided to the instance
642: * constructor
643: * @return the instance
644: */
645: public abstract Nestable getTester2(String msg, Throwable t);
646:
647: /**
648: * Returns the class of the first tester <code>Nestable</code>
649: * implementation.
650: *
651: * @return the class
652: */
653: public abstract Class getTester1Class();
654:
655: /**
656: * Returns the class of the second tester <code>Nestable</code>
657: * implementation.
658: *
659: * @return the class
660: */
661: public abstract Class getTester2Class();
662:
663: /**
664: * Returns the class of the <code>Throwable</code> used in constructing
665: * instances of the <code>Nestable</code> implementation being tested.
666: *
667: * @return the class
668: */
669: public abstract Class getThrowableClass();
670:
671: /**
672: * Returns the base class being used, typically Error, Eception or RuntimeException.
673: *
674: * @return the class
675: */
676: public abstract Class getBaseThrowableClass();
677:
678: }
|