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:
018: /**
019: * @author Dmitry B. Yershov
020: * @version $Revision$
021: */package java.lang;
022:
023: import java.io.ByteArrayOutputStream;
024: import java.io.PrintStream;
025: import java.io.PrintWriter;
026: import junit.framework.TestCase;
027:
028: public class ThrowableTest extends TestCase {
029:
030: private static final boolean isLinux = System
031: .getProperty("os.name").toLowerCase().indexOf("linux") != -1;
032:
033: private static final String printOutput = "java.lang.Throwable: Throwable 0\n"
034: + "\tat d.d(d:1)\n\tat c.c(c:1)\n\tat b.b(Native Method)\n\tat a.a(a:1)\n"
035: + "Caused by: java.lang.Throwable: Throwable 1\n"
036: + "\tat f.f(f:1)\n\tat e.e(Native Method)\n\tat d.d(d:1)\n\t... 3 more\n"
037: + "Caused by: java.lang.Throwable: Throwable 2\n"
038: + "\tat d.d(d:1)\n\t... 3 more" + (isLinux ? "\n" : "\r\n");
039:
040: /**
041: * Constructor under test Throwable(String)
042: */
043: public void testThrowableString() {
044: Throwable th = new Throwable("aaa");
045: assertEquals("incorrect message", "aaa", th.getMessage());
046: assertNull("cause should be null", th.getCause());
047: assertTrue("empty stack trace", th.getStackTrace().length > 0);
048: }
049:
050: /**
051: * Constructor under test Throwable(String, Throwable)
052: */
053: public void testThrowableStringThrowable() {
054: Throwable th1 = new Throwable();
055: Throwable th = new Throwable("aaa", th1);
056: assertEquals("incorrect message", "aaa", th.getMessage());
057: assertSame("incorrect cause", th1, th.getCause());
058: assertTrue("empty stack trace", th.getStackTrace().length > 0);
059: }
060:
061: /**
062: * Constructor under test Throwable(Throwable)
063: */
064: public void testThrowableThrowable() {
065: Throwable th1 = new Throwable("aaa");
066: Throwable th = new Throwable(th1);
067: assertEquals("incorrect message", "java.lang.Throwable: aaa",
068: th.getMessage());
069: assertSame("incorrect cause", th1, th.getCause());
070: assertTrue("empty stack trace", th.getStackTrace().length > 0);
071: }
072:
073: /**
074: * fillInStackTrace() should return reference to <code>this</code>
075: * of the target Throwable.
076: */
077: public void testFillInStackTrace_return() {
078:
079: Throwable th = new Throwable();
080: assertSame(th, th.fillInStackTrace());
081: }
082:
083: private Throwable makeThrowable() {
084: return new Throwable();
085: }
086:
087: private void updateThrowable(Throwable t, int depth) {
088: if (depth-- > 0) {
089: updateThrowable(t, depth);
090: } else {
091: t.fillInStackTrace();
092: }
093: }
094:
095: /**
096: * fillInStackTrace() should not change recorded stack info
097: * on subsequent invocations.
098: */
099: public void testFillInStackTrace_manytimes() {
100: Throwable th = makeThrowable();
101: int len1 = th.getStackTrace().length;
102: th.fillInStackTrace();
103: assertEquals("case 1", len1, th.getStackTrace().length);
104: updateThrowable(th, 10);
105: assertEquals("case 2", len1, th.getStackTrace().length);
106: }
107:
108: /**
109: * Method under test Throwable getCause()
110: */
111: public void testGetCause() {
112: Throwable th = new Throwable();
113: Throwable th1 = new Throwable();
114: assertNull("cause should be null", th.getCause());
115: th = new Throwable(th1);
116: assertSame("incorrect cause", th1, th.getCause());
117: }
118:
119: /**
120: * Method under test String getLocalizedMessage()
121: */
122: public void testGetLocalizedMessage() {
123: Throwable th = new Throwable("aaa");
124: assertEquals("incorrect localized message", "aaa", th
125: .getLocalizedMessage());
126: }
127:
128: /**
129: * Method under test String getMessage()
130: */
131: public void testGetMessage() {
132: Throwable th = new Throwable("aaa");
133: assertEquals("incorrect message", "aaa", th.getMessage());
134: }
135:
136: /**
137: * Method under test StackTraceElement[] getStackTrace()
138: */
139: public void testGetStackTrace() {
140: StackTraceElement[] ste = new StackTraceElement[1];
141: ste[0] = new StackTraceElement("class", "method", "file", -2);
142: Throwable th = new Throwable("message");
143: th.setStackTrace(ste);
144: ste = th.getStackTrace();
145: assertEquals("incorrect length", 1, ste.length);
146: assertEquals("incorrect file name", "file", ste[0]
147: .getFileName());
148: assertEquals("incorrect line number", -2, ste[0]
149: .getLineNumber());
150: assertEquals("incorrect class name", "class", ste[0]
151: .getClassName());
152: assertEquals("incorrect method name", "method", ste[0]
153: .getMethodName());
154: assertTrue("native method should be reported", ste[0]
155: .isNativeMethod());
156: }
157:
158: /**
159: * Method under test Throwable initCause(Throwable)
160: */
161: public void testInitCause() {
162: Throwable th = new Throwable();
163: Throwable th1 = new Throwable();
164: th.initCause(th1);
165: assertSame("incorrect cause", th1, th.getCause());
166: th = new Throwable();
167: th.initCause(null);
168: assertNull("cause should be null", th.getCause());
169: th = new Throwable();
170: try {
171: th.initCause(th);
172: fail("Throwable initialized by itself");
173: } catch (IllegalArgumentException ex) {
174: }
175: th = new Throwable((Throwable) null);
176: try {
177: th.initCause(th1);
178: fail("Second initialization");
179: } catch (IllegalStateException ex) {
180: }
181: th = new Throwable(th1);
182: try {
183: th.initCause(th1);
184: fail("Second initialization");
185: } catch (IllegalStateException ex) {
186: }
187: th = new Throwable();
188: th1 = th.initCause(th1);
189: assertSame("incorrect value returned from initCause", th, th1);
190: }
191:
192: /**
193: * Method under test void setStackTrace(StackTraceElement[])
194: */
195: public void testSetStackTrace() {
196: StackTraceElement[] ste = new StackTraceElement[2];
197: ste[0] = new StackTraceElement("class", "method", "file", -2);
198: ste[1] = new StackTraceElement("class", "method", "file", 1);
199: Throwable th = new Throwable();
200: th.setStackTrace(ste);
201: ste = th.getStackTrace();
202: assertEquals("incorrect length", 2, ste.length);
203: assertEquals("incorrect file name", "file", ste[0]
204: .getFileName());
205: assertEquals("incorrect line number", -2, ste[0]
206: .getLineNumber());
207: assertEquals("incorrect class name", "class", ste[0]
208: .getClassName());
209: assertEquals("incorrect method name", "method", ste[0]
210: .getMethodName());
211: assertTrue("native method should be reported", ste[0]
212: .isNativeMethod());
213: assertEquals("incorrect file name", "file", ste[1]
214: .getFileName());
215: assertEquals("incorrect line number", 1, ste[1].getLineNumber());
216: assertEquals("incorrect class name", "class", ste[1]
217: .getClassName());
218: assertEquals("incorrect method name", "method", ste[1]
219: .getMethodName());
220: assertFalse("native method should NOT be reported", ste[1]
221: .isNativeMethod());
222: ste[1] = null;
223: try {
224: th.setStackTrace(ste);
225: } catch (NullPointerException ex) {
226: }
227: ste = null;
228: try {
229: th.setStackTrace(ste);
230: } catch (NullPointerException ex) {
231: }
232: }
233:
234: /**
235: * Method under test void setStackTrace(StackTraceElement[]).
236: * Null arguments are verified
237: */
238: public void testSetStackTrace_Null() {
239: Throwable th = new Throwable();
240: StackTraceElement[] ste = null;
241: try {
242: th.setStackTrace(ste);
243: fail("Assert 1: NullPointerException should be thrown");
244: } catch (NullPointerException ex) {
245: }
246: ste = new StackTraceElement[2];
247: ste[0] = new StackTraceElement("class", "method", "file", -2);
248: ste[1] = null;
249: try {
250: th.setStackTrace(ste);
251: fail("Assert 2: NullPointerException should be thrown");
252: } catch (NullPointerException ex) {
253: }
254: }
255:
256: /**
257: * Method under test String toString()
258: */
259: public void testToString() {
260: Throwable th = new Throwable("aaa");
261: assertEquals("incorrect String representation",
262: "java.lang.Throwable: aaa", th.toString());
263: }
264:
265: /**
266: * Method under test:
267: * - void printStackTrace(PrintStream)
268: */
269: public void testPrintStackTracePrintStream() {
270: Throwable th;
271: ByteArrayOutputStream ba = new ByteArrayOutputStream();
272: PrintStream ps = new PrintStream(ba);
273: th = prepareThrowables();
274: th.printStackTrace(ps);
275: assertEquals("incorrect info printed in stack trace",
276: printOutput, ba.toString());
277: }
278:
279: /**
280: * Methods under test:
281: * - void printStackTrace(PrintWriter),
282: * where PrintWriter does not flush automatically.
283: */
284: public void testPrintStackTracePrintWriter_False() {
285: ByteArrayOutputStream ba = new ByteArrayOutputStream();
286: PrintWriter ps = new PrintWriter(ba, false);
287: try {
288: throw new Exception("level1",
289: new Exception("level2", new Exception("level3",
290: new NullPointerException())));
291: } catch (Exception e) {
292: e.printStackTrace(ps);
293: }
294: assertEquals("the output should be empty until flush", "", ba
295: .toString());
296: }
297:
298: /**
299: * Methods under test:
300: * - void printStackTrace(PrintWriter),
301: * where PrintWriter flushes automatically
302: */
303: public void testPrintStackTracePrintWriter_True() {
304: Throwable th;
305: ByteArrayOutputStream ba = new ByteArrayOutputStream();
306: PrintWriter ps = new PrintWriter(ba, true);
307: th = prepareThrowables();
308: th.printStackTrace(ps);
309: assertEquals("incorrect info in printed stack trace",
310: printOutput, ba.toString());
311: }
312:
313: private Throwable prepareThrowables() {
314: Throwable th, th1, th2;
315: StackTraceElement[] ste = new StackTraceElement[4];
316: StackTraceElement[] ste1 = new StackTraceElement[6];
317:
318: ste[0] = new StackTraceElement("d", "d", "d", 1);
319: ste[1] = new StackTraceElement("c", "c", "c", 1);
320: ste[2] = new StackTraceElement("b", "b", null, -2);
321: ste[3] = new StackTraceElement("a", "a", "a", 1);
322:
323: ste1[0] = new StackTraceElement("f", "f", "f", 1);
324: ste1[1] = new StackTraceElement("e", "e", null, -2);
325: ste1[2] = new StackTraceElement("d", "d", "d", 1);
326: ste1[3] = new StackTraceElement("c", "c", "c", 1);
327: ste1[4] = new StackTraceElement("b", "b", null, -2);
328: ste1[5] = new StackTraceElement("a", "a", "a", 1);
329:
330: th2 = new Throwable("Throwable 2");
331: th2.setStackTrace(ste);
332: th1 = new Throwable("Throwable 1");
333: th1.initCause(th2);
334: th1.setStackTrace(ste1);
335: th = new Throwable("Throwable 0", th1);
336: th.setStackTrace(ste);
337: return th;
338: }
339: }
|