1 package org.apache.maven.surefire.report;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.lang.reflect.Field;
23 import java.util.List;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.FutureTask;
26
27 import junit.framework.AssertionFailedError;
28 import junit.framework.ComparisonFailure;
29 import junit.framework.TestCase;
30 import org.apache.maven.surefire.util.internal.DaemonThreadFactory;
31
32 import static org.apache.maven.surefire.report.SmartStackTraceParser.*;
33
34 @SuppressWarnings( "ThrowableResultOfMethodCallIgnored" )
35 public class SmartStackTraceParserTest
36 extends TestCase
37 {
38 public void testGetString()
39 throws Exception
40 {
41 ATestClass aTestClass = new ATestClass();
42 try
43 {
44 aTestClass.failInAssert();
45 }
46 catch ( AssertionError e )
47 {
48 SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
49 String res = smartStackTraceParser.getString();
50 assertEquals( "ATestClass.failInAssert:30 X is not Z", res );
51
52 }
53
54 }
55
56 public void testNestedFailure()
57 throws Exception
58 {
59 ATestClass aTestClass = new ATestClass();
60 try
61 {
62 aTestClass.nestedFailInAssert();
63 }
64 catch ( AssertionError e )
65 {
66 SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
67 String res = smartStackTraceParser.getString();
68 assertEquals( "ATestClass.nestedFailInAssert:35->failInAssert:30 X is not Z", res );
69 }
70 }
71
72 public void testNestedNpe()
73 throws Exception
74 {
75 ATestClass aTestClass = new ATestClass();
76 try
77 {
78 aTestClass.nestedNpe();
79 }
80 catch ( NullPointerException e )
81 {
82 SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
83 String res = smartStackTraceParser.getString();
84 assertEquals( "ATestClass.nestedNpe:45->npe:40 NullPointer It was null", res );
85
86 }
87 }
88
89 public void testNestedNpeOutsideTest()
90 throws Exception
91 {
92 ATestClass aTestClass = new ATestClass();
93 try
94 {
95 aTestClass.nestedNpeOutsideTest();
96 }
97 catch ( NullPointerException e )
98 {
99 SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
100 String res = smartStackTraceParser.getString();
101 assertEquals( "ATestClass.nestedNpeOutsideTest:55->npeOutsideTest:50 » NullPointer", res );
102
103 }
104 }
105
106 public void testLongMessageTruncation()
107 throws Exception
108 {
109 ATestClass aTestClass = new ATestClass();
110 try
111 {
112 aTestClass.aLongTestErrorMessage();
113 }
114 catch ( RuntimeException e )
115 {
116 SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
117 String res = smartStackTraceParser.getString();
118 assertEquals( "ATestClass.aLongTestErrorMessage:60 Runtime This message will be truncated, so...", res );
119
120 }
121 }
122
123 public void testFailureInBaseClass()
124 throws Exception
125 {
126 ASubClass aTestClass = new ASubClass();
127 try
128 {
129 aTestClass.npe();
130 }
131 catch ( NullPointerException e )
132 {
133 SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ASubClass.class, e );
134 String res = smartStackTraceParser.getString();
135 assertEquals( "ASubClass>ABaseClass.npe:27 » NullPointer It was null", res );
136 }
137 }
138
139 public void testClassThatWillFail()
140 throws Exception
141 {
142 CaseThatWillFail aTestClass = new CaseThatWillFail();
143 try
144 {
145 aTestClass.testThatWillFail();
146 }
147 catch ( ComparisonFailure e )
148 {
149 SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( CaseThatWillFail.class, e );
150 String res = smartStackTraceParser.getString();
151 assertEquals( "CaseThatWillFail.testThatWillFail:29 expected:<[abc]> but was:<[def]>", res );
152 }
153 }
154
155 public Throwable getAThrownException()
156 {
157 try
158 {
159 TestClass1.InnerBTestClass.throwSomething();
160 }
161 catch ( Throwable t )
162 {
163 return t;
164 }
165 return null;
166 }
167
168 public void testCollections()
169 {
170 Throwable aThrownException = getAThrownException();
171 List<StackTraceElement> innerMost =
172 focusInsideClass( aThrownException.getCause().getStackTrace(),
173 new ClassNameStackTraceFilter( TestClass1.InnerBTestClass.class.getName() ) );
174 assertEquals( 2, innerMost.size() );
175 StackTraceElement inner = innerMost.get( 0 );
176 assertEquals( TestClass1.InnerBTestClass.class.getName(), inner.getClassName() );
177 StackTraceElement outer = innerMost.get( 1 );
178 assertEquals( TestClass1.InnerBTestClass.class.getName(), outer.getClassName() );
179 }
180
181 public void testAssertionWithNoMessage()
182 {
183 try
184 {
185 new AssertionNoMessage().testThrowSomething();
186 }
187 catch ( ComparisonFailure e )
188 {
189 SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( AssertionNoMessage.class, e );
190 String res = smartStackTraceParser.getString();
191 assertEquals( "AssertionNoMessage.testThrowSomething:29 expected:<[abc]> but was:<[xyz]>", res );
192 }
193 }
194
195 public void testFailWithFail()
196 {
197 try
198 {
199 new FailWithFail().testThatWillFail();
200 }
201 catch ( AssertionFailedError e )
202 {
203 SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( FailWithFail.class, e );
204 String res = smartStackTraceParser.getString();
205 assertEquals( "FailWithFail.testThatWillFail:29 abc", res );
206 }
207 }
208
209 public void testCollectorWithNested()
210 {
211 try
212 {
213 InnerATestClass.testFake();
214 }
215 catch ( Throwable t )
216 {
217 List<StackTraceElement> stackTraceElements =
218 focusInsideClass( t.getStackTrace(),
219 new ClassNameStackTraceFilter( InnerATestClass.class.getName() ) );
220 assertNotNull( stackTraceElements );
221 assertEquals( 2, stackTraceElements.size() );
222 StackTraceElement innerMost = stackTraceElements.get( 0 );
223 assertEquals( InnerATestClass.class.getName(), innerMost.getClassName() );
224 StackTraceElement outer = stackTraceElements.get( 1 );
225 assertEquals( InnerATestClass.class.getName(), outer.getClassName() );
226 }
227 }
228
229 public void testNonClassNameStacktrace()
230 {
231 SmartStackTraceParser smartStackTraceParser =
232 new SmartStackTraceParser( "Not a class name", new Throwable( "my message" ), null );
233 assertEquals( "my message", smartStackTraceParser.getString() );
234 }
235
236 public void testNullElementInStackTrace()
237 throws Exception
238 {
239 ATestClass aTestClass = new ATestClass();
240 try
241 {
242 aTestClass.failInAssert();
243 }
244 catch ( AssertionError e )
245 {
246 SmartStackTraceParser smartStackTraceParser = new SmartStackTraceParser( ATestClass.class, e );
247 Field stackTrace = SmartStackTraceParser.class.getDeclaredField( "stackTrace" );
248 stackTrace.setAccessible( true );
249 stackTrace.set( smartStackTraceParser, new StackTraceElement[0] );
250 String res = smartStackTraceParser.getString();
251 assertEquals( "ATestClass X is not Z", res );
252 }
253 }
254
255 public void testSingleNestedWithThread()
256 {
257 ExecutionException e = getSingleNested();
258 String name = getClass().getName();
259 Throwable focus = findTopmostWithClass( e, new ClassNameStackTraceFilter( name ) );
260 assertSame( e, focus );
261 List<StackTraceElement> stackTraceElements =
262 focusInsideClass( focus.getStackTrace(), new ClassNameStackTraceFilter( name ) );
263 assertEquals( stackTraceElements.get( stackTraceElements.size() - 1 ).getClassName(), name );
264 }
265
266 public void testDoubleNestedWithThread()
267 {
268 ExecutionException e = getDoubleNestedException();
269
270 String name = getClass().getName();
271 Throwable focus = findTopmostWithClass( e, new ClassNameStackTraceFilter( name ) );
272 assertSame( e, focus );
273 List<StackTraceElement> stackTraceElements =
274 focusInsideClass( focus.getStackTrace(), new ClassNameStackTraceFilter( name ) );
275 assertEquals( stackTraceElements.get( stackTraceElements.size() - 1 ).getClassName(), name );
276
277 name = RunnableTestClass1.class.getName();
278 focus = findTopmostWithClass( e, new ClassNameStackTraceFilter( name ) );
279 assertSame( e.getCause(), focus );
280 stackTraceElements = focusInsideClass( focus.getStackTrace(), new ClassNameStackTraceFilter( name ) );
281 assertEquals( stackTraceElements.get( stackTraceElements.size() - 1 ).getClassName(), name );
282 }
283
284 public void testStackTraceWithFocusOnClassAsString()
285 {
286 try
287 {
288 new StackTraceFocusedOnClass.C().c();
289 fail();
290 }
291 catch ( Exception e )
292 {
293 String trace = stackTraceWithFocusOnClassAsString( e, StackTraceFocusedOnClass.B.class.getName() );
294
295 assertEquals( "java.lang.RuntimeException: java.lang.IllegalStateException: java.io.IOException: I/O error\n"
296 + "\tat org.apache.maven.surefire.report.StackTraceFocusedOnClass$B.b(StackTraceFocusedOnClass.java:65)\n"
297 + "Caused by: java.lang.IllegalStateException: java.io.IOException: I/O error\n"
298 + "\tat org.apache.maven.surefire.report.StackTraceFocusedOnClass$B.b(StackTraceFocusedOnClass.java:61)\n"
299 + "Caused by: java.io.IOException: I/O error\n"
300 + "\tat org.apache.maven.surefire.report.StackTraceFocusedOnClass$B.abs(StackTraceFocusedOnClass.java:73)\n"
301 + "\tat org.apache.maven.surefire.report.StackTraceFocusedOnClass$B.b(StackTraceFocusedOnClass.java:61)\n",
302 trace );
303 }
304 }
305
306 public ExecutionException getSingleNested()
307 {
308 FutureTask<Object> futureTask = new FutureTask<Object>( new RunnableTestClass2() );
309 DaemonThreadFactory.newDaemonThread( futureTask ).start();
310 try
311 {
312 futureTask.get();
313 }
314 catch ( InterruptedException e )
315 {
316 fail();
317 }
318 catch ( ExecutionException e )
319 {
320 return e;
321 }
322 fail();
323 return null;
324 }
325
326 private ExecutionException getDoubleNestedException()
327 {
328 FutureTask<Object> futureTask = new FutureTask<Object>( new RunnableTestClass1() );
329 DaemonThreadFactory.newDaemonThread( futureTask ).start();
330 try
331 {
332 futureTask.get();
333 }
334 catch ( InterruptedException e )
335 {
336 fail();
337 }
338 catch ( ExecutionException e )
339 {
340 return e;
341 }
342 return null;
343 }
344 }