1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.apache.maven.surefire.common.junit4;
20  
21  import org.apache.maven.surefire.api.report.SafeThrowable;
22  import org.apache.maven.surefire.api.report.StackTraceWriter;
23  import org.apache.maven.surefire.api.util.internal.ClassMethod;
24  import org.apache.maven.surefire.report.SmartStackTraceParser;
25  import org.junit.runner.notification.Failure;
26  
27  import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.toClassMethod;
28  import static org.apache.maven.surefire.report.SmartStackTraceParser.stackTraceWithFocusOnClassAsString;
29  
30  
31  
32  
33  
34  
35  
36  public class JUnit4StackTraceWriter implements StackTraceWriter {
37      private final Failure junitFailure;
38  
39      
40  
41  
42  
43  
44      public JUnit4StackTraceWriter(Failure junitFailure) {
45          this.junitFailure = junitFailure;
46      }
47  
48      
49  
50  
51  
52  
53      @Override
54      public String writeTraceToString() {
55          Throwable t = junitFailure.getException();
56          if (t != null) {
57              String originalTrace = junitFailure.getTrace();
58              if (isMultiLineExceptionMessage(t)) {
59                  
60                  StringBuilder builder = new StringBuilder(originalTrace);
61                  String exc = t.getClass().getName() + ": ";
62                  if (originalTrace.startsWith(exc)) {
63                      builder.insert(exc.length(), '\n');
64                  }
65                  return builder.toString();
66              }
67              return originalTrace;
68          }
69          return "";
70      }
71  
72      @Override
73      public String smartTrimmedStackTrace() {
74          Throwable exception = junitFailure.getException();
75          ClassMethod classMethod = toClassMethod(junitFailure.getDescription());
76          return exception == null
77                  ? junitFailure.getMessage()
78                  : new SmartStackTraceParser(classMethod.getClazz(), exception, classMethod.getMethod()).getString();
79      }
80  
81      
82  
83  
84  
85  
86      @Override
87      public String writeTrimmedTraceToString() {
88          String testClass = toClassMethod(junitFailure.getDescription()).getClazz();
89          try {
90              Throwable e = junitFailure.getException();
91              return stackTraceWithFocusOnClassAsString(e, testClass);
92          } catch (Throwable t) {
93              return stackTraceWithFocusOnClassAsString(t, testClass);
94          }
95      }
96  
97      
98  
99  
100 
101 
102     @Override
103     public SafeThrowable getThrowable() {
104         return new SafeThrowable(junitFailure.getException());
105     }
106 
107     private static boolean isMultiLineExceptionMessage(Throwable t) {
108         String msg = t.getLocalizedMessage();
109         if (msg != null) {
110             int countNewLines = 0;
111             for (int i = 0, length = msg.length(); i < length; i++) {
112                 if (msg.charAt(i) == '\n') {
113                     if (++countNewLines == 2) {
114                         break;
115                     }
116                 }
117             }
118             return countNewLines > 1 || countNewLines == 1 && !msg.trim().endsWith("\n");
119         }
120         return false;
121     }
122 }