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