1 package org.apache.maven.surefire.its.misc;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.surefire.its.misc.ReportTestCase;
23 import org.apache.maven.surefire.its.misc.ReportTestSuite;
24
25 import javax.xml.parsers.ParserConfigurationException;
26 import javax.xml.parsers.SAXParser;
27 import javax.xml.parsers.SAXParserFactory;
28 import java.io.File;
29 import java.io.IOException;
30 import java.text.NumberFormat;
31 import java.text.ParseException;
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.StringTokenizer;
38
39 import org.xml.sax.Attributes;
40 import org.xml.sax.SAXException;
41 import org.xml.sax.helpers.DefaultHandler;
42
43
44
45
46 public class TestSuiteXmlParser
47 extends DefaultHandler
48 {
49 private ReportTestSuite defaultSuite;
50 private ReportTestSuite currentSuite;
51 private Map classesToSuites;
52 private final NumberFormat numberFormat = NumberFormat.getInstance();
53
54
55
56
57 private StringBuffer currentElement;
58
59 private ReportTestCase testCase;
60
61 public Collection parse( String xmlPath )
62 throws ParserConfigurationException, SAXException, IOException
63 {
64 SAXParserFactory factory = SAXParserFactory.newInstance();
65
66 SAXParser saxParser = factory.newSAXParser();
67
68 classesToSuites = new HashMap();
69
70 saxParser.parse( new File( xmlPath ), this );
71
72 if ( currentSuite != defaultSuite )
73 {
74 if ( defaultSuite.getNumberOfTests() == 0 )
75 {
76 classesToSuites.remove( defaultSuite.getFullClassName() );
77 }
78 }
79
80 return classesToSuites.values();
81 }
82
83
84 public void startElement( String uri, String localName, String qName, Attributes attributes )
85 throws SAXException
86 {
87 try
88 {
89 if ( "testsuite".equals( qName ) )
90 {
91 currentSuite = defaultSuite = new ReportTestSuite();
92
93 try
94 {
95 Number time = numberFormat.parse( attributes.getValue( "time" ) );
96
97 defaultSuite.setTimeElapsed( time.floatValue() );
98 }
99 catch ( NullPointerException npe )
100 {
101 System.err.println( "WARNING: no time attribute found on testsuite element" );
102 }
103
104
105 if ( attributes.getValue( "group" ) != null && !"".equals( attributes.getValue( "group" ) ) )
106 {
107 String packageName = attributes.getValue( "group" );
108 String name = attributes.getValue( "name" );
109
110 defaultSuite.setFullClassName( packageName + "." + name );
111 }
112 else
113 {
114 String fullClassName = attributes.getValue( "name" );
115 defaultSuite.setFullClassName( fullClassName );
116 }
117
118 classesToSuites.put( defaultSuite.getFullClassName(), defaultSuite );
119 }
120 else if ( "testcase".equals( qName ) )
121 {
122 currentElement = new StringBuffer();
123
124 testCase = new ReportTestCase();
125
126 testCase.setName( attributes.getValue( "name" ) );
127
128 String fullClassName = attributes.getValue( "classname" );
129
130
131 if ( fullClassName != null )
132 {
133 currentSuite = (ReportTestSuite) classesToSuites.get( fullClassName );
134 if ( currentSuite == null )
135 {
136 currentSuite = new ReportTestSuite();
137 currentSuite.setFullClassName( fullClassName );
138 classesToSuites.put( fullClassName, currentSuite );
139 }
140 }
141
142 testCase.setFullClassName( currentSuite.getFullClassName() );
143 testCase.setClassName( currentSuite.getName() );
144 testCase.setFullName( currentSuite.getFullClassName() + "." + testCase.getName() );
145
146 String timeAsString = attributes.getValue( "time" );
147
148 Number time = new Integer( 0 );
149
150 if ( timeAsString != null )
151 {
152 time = numberFormat.parse( timeAsString );
153 }
154
155 testCase.setTime( time.floatValue() );
156
157 if ( currentSuite != defaultSuite )
158 {
159 currentSuite.setTimeElapsed( time.floatValue() + currentSuite.getTimeElapsed() );
160 }
161 }
162 else if ( "failure".equals( qName ) )
163 {
164 testCase.addFailure( attributes.getValue( "message" ), attributes.getValue( "type" ) );
165 currentSuite.setNumberOfFailures( 1 + currentSuite.getNumberOfFailures() );
166 }
167 else if ( "error".equals( qName ) )
168 {
169 testCase.addFailure( attributes.getValue( "message" ), attributes.getValue( "type" ) );
170 currentSuite.setNumberOfErrors( 1 + currentSuite.getNumberOfErrors() );
171 }
172 else if ( "skipped".equals( qName ) )
173 {
174 testCase.addFailure( "skipped", "skipped" );
175 currentSuite.setNumberOfSkipped( 1 + currentSuite.getNumberOfSkipped() );
176 }
177 }
178 catch ( ParseException e )
179 {
180 throw new SAXException( e.getMessage(), e );
181 }
182 }
183
184
185 public void endElement( String uri, String localName, String qName )
186 throws SAXException
187 {
188 if ( "testcase".equals( qName ) )
189 {
190 currentSuite.getTestCases().add( testCase );
191 }
192 else if ( "failure".equals( qName ) )
193 {
194 Map failure = testCase.getFailure();
195
196 failure.put( "detail", parseCause( currentElement.toString() ) );
197 }
198 else if ( "error".equals( qName ) )
199 {
200 Map error = testCase.getFailure();
201
202 error.put( "detail", parseCause( currentElement.toString() ) );
203 }
204 else if ( "time".equals( qName ) )
205 {
206 try
207 {
208 Number time = numberFormat.parse( currentElement.toString() );
209 defaultSuite.setTimeElapsed( time.floatValue() );
210 }
211 catch ( ParseException e )
212 {
213 throw new SAXException( e.getMessage(), e );
214 }
215 }
216
217 }
218
219
220 public void characters( char[] ch, int start, int length )
221 throws SAXException
222 {
223 String s = new String( ch, start, length );
224
225 if ( !"".equals( s.trim() ) )
226 {
227 currentElement.append( s );
228 }
229 }
230
231 private List parseCause( String detail )
232 {
233 String fullName = testCase.getFullName();
234 String name = fullName.substring( fullName.lastIndexOf( "." ) + 1 );
235 return parseCause( detail, name );
236 }
237
238 private List parseCause( String detail, String compareTo )
239 {
240 StringTokenizer stringTokenizer = new StringTokenizer( detail, "\n" );
241 List parsedDetail = new ArrayList( stringTokenizer.countTokens() );
242
243 while ( stringTokenizer.hasMoreTokens() )
244 {
245 String lineString = stringTokenizer.nextToken().trim();
246 parsedDetail.add( lineString );
247 if ( lineString.indexOf( compareTo ) >= 0 )
248 {
249 break;
250 }
251 }
252
253 return parsedDetail;
254 }
255
256 }