1 /*
2 * Copyright 2002-2005 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.apache.commons.lang.exception;
17
18 import java.io.ByteArrayOutputStream;
19 import java.io.PrintStream;
20 import java.io.PrintWriter;
21
22 import junit.framework.TestCase;
23 /**
24 * Tests implementations of the org.apache.commons.lang.exception.Nestable
25 * interface.
26 *
27 * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
28 * @version $Id: AbstractNestableTestCase.java 161244 2005-04-14 06:16:36Z ggregory $
29 */
30 public abstract class AbstractNestableTestCase extends TestCase
31 {
32
33 /**
34 * Constructs an instance of
35 * <code>AbstractNestableTestCase</code>.
36 *
37 * @param name the test name
38 */
39 public AbstractNestableTestCase(String name)
40 {
41 super(name);
42 }
43
44 /**
45 * Tests the getCause() operation.
46 */
47 public void testGetCause()
48 {
49 Nestable ne1 = getNestable();
50 assertNull("nestable exception() cause is null", ne1.getCause());
51
52 Nestable ne2 = getNestable("ne2");
53 assertNull("nestable exception(\"ne2\") cause is null", ne2.getCause());
54
55 Nestable ne3 = getNestable(getThrowable("ne3 exception"));
56 assertNotNull("nestable exception(Throwable(\"ne3 exception\") cause is not null",
57 ne3.getCause());
58 assertTrue("nestable exception(Throwable(\"ne3 exception\") cause message == ne3 exception",
59 ne3.getCause().getMessage().equals("ne3 exception"));
60
61 Nestable ne4 = getNestable("ne4", getThrowable("ne4 exception"));
62 assertNotNull("nestable exception(\"ne4\", Throwable(\"ne4 exception\") cause is not null",
63 ne4.getCause());
64
65 Nestable ne5 = getNestable("ne5", (Throwable) null);
66 assertNull("nestable exception(\"ne5\", null) cause is null",
67 ne5.getCause());
68
69 Nestable ne6 = getNestable(null, getThrowable("ne6 exception"));
70 assertNotNull("nestable exception(null, Throwable(\"ne6 exception\") cause is not null",
71 ne6.getCause());
72 }
73
74 /**
75 * Tests the getThrowableCount() operation.
76 */
77 public void testGetThrowableCount()
78 {
79 Nestable ne1 = getNestable();
80 assertEquals("ne1 throwable count", 1, ne1.getThrowableCount());
81
82 Nestable ne2 = getNestable("ne2");
83 assertEquals("ne2 throwable count", 1, ne2.getThrowableCount());
84
85 Nestable ne3 = getNestable(getThrowable("ne3 exception"));
86 assertEquals("ne3 throwable count", 2, ne3.getThrowableCount());
87
88 Nestable ne4 = getNestable("ne4", getThrowable("ne4 exception"));
89 assertEquals("ne4 throwable count", 2, ne4.getThrowableCount());
90
91 Nestable ne5 = getNestable("ne5", (Throwable) null);
92 assertEquals("ne 5 throwable count", 1, ne5.getThrowableCount());
93
94 Nestable ne6 = getNestable(null, getThrowable("ne6 exception"));
95 assertEquals("ne 6 throwable count", 2, ne6.getThrowableCount());
96
97 Nestable ne7 = getNestable("ne7o", getNestable("ne7i", getThrowable("ne7 exception")));
98 assertEquals("ne 7 throwable count", 3, ne7.getThrowableCount());
99
100 Nestable ne8 = getNestable("level 1", getNestable("level 2", getNestable(getNestable("level 4", getThrowable("level 5")))));
101 assertEquals("ne 8 throwable count", 5, ne8.getThrowableCount());
102 }
103
104 /**
105 * Tests the getMessage() operation.
106 */
107 public void testGetMessage()
108 {
109 Nestable ne1 = getNestable();
110 assertNull("nestable exception() message is null", ne1.getMessage());
111
112 Nestable ne2 = getNestable("ne2");
113 assertNotNull("nestable exception(\"ne2\") message is not null", ne2.getMessage());
114 assertEquals("nestable exception(\"ne2\") message == ne2", ne2.getMessage(), "ne2");
115
116 Nestable ne3 = getNestable(getThrowable("ne3 exception"));
117 assertNotNull("nestable exception(Throwable(\"ne3 exception\") message is not null",
118 ne3.getMessage());
119 assertEquals("nestable exception(Throwable(\"ne3 exception\") message equals cause.toString()",
120 ne3.getMessage(), ne3.getCause().toString());
121
122 Nestable ne4 = getNestable("ne4", getThrowable("ne4 exception"));
123 assertNotNull("nestable exception(\"ne4\", Throwable(\"ne4 exception\") message is not null",
124 ne4.getMessage());
125 assertEquals("nestable exception(\"ne4\", Throwable(\"ne4 exception\") message == ne4",
126 ne4.getMessage(), "ne4");
127
128 Nestable ne5 = getNestable("ne5", (Throwable) null);
129 assertNotNull("nestable exception(\"ne5\", null) message is not null",
130 ne5.getMessage());
131 assertEquals("nestable exception(\"ne5\", null) message == ne5",
132 ne5.getMessage(), "ne5");
133
134 Throwable t6 = getThrowable("ne6 exception");
135 Nestable ne6 = getNestable(null, t6);
136 assertNotNull("nestable exception(null, Throwable(\"ne6 exception\") message is not null",
137 ne6.getMessage());
138 assertEquals("nestable exception(null, Throwable(\"ne6 exception\") message equals cause.toString()",
139 ne6.getMessage(), ne6.getCause().toString());
140
141 Nestable ne7 = getNestable("ne7o", getNestable("ne7i", getThrowable("ne7 exception")));
142 assertEquals("nestable exception(\"ne7o\", getNestable(\"ne7i\", Throwable(\"ne7 exception\"))) message is ne7o: ne7i: ne7 exception",
143 ne7.getMessage(), "ne7o");
144
145 Nestable ne8 = getNestable();
146 assertNull("nestable exception() message is null",
147 ne8.getMessage());
148
149 }
150
151 /**
152 * Tests the getMessage(int) operation.
153 */
154 public void testGetMessageI()
155 {
156 String[] msgs = new String[5];
157 msgs[0] = "level 1";
158 msgs[1] = "level 2";
159 msgs[2] = null;
160 msgs[3] = "level 4";
161 msgs[4] = "level 5";
162 Nestable ne = getNestable(msgs[0], getNestable(msgs[1], getNestable(getNestable(msgs[3], getThrowable(msgs[4])))));
163 for(int i = 0; i < msgs.length; i++)
164 {
165 assertEquals("message " + i, msgs[i], ne.getMessage(i));
166 }
167
168 // Test for index out of bounds
169 try
170 {
171 String msg = ne.getMessage(-1);
172 fail("getMessage(-1) should have thrown IndexOutOfBoundsException");
173 }
174 catch(IndexOutOfBoundsException ioode)
175 {
176 }
177 try
178 {
179 String msg = ne.getMessage(msgs.length + 100);
180 fail("getMessage(999) should have thrown IndexOutOfBoundsException");
181 }
182 catch(IndexOutOfBoundsException ioode)
183 {
184 }
185 }
186
187 /**
188 * Tests the getMessages() operation.
189 */
190 public void testGetMessages()
191 {
192 String[] msgs = new String[5];
193 msgs[0] = "level 1";
194 msgs[1] = "level 2";
195 msgs[2] = null;
196 msgs[3] = "level 4";
197 msgs[4] = "level 5";
198 Nestable ne = getNestable(msgs[0], getNestable(msgs[1], getNestable(getNestable(msgs[3], getThrowable(msgs[4])))));
199 String[] nMsgs = ne.getMessages();
200 assertEquals("messages length", msgs.length, nMsgs.length);
201 for(int i = 0; i < nMsgs.length; i++)
202 {
203 assertEquals("message " + i, msgs[i], nMsgs[i]);
204 }
205 }
206
207 /**
208 * Tests the getThrowable(int) operation.
209 */
210 public void testGetThrowableI()
211 {
212 Nestable n = null;
213 String msgs[] = null;
214 Class[] throwables = null;
215
216 msgs = new String[2];
217 msgs[0] = null;
218 msgs[1] = "level 2";
219 throwables = new Class[2];
220 throwables[0] = getTester1Class();
221 throwables[1] = getThrowableClass();
222 n = getTester1(getThrowable(msgs[1]));
223 doNestableExceptionGetThrowableI(n, throwables, msgs);
224
225 msgs = new String[5];
226 msgs[0] = "level 1";
227 msgs[1] = "level 2";
228 msgs[2] = null;
229 msgs[3] = "level 4";
230 msgs[4] = "level 5";
231 throwables = new Class[5];
232 throwables[0] = getTester1Class();
233 throwables[1] = getTester2Class();
234 throwables[2] = getTester1Class();
235 throwables[3] = getTester2Class();
236 throwables[4] = getThrowableClass();
237 n = getTester1(msgs[0], getTester2(msgs[1], getTester1(getTester2(msgs[3], getThrowable(msgs[4])))));
238 doNestableExceptionGetThrowableI(n, throwables, msgs);
239 }
240
241 private void doNestableExceptionGetThrowableI(Nestable n, Class[] classes, String[] msgs)
242 {
243 Throwable t = null;
244 String msg = null;
245
246 for(int i = 0; i < classes.length; i++)
247 {
248 t = n.getThrowable(i);
249 assertEquals("throwable class", classes[i], t.getClass());
250 if(Nestable.class.isInstance(t))
251 {
252 msg = ((Nestable) t).getMessage(0);
253 }
254 else
255 {
256 msg = t.getMessage();
257 }
258 assertEquals("throwable message", msgs[i], msg);
259 }
260
261 // Test for index out of bounds
262 try
263 {
264 t = n.getThrowable(-1);
265 fail("getThrowable(-1) should have thrown IndexOutOfBoundsException");
266 }
267 catch(IndexOutOfBoundsException ioobe)
268 {
269 }
270 try
271 {
272 t = n.getThrowable(999);
273 fail("getThrowable(999) should have thrown IndexOutOfBoundsException");
274 }
275 catch(IndexOutOfBoundsException ioobe)
276 {
277 }
278 }
279
280 /**
281 * Tests the getThrowables() operation.
282 */
283 public void testGetThrowables()
284 {
285 Nestable n = null;
286 String msgs[] = null;
287 Class[] throwables = null;
288
289 msgs = new String[2];
290 msgs[0] = null;
291 msgs[1] = "level 2";
292 throwables = new Class[2];
293 throwables[0] = getTester1Class();
294 throwables[1] = getThrowableClass();
295 n = getTester1(getThrowable(msgs[1]));
296 doNestableExceptionGetThrowables(n, throwables, msgs);
297
298 msgs = new String[5];
299 msgs[0] = "level 1";
300 msgs[1] = "level 2";
301 msgs[2] = null;
302 msgs[3] = "level 4";
303 msgs[4] = "level 5";
304 throwables = new Class[5];
305 throwables[0] = getTester1Class();
306 throwables[1] = getTester2Class();
307 throwables[2] = getTester1Class();
308 throwables[3] = getTester2Class();
309 throwables[4] = getThrowableClass();
310 n = getTester1(msgs[0], getTester2(msgs[1], getTester1(getTester2(msgs[3], getThrowable(msgs[4])))));
311 doNestableExceptionGetThrowables(n, throwables, msgs);
312 }
313
314 private void doNestableExceptionGetThrowables(Nestable n, Class[] classes, String[] msgs)
315 {
316 String msg = null;
317
318 Throwable throwables[] = n.getThrowables();
319 assertEquals("throwables length", classes.length, throwables.length);
320 for(int i = 0; i < classes.length; i++)
321 {
322 assertEquals("throwable class", classes[i], throwables[i].getClass());
323 Throwable t = throwables[i];
324 if(Nestable.class.isInstance(t))
325 {
326 msg = ((Nestable) t).getMessage(0);
327 }
328 else
329 {
330 msg = t.getMessage();
331 }
332 assertEquals("throwable message", msgs[i], msg);
333 }
334 }
335
336 /**
337 * Tests the indexOfThrowable() operation.
338 */
339 public void testIndexOfThrowable()
340 {
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], getTester1(getTester2(msgs[3], getThrowable(msgs[4])))));
359 for(int i = 0; i < throwables.length; i++)
360 {
361 doNestableExceptionIndexOfThrowable(n, throwables[i], indexes[i], msgs[indexes[i]]);
362 }
363 doNestableExceptionIndexOfThrowable(n, getBaseThrowableClass(), 0, msgs[0]);
364 doNestableExceptionIndexOfThrowable(n, java.util.Date.class, -1, null);
365 doNestableExceptionIndexOfThrowable(n, null, -1, null);
366 }
367
368 private void doNestableExceptionIndexOfThrowable(Nestable n, Class type, int expectedIndex, String expectedMsg)
369 {
370 Throwable t = null;
371
372 int index = n.indexOfThrowable(type);
373 assertEquals("index of throwable " + (type == null ? "null" : type.getName()), expectedIndex, index);
374 if(expectedIndex > -1)
375 {
376 t = n.getThrowable(index);
377 if(expectedMsg != null)
378 {
379 String msg = null;
380 if(Nestable.class.isInstance(t))
381 {
382 msg = ((Nestable) t).getMessage(0);
383 }
384 else
385 {
386 msg = t.getMessage();
387 }
388 assertEquals("message of indexed throwable", expectedMsg, msg);
389 }
390 }
391 }
392
393 /**
394 * Tests the indexOfThrowable(int) operation.
395 */
396 public void testIndexOfThrowableI()
397 {
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], getTester1(getTester2(msgs[3], getThrowable(msgs[4])))));
416 for(int i = 0; i < throwables.length; i++)
417 {
418 doNestableExceptionIndexOfThrowableI(n, throwables[i], 0, indexes[i], msgs[indexes[i]]);
419 }
420 doNestableExceptionIndexOfThrowableI(n, getTester2Class(), 2, 3, msgs[3]);
421 doNestableExceptionIndexOfThrowableI(n, getTester1Class(), 1, 2, msgs[2]);
422 doNestableExceptionIndexOfThrowableI(n, getTester1Class(), 3, -1, null);
423 doNestableExceptionIndexOfThrowableI(n, getTester1Class(), 4, -1, null);
424 doNestableExceptionIndexOfThrowableI(n, getThrowableClass(), 2, 4, msgs[4]);
425 doNestableExceptionIndexOfThrowableI(n, java.util.Date.class, 0, -1, null);
426 doNestableExceptionIndexOfThrowableI(n, null, 0, -1, null);
427
428 // Test for index out of bounds
429 try
430 {
431 int index = n.indexOfThrowable(getTester1Class(), -1);
432 fail("method should have thrown IndexOutOfBoundsException");
433 }
434 catch(IndexOutOfBoundsException iooob)
435 {
436 }
437 try
438 {
439 int index = n.indexOfThrowable(getTester1Class(), 5);
440 fail("method should have thrown IndexOutOfBoundsException");
441 }
442 catch(IndexOutOfBoundsException iooob)
443 {
444 }
445
446 }
447
448 private void doNestableExceptionIndexOfThrowableI(Nestable n, Class type, int fromIndex, int expectedIndex, String expectedMsg)
449 {
450 Throwable t = null;
451
452 int index = n.indexOfThrowable(type, fromIndex);
453 assertEquals("index of throwable " + (type == null ? "null" : type.getName()), expectedIndex, index);
454 if(expectedIndex > -1)
455 {
456 t = n.getThrowable(index);
457 if(expectedMsg != null)
458 {
459 String msg = null;
460 if(Nestable.class.isInstance(t))
461 {
462 msg = ((Nestable) t).getMessage(0);
463 }
464 else
465 {
466 msg = t.getMessage();
467 }
468 assertEquals("message of indexed throwable", expectedMsg, msg);
469 }
470 }
471
472 }
473
474 /**
475 * Tests the printPartialStackTrace() operation.
476 */
477 public void testPrintPartialStackTrace()
478 {
479 Nestable ne9 = getNestable("ne9", getThrowable("ne9 exception"));
480 ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
481 PrintStream ps2 = new PrintStream(baos2);
482 PrintWriter pw2 = new PrintWriter(ps2, true);
483 ne9.printPartialStackTrace(pw2);
484 String stack2 = baos2.toString();
485 String startsWith = ne9.getClass().getName() + ": ne9";
486 assertTrue("stack trace startsWith == " + startsWith,
487 stack2.startsWith(startsWith));
488 assertEquals("stack trace indexOf rethrown == -1",
489 stack2.indexOf("rethrown"), -1);
490 }
491
492 /**
493 * Tests the printStackTrace() operation.
494 */
495 public void testPrintStackTrace()
496 {
497 Nestable ne8 = getNestable("ne8", getThrowable("ne8 exception"));
498 ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
499 PrintStream ps1 = new PrintStream(baos1);
500 PrintWriter pw1 = new PrintWriter(ps1, true);
501 ne8.printStackTrace(pw1);
502 String stack1 = baos1.toString();
503 String startsWith = ne8.getClass().getName() + ": ne8";
504 assertTrue("stack trace startsWith == " + startsWith,
505 stack1.startsWith(startsWith));
506 String indexOf = getThrowableClass().getName() + ": ne8 exception";
507 assertTrue("stack trace indexOf " + indexOf + " > -1",
508 stack1.indexOf(indexOf) > -1);
509 }
510
511 /**
512 * Returns an instance of the <code>Nestable</code> implementation being
513 * tested.
514 *
515 * @return the instance
516 */
517 public abstract Nestable getNestable();
518
519 /**
520 * Returns an instance of the <code>Nestable</code> implementation being
521 * tested.
522 *
523 * @param n <code>Nestable</code> argument to be provided to the instance
524 * constructor
525 * @return the instance
526 */
527 public abstract Nestable getNestable(Nestable n);
528
529 /**
530 * Returns an instance of the <code>Nestable</code> implementation being
531 * tested.
532 *
533 * @param msg <code>String</code> argument to be provided to the instance
534 * constructor
535 * @return the instance
536 */
537 public abstract Nestable getNestable(String msg);
538
539 /**
540 * Returns an instance of the <code>Nestable</code> implementation being
541 * tested.
542 *
543 * @param msg <code>String</code> argument to be provided to the instance
544 * constructor
545 * @param n <code>Nestable</code> argument to be provided to the instance
546 * constructor
547 * @return the instance
548 */
549 public abstract Nestable getNestable(String msg, Nestable n);
550
551 /**
552 * Returns an instance of the <code>Nestable</code> implementation being
553 * tested.
554 *
555 * @param msg <code>String</code> argument to be provided to the instance
556 * constructor
557 * @param t <code>Throwable</code> argument to be provided to the instance
558 * constructor
559 * @return the instance
560 */
561 public abstract Nestable getNestable(String msg, Throwable t);
562
563 /**
564 * Returns an instance of the <code>Nestable</code> implementation being
565 * tested.
566 *
567 * @param t <code>Throwable</code> argument to be provided to the instance
568 * constructor
569 * @return the instance
570 */
571 public abstract Nestable getNestable(Throwable t);
572
573 /**
574 * Returns an instance of a <code>Throwable</code> to be used in
575 * constructing instances of the <code>Nestable</code> implementation being
576 * tested.
577 *
578 * @param msg <code>String</code> argument to be provided to the instance
579 * constructor
580 * @return the instance
581 */
582 public abstract Throwable getThrowable(String msg);
583
584 /**
585 * Returns an instance of one tester <code>Nestable</code> implementation.
586 *
587 * @param n <code>Nestable</code> argument to be provided to the instance
588 * constructor
589 * @return the instance
590 */
591 public abstract Nestable getTester1(Nestable n);
592
593 /**
594 * Returns an instance of one tester <code>Nestable</code> implementation.
595 *
596 * @param t <code>Throwable</code> argument to be provided to the instance
597 * constructor
598 * @return the instance
599 */
600 public abstract Nestable getTester1(Throwable t);
601
602 /**
603 * Returns an instance of one tester <code>Nestable</code> implementation.
604 *
605 * @param msg <code>String</code> argument to be provided to the instance
606 * constructor
607 * @param n <code>Nestable</code> argument to be provided to the instance
608 * constructor
609 * @return the instance
610 */
611 public abstract Nestable getTester1(String msg, Nestable n);
612
613 /**
614 * Returns an instance of one tester <code>Nestable</code> implementation.
615 *
616 * @param msg <code>String</code> argument to be provided to the instance
617 * constructor
618 * @param t <code>Throwable</code> argument to be provided to the instance
619 * constructor
620 * @return the instance
621 */
622 public abstract Nestable getTester1(String msg, Throwable t);
623
624 /**
625 * Returns an instance of a second tester <code>Nestable</code>
626 * implementation.
627 *
628 * @param msg <code>String</code> argument to be provided to the instance
629 * constructor
630 * @param n <code>Nestable</code> argument to be provided to the instance
631 * constructor
632 * @return the instance
633 */
634 public abstract Nestable getTester2(String msg, Nestable n);
635
636 /**
637 * Returns an instance of a second tester <code>Nestable</code>
638 * implementation.
639 *
640 * @param msg <code>String</code> argument to be provided to the instance
641 * constructor
642 * @param t <code>Throwable</code> argument to be provided to the instance
643 * constructor
644 * @return the instance
645 */
646 public abstract Nestable getTester2(String msg, Throwable t);
647
648 /**
649 * Returns the class of the first tester <code>Nestable</code>
650 * implementation.
651 *
652 * @return the class
653 */
654 public abstract Class getTester1Class();
655
656 /**
657 * Returns the class of the second tester <code>Nestable</code>
658 * implementation.
659 *
660 * @return the class
661 */
662 public abstract Class getTester2Class();
663
664 /**
665 * Returns the class of the <code>Throwable</code> used in constructing
666 * instances of the <code>Nestable</code> implementation being tested.
667 *
668 * @return the class
669 */
670 public abstract Class getThrowableClass();
671
672 /**
673 * Returns the base class being used, typically Error, Eception or RuntimeException.
674 *
675 * @return the class
676 */
677 public abstract Class getBaseThrowableClass();
678
679 }
680