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
23 import org.apache.maven.surefire.util.internal.StringUtils;
24
25 import java.io.PrintWriter;
26 import java.io.StringWriter;
27
28
29
30
31
32
33 public class LegacyPojoStackTraceWriter
34 implements StackTraceWriter
35 {
36 private static final int MAX_LINE_LENGTH = 77;
37
38 private final Throwable t;
39
40 private final String testClass;
41
42 private final String testMethod;
43
44 public LegacyPojoStackTraceWriter( String testClass, String testMethod, Throwable t )
45 {
46 this.testClass = testClass;
47 this.testMethod = testMethod;
48 this.t = t;
49 }
50
51 @Override
52 public String writeTraceToString()
53 {
54 if ( t != null )
55 {
56 StringWriter w = new StringWriter();
57 try ( PrintWriter stackTrace = new PrintWriter( w ) )
58 {
59 t.printStackTrace( stackTrace );
60 }
61 StringBuffer builder = w.getBuffer();
62 if ( isMultiLineExceptionMessage( t ) )
63 {
64
65 String exc = t.getClass().getName() + ": ";
66 if ( StringUtils.startsWith( builder, exc ) )
67 {
68 builder.insert( exc.length(), '\n' );
69 }
70 }
71 return builder.toString();
72 }
73 return "";
74 }
75
76 @Override
77 public String smartTrimmedStackTrace()
78 {
79 StringBuilder result = new StringBuilder();
80 result.append( testClass );
81 result.append( "#" );
82 result.append( testMethod );
83 SafeThrowable throwable = getThrowable();
84 if ( throwable.getTarget() instanceof AssertionError )
85 {
86 result.append( " " );
87 result.append( getTruncatedMessage( throwable.getMessage(), MAX_LINE_LENGTH - result.length() ) );
88 }
89 else
90 {
91 Throwable target = throwable.getTarget();
92 if ( target != null )
93 {
94 result.append( " " );
95 result.append( target.getClass().getSimpleName() );
96 result.append( getTruncatedMessage( throwable.getMessage(), MAX_LINE_LENGTH - result.length() ) );
97 }
98 }
99 return result.toString();
100 }
101
102 private static boolean isMultiLineExceptionMessage( Throwable t )
103 {
104 String msg = t.getLocalizedMessage();
105 if ( msg != null )
106 {
107 int countNewLines = 0;
108 for ( int i = 0, length = msg.length(); i < length; i++ )
109 {
110 if ( msg.charAt( i ) == '\n' )
111 {
112 if ( ++countNewLines == 2 )
113 {
114 break;
115 }
116 }
117 }
118 return countNewLines > 1 || countNewLines == 1 && !msg.trim().endsWith( "\n" );
119 }
120 return false;
121 }
122
123 private static String getTruncatedMessage( String msg, int i )
124 {
125 if ( i < 0 )
126 {
127 return "";
128 }
129 if ( msg == null )
130 {
131 return "";
132 }
133 String substring = msg.substring( 0, Math.min( i, msg.length() ) );
134 if ( i < msg.length() )
135 {
136 return " " + substring + "...";
137 }
138 else
139 {
140 return " " + substring;
141 }
142 }
143
144
145 @Override
146 public String writeTrimmedTraceToString()
147 {
148 String text = writeTraceToString();
149
150 String marker = "at " + testClass + "." + testMethod;
151
152 String[] lines = StringUtils.split( text, "\n" );
153 int lastLine = lines.length - 1;
154 int causedByLine = -1;
155
156 for ( int i = 1; i < lines.length; i++ )
157 {
158 String line = lines[i].trim();
159 if ( line.startsWith( marker ) )
160 {
161 lastLine = i;
162 }
163 else if ( line.startsWith( "Caused by" ) )
164 {
165 causedByLine = i;
166 break;
167 }
168 }
169
170 StringBuilder trace = new StringBuilder();
171 for ( int i = 0; i <= lastLine; i++ )
172 {
173 trace.append( lines[i] );
174 trace.append( "\n" );
175 }
176
177 if ( causedByLine != -1 )
178 {
179 for ( int i = causedByLine; i < lines.length; i++ )
180 {
181 trace.append( lines[i] );
182 trace.append( "\n" );
183 }
184 }
185 return trace.toString();
186 }
187
188 @Override
189 public SafeThrowable getThrowable()
190 {
191 return new SafeThrowable( t );
192 }
193 }