1 package org.apache.maven.plugins.surefire.report;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import org.xml.sax.Attributes;
20 import org.xml.sax.SAXException;
21 import org.xml.sax.helpers.DefaultHandler;
22
23 import javax.xml.parsers.ParserConfigurationException;
24 import javax.xml.parsers.SAXParser;
25 import javax.xml.parsers.SAXParserFactory;
26 import java.io.File;
27 import java.io.IOException;
28 import java.text.NumberFormat;
29 import java.text.ParseException;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.StringTokenizer;
35
36 public class ReportTestSuite
37 extends DefaultHandler
38 {
39 private List testCases;
40
41 private int numberOfErrors;
42
43 private int numberOfFailures;
44
45 private int numberOfSkipped;
46
47 private int numberOfTests;
48
49 private String name;
50
51 private String fullClassName;
52
53 private String packageName;
54
55 private float timeElapsed;
56
57 private NumberFormat numberFormat = NumberFormat.getInstance();
58
59 /**
60 * @noinspection StringBufferField
61 */
62 private StringBuffer currentElement;
63
64 private ReportTestCase testCase;
65
66 public void parse( String xmlPath )
67 throws ParserConfigurationException, SAXException, IOException
68 {
69 SAXParserFactory factory = SAXParserFactory.newInstance();
70
71 SAXParser saxParser = factory.newSAXParser();
72
73 saxParser.parse( new File( xmlPath ), this );
74 }
75
76
77 private int getAttributeAsInt( Attributes attributes, String name )
78 {
79
80 String valueAsString = attributes.getValue( name );
81 if ( valueAsString != null )
82 {
83 return Integer.parseInt( valueAsString );
84 }
85 return 0;
86 }
87
88 public void startElement( String uri, String localName, String qName, Attributes attributes )
89 throws SAXException
90 {
91 try
92 {
93 if ( "testsuite".equals( qName ) )
94 {
95 numberOfErrors = getAttributeAsInt( attributes, "errors" );
96 numberOfFailures = getAttributeAsInt( attributes, "failures" );
97 numberOfSkipped = getAttributeAsInt( attributes, "skipped" );
98 numberOfTests = getAttributeAsInt( attributes, "tests" );
99
100 Number time = numberFormat.parse( attributes.getValue( "time" ) );
101
102 timeElapsed = time.floatValue();
103
104
105 if ( attributes.getValue( "group" ) != null && !"".equals( attributes.getValue( "group" ) ) )
106 {
107 packageName = attributes.getValue( "group" );
108
109 name = attributes.getValue( "name" );
110
111 fullClassName = packageName + "." + name;
112 }
113 else
114 {
115 fullClassName = attributes.getValue( "name" );
116
117 name = fullClassName.substring( fullClassName.lastIndexOf( "." ) + 1, fullClassName.length() );
118
119 int lastDotPosition = fullClassName.lastIndexOf( "." );
120 if ( lastDotPosition < 0 )
121 {
122
123 packageName = "";
124 }
125 else
126 {
127 packageName = fullClassName.substring( 0, lastDotPosition );
128 }
129 }
130
131 testCases = new ArrayList();
132 }
133 else if ( "testcase".equals( qName ) )
134 {
135 currentElement = new StringBuffer();
136
137 testCase = new ReportTestCase();
138
139 testCase.setFullClassName( fullClassName );
140
141 testCase.setName( attributes.getValue( "name" ) );
142
143 testCase.setClassName( name );
144
145 String timeAsString = attributes.getValue( "time" );
146
147 Number time = new Integer( 0 );
148
149 if ( timeAsString != null )
150 {
151 time = numberFormat.parse( timeAsString );
152 }
153
154 testCase.setTime( time.floatValue() );
155
156 testCase.setFullName( packageName + "." + name + "." + testCase.getName() );
157 }
158 else if ( "failure".equals( qName ) )
159 {
160 testCase.addFailure( attributes.getValue( "message" ), attributes.getValue( "type" ) );
161 }
162 else if ( "error".equals( qName ) )
163 {
164 testCase.addFailure( attributes.getValue( "message" ), attributes.getValue( "type" ) );
165 }
166 }
167 catch ( ParseException e )
168 {
169 throw new SAXException( e.getMessage(), e );
170 }
171 }
172
173 public void endElement( String uri, String localName, String qName )
174 throws SAXException
175 {
176 if ( "testcase".equals( qName ) )
177 {
178 testCases.add( testCase );
179 }
180 else if ( "failure".equals( qName ) )
181 {
182 Map failure = testCase.getFailure();
183
184 failure.put( "detail", parseCause( currentElement.toString() ) );
185 }
186 else if ( "error".equals( qName ) )
187 {
188 Map error = testCase.getFailure();
189
190 error.put( "detail", parseCause( currentElement.toString() ) );
191 }
192 }
193
194 public void characters( char[] ch, int start, int length )
195 throws SAXException
196 {
197 String s = new String( ch, start, length );
198
199 if ( ! "".equals( s.trim() ) )
200 {
201 currentElement.append( s );
202 }
203 }
204
205 public List getTestCases()
206 {
207 return this.testCases;
208 }
209
210 public int getNumberOfErrors()
211 {
212 return numberOfErrors;
213 }
214
215 public void setNumberOfErrors( int numberOfErrors )
216 {
217 this.numberOfErrors = numberOfErrors;
218 }
219
220 public int getNumberOfFailures()
221 {
222 return numberOfFailures;
223 }
224
225 public void setNumberOfFailures( int numberOfFailures )
226 {
227 this.numberOfFailures = numberOfFailures;
228 }
229
230 public int getNumberOfSkipped()
231 {
232 return numberOfSkipped;
233 }
234
235 public void setNumberOfSkipped( int numberOfSkipped )
236 {
237 this.numberOfSkipped = numberOfSkipped;
238 }
239
240 public int getNumberOfTests()
241 {
242 return numberOfTests;
243 }
244
245 public void setNumberOfTests( int numberOfTests )
246 {
247 this.numberOfTests = numberOfTests;
248 }
249
250 public String getName()
251 {
252 return name;
253 }
254
255 public void setName( String name )
256 {
257 this.name = name;
258 }
259
260 public String getFName()
261 {
262 return name;
263 }
264
265 public void setFName( String name )
266 {
267 this.name = name;
268 }
269
270 public String getPackageName()
271 {
272 return packageName;
273 }
274
275 public void setPackageName( String packageName )
276 {
277 this.packageName = packageName;
278 }
279
280 public float getTimeElapsed()
281 {
282 return this.timeElapsed;
283 }
284
285 public void setTimeElapsed( float timeElapsed )
286 {
287 this.timeElapsed = timeElapsed;
288 }
289
290 private List parseCause( String detail )
291 {
292 String fullName = testCase.getFullName();
293 String name = fullName.substring( fullName.lastIndexOf( "." ) + 1 );
294 return parseCause( detail, name );
295 }
296
297 private List parseCause( String detail, String compareTo )
298 {
299 StringTokenizer stringTokenizer = new StringTokenizer( detail, "\n" );
300 List parsedDetail = new ArrayList( stringTokenizer.countTokens() );
301
302 while ( stringTokenizer.hasMoreTokens() )
303 {
304 String lineString = stringTokenizer.nextToken().trim();
305 parsedDetail.add( lineString );
306 if ( lineString.indexOf( compareTo ) >= 0 )
307 {
308 break;
309 }
310 }
311
312 return parsedDetail;
313 }
314
315 public void setTestCases( List testCases )
316 {
317 this.testCases = Collections.unmodifiableList( testCases );
318 }
319 }