Coverage Report - org.apache.maven.plugins.surefire.report.TestSuiteXmlParser
 
Classes in this File Line Coverage Branch Coverage Complexity
TestSuiteXmlParser
89%
83/93
82%
33/40
5.167
 
 1  
 package org.apache.maven.plugins.surefire.report;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *     http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.io.File;
 23  
 import java.io.IOException;
 24  
 import java.text.NumberFormat;
 25  
 import java.text.ParseException;
 26  
 import java.util.ArrayList;
 27  
 import java.util.Collection;
 28  
 import java.util.HashMap;
 29  
 import java.util.List;
 30  
 import java.util.Locale;
 31  
 import java.util.Map;
 32  
 import java.util.StringTokenizer;
 33  
 
 34  
 import javax.xml.parsers.ParserConfigurationException;
 35  
 import javax.xml.parsers.SAXParser;
 36  
 import javax.xml.parsers.SAXParserFactory;
 37  
 
 38  
 import org.xml.sax.Attributes;
 39  
 import org.xml.sax.SAXException;
 40  
 import org.xml.sax.helpers.DefaultHandler;
 41  
 
 42  
 /**
 43  
  * @version $Id: TestSuiteXmlParser.java 1125058 2011-05-19 19:06:07Z krosenvold $
 44  
  */
 45  5
 public class TestSuiteXmlParser
 46  
     extends DefaultHandler
 47  
 {
 48  
     private ReportTestSuite defaultSuite;
 49  
     private ReportTestSuite currentSuite;
 50  
     private Map classesToSuites;
 51  5
     private final NumberFormat numberFormat = NumberFormat.getInstance( Locale.ENGLISH);
 52  
 
 53  
     /**
 54  
      * @noinspection StringBufferField
 55  
      */
 56  
     private StringBuffer currentElement;
 57  
 
 58  
     private ReportTestCase testCase;
 59  
 
 60  
     public Collection parse( String xmlPath )
 61  
         throws ParserConfigurationException, SAXException, IOException
 62  
     {
 63  11
         SAXParserFactory factory = SAXParserFactory.newInstance();
 64  
 
 65  11
         SAXParser saxParser = factory.newSAXParser();
 66  
 
 67  11
         classesToSuites = new HashMap();
 68  
 
 69  11
         saxParser.parse( new File( xmlPath ), this );
 70  
 
 71  11
         if ( currentSuite != defaultSuite )
 72  
         { // omit the defaultSuite if it's empty and there are alternatives
 73  1
             if ( defaultSuite.getNumberOfTests() == 0 )
 74  
             {
 75  1
                 classesToSuites.remove( defaultSuite.getFullClassName() );
 76  
             }
 77  
         }
 78  
 
 79  11
         return classesToSuites.values();
 80  
     }
 81  
 
 82  
     /** {@inheritDoc} */
 83  
     public void startElement( String uri, String localName, String qName, Attributes attributes )
 84  
         throws SAXException
 85  
     {
 86  
         try
 87  
         {
 88  674
             if ( "testsuite".equals( qName ) )
 89  
             {
 90  11
                 currentSuite = defaultSuite = new ReportTestSuite();
 91  
 
 92  
                 try
 93  
                 {
 94  11
                     Number time = numberFormat.parse( attributes.getValue( "time" ) );
 95  
 
 96  10
                     defaultSuite.setTimeElapsed( time.floatValue() );
 97  
                 }
 98  1
                 catch ( NullPointerException npe )
 99  
                 {
 100  1
                     System.err.println( "WARNING: no time attribute found on testsuite element" );
 101  10
                 }
 102  
 
 103  
                 //check if group attribute is existing
 104  11
                 if ( attributes.getValue( "group" ) != null && !"".equals( attributes.getValue( "group" ) ) )
 105  
                 {
 106  0
                     String packageName = attributes.getValue( "group" );
 107  0
                     String name = attributes.getValue( "name" );
 108  
 
 109  0
                     defaultSuite.setFullClassName( packageName + "." + name );
 110  0
                 }
 111  
                 else
 112  
                 {
 113  11
                     String fullClassName = attributes.getValue( "name" );
 114  11
                     defaultSuite.setFullClassName( fullClassName );
 115  
                 }
 116  
 
 117  11
                 classesToSuites.put( defaultSuite.getFullClassName(), defaultSuite );
 118  
             }
 119  663
             else if ( "testcase".equals( qName ) )
 120  
             {
 121  57
                 currentElement = new StringBuffer();
 122  
 
 123  57
                 testCase = new ReportTestCase();
 124  
 
 125  57
                 testCase.setName( attributes.getValue( "name" ) );
 126  
 
 127  57
                 String fullClassName = attributes.getValue( "classname" );
 128  
 
 129  
                 // if the testcase declares its own classname, it may need to belong to its own suite
 130  57
                 if ( fullClassName != null )
 131  
                 {
 132  2
                     currentSuite = (ReportTestSuite) classesToSuites.get( fullClassName );
 133  2
                     if ( currentSuite == null )
 134  
                     {
 135  2
                         currentSuite = new ReportTestSuite();
 136  2
                         currentSuite.setFullClassName( fullClassName );
 137  2
                         classesToSuites.put( fullClassName, currentSuite );
 138  
                     }
 139  
                 }
 140  
 
 141  57
                 testCase.setFullClassName( currentSuite.getFullClassName() );
 142  57
                 testCase.setClassName( currentSuite.getName() );
 143  57
                 testCase.setFullName( currentSuite.getFullClassName() + "." + testCase.getName() );
 144  
 
 145  57
                 String timeAsString = attributes.getValue( "time" );
 146  
 
 147  57
                 Number time = new Integer( 0 );
 148  
 
 149  57
                 if ( timeAsString != null )
 150  
                 {
 151  54
                     time = numberFormat.parse( timeAsString );
 152  
                 }
 153  
 
 154  57
                 testCase.setTime( time.floatValue() );
 155  
 
 156  57
                 if ( currentSuite != defaultSuite )
 157  
                 {
 158  2
                     currentSuite.setTimeElapsed( time.floatValue() + currentSuite.getTimeElapsed() );
 159  
                 }
 160  57
             }
 161  606
             else if ( "failure".equals( qName ) )
 162  
             {
 163  9
                 testCase.addFailure( attributes.getValue( "message" ), attributes.getValue( "type" ) );
 164  9
                 currentSuite.setNumberOfFailures( 1 + currentSuite.getNumberOfFailures() );
 165  
             }
 166  597
             else if ( "error".equals( qName ) )
 167  
             {
 168  5
                 testCase.addFailure( attributes.getValue( "message" ), attributes.getValue( "type" ) );
 169  5
                 currentSuite.setNumberOfErrors( 1 + currentSuite.getNumberOfErrors() );
 170  
             }
 171  592
             else if ( "skipped".equals( qName ) )
 172  
             {
 173  0
                 testCase.addFailure( "skipped", "skipped" ); // TODO extract real reasons
 174  0
                 currentSuite.setNumberOfSkipped( 1 + currentSuite.getNumberOfSkipped() );
 175  
             }
 176  
         }
 177  0
         catch ( ParseException e )
 178  
         {
 179  0
             throw new SAXException( e.getMessage(), e );
 180  674
         }
 181  674
     }
 182  
 
 183  
     /** {@inheritDoc} */
 184  
     public void endElement( String uri, String localName, String qName )
 185  
         throws SAXException
 186  
     {
 187  674
         if ( "testcase".equals( qName ) )
 188  
         {
 189  57
             currentSuite.getTestCases().add( testCase );
 190  
         }
 191  617
         else if ( "failure".equals( qName ) )
 192  
         {
 193  9
             Map failure = testCase.getFailure();
 194  
 
 195  9
             failure.put( "detail", parseCause( currentElement.toString() ) );
 196  9
         }
 197  608
         else if ( "error".equals( qName ) )
 198  
         {
 199  5
             Map error = testCase.getFailure();
 200  
 
 201  5
             error.put( "detail", parseCause( currentElement.toString() ) );
 202  5
         }
 203  603
         else if ( "time".equals( qName ) )
 204  
         {
 205  
             try
 206  
             {
 207  2
                 Number time = numberFormat.parse( currentElement.toString() );
 208  2
                 defaultSuite.setTimeElapsed( time.floatValue() );
 209  
             }
 210  0
             catch ( ParseException e )
 211  
             {
 212  0
                 throw new SAXException( e.getMessage(), e );
 213  2
             }
 214  
         }
 215  
         // TODO extract real skipped reasons
 216  674
     }
 217  
 
 218  
     /** {@inheritDoc} */
 219  
     public void characters( char[] ch, int start, int length )
 220  
         throws SAXException
 221  
     {
 222  1558
         String s = new String( ch, start, length );
 223  
 
 224  1558
         if ( !"".equals( s.trim() ) )
 225  
         {
 226  824
             currentElement.append( s );
 227  
         }
 228  1558
     }
 229  
 
 230  
     private List parseCause( String detail )
 231  
     {
 232  14
         String fullName = testCase.getFullName();
 233  14
         String name = fullName.substring( fullName.lastIndexOf( "." ) + 1 );
 234  14
         return parseCause( detail, name );
 235  
     }
 236  
 
 237  
     private List parseCause( String detail, String compareTo )
 238  
     {
 239  14
         StringTokenizer stringTokenizer = new StringTokenizer( detail, "\n" );
 240  14
         List parsedDetail = new ArrayList( stringTokenizer.countTokens() );
 241  
 
 242  61
         while ( stringTokenizer.hasMoreTokens() )
 243  
         {
 244  61
             String lineString = stringTokenizer.nextToken().trim();
 245  61
             parsedDetail.add( lineString );
 246  61
             if ( lineString.indexOf( compareTo ) >= 0 )
 247  
             {
 248  14
                 break;
 249  
             }
 250  47
         }
 251  
 
 252  14
         return parsedDetail;
 253  
     }
 254  
 
 255  
 }