Home | History | Annotate | Download | only in etc
      1 <?xml version="1.0"?>
      2 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
      3         xmlns:lxslt="http://xml.apache.org/xslt"
      4         xmlns:stringutils="xalan://org.apache.tools.ant.util.StringUtils">
      5 <xsl:output method="html" indent="yes" encoding="US-ASCII"
      6   doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" />
      7 <xsl:decimal-format decimal-separator="." grouping-separator="," />
      8 <!--
      9    Licensed to the Apache Software Foundation (ASF) under one or more
     10    contributor license agreements.  See the NOTICE file distributed with
     11    this work for additional information regarding copyright ownership.
     12    The ASF licenses this file to You under the Apache License, Version 2.0
     13    (the "License"); you may not use this file except in compliance with
     14    the License.  You may obtain a copy of the License at
     15 
     16        http://www.apache.org/licenses/LICENSE-2.0
     17 
     18    Unless required by applicable law or agreed to in writing, software
     19    distributed under the License is distributed on an "AS IS" BASIS,
     20    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     21    See the License for the specific language governing permissions and
     22    limitations under the License.
     23  -->
     24 
     25 <xsl:param name="TITLE">Unit Test Results.</xsl:param>
     26 
     27 <!--
     28 
     29  Sample stylesheet to be used with Ant JUnitReport output.
     30 
     31  It creates a non-framed report that can be useful to send via
     32  e-mail or such.
     33 
     34 -->
     35 <xsl:template match="testsuites">
     36     <html>
     37         <head>
     38             <title><xsl:value-of select="$TITLE"/></title>
     39     <style type="text/css">
     40       body {
     41         font:normal 68% verdana,arial,helvetica;
     42         color:#000000;
     43       }
     44       table tr td, table tr th {
     45           font-size: 68%;
     46       }
     47       table.details tr th{
     48         font-weight: bold;
     49         text-align:left;
     50         background:#a6caf0;
     51       }
     52       table.details tr td{
     53         background:#eeeee0;
     54       }
     55 
     56       p {
     57         line-height:1.5em;
     58         margin-top:0.5em; margin-bottom:1.0em;
     59       }
     60       h1 {
     61         margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
     62       }
     63       h2 {
     64         margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
     65       }
     66       h3 {
     67         margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
     68       }
     69       h4 {
     70         margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
     71       }
     72       h5 {
     73         margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
     74       }
     75       h6 {
     76         margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
     77       }
     78       .Error {
     79         font-weight:bold; color:red;
     80       }
     81       .Failure {
     82         font-weight:bold; color:purple;
     83       }
     84       .Properties {
     85         text-align:right;
     86       }
     87       </style>
     88       <script type="text/javascript" language="JavaScript">
     89         var TestCases = new Array();
     90         var cur;
     91         <xsl:for-each select="./testsuite">
     92             <xsl:apply-templates select="properties"/>
     93         </xsl:for-each>
     94 
     95        </script>
     96        <script type="text/javascript" language="JavaScript"><![CDATA[
     97         function displayProperties (name) {
     98           var win = window.open('','JUnitSystemProperties','scrollbars=1,resizable=1');
     99           var doc = win.document;
    100           doc.open();
    101           doc.write("<html><head><title>Properties of " + name + "</title>");
    102           doc.write("<style>")
    103           doc.write("body {font:normal 68% verdana,arial,helvetica; color:#000000; }");
    104           doc.write("table tr td, table tr th { font-size: 68%; }");
    105           doc.write("table.properties { border-collapse:collapse; border-left:solid 1 #cccccc; border-top:solid 1 #cccccc; padding:5px; }");
    106           doc.write("table.properties th { text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#eeeeee; }");
    107           doc.write("table.properties td { font:normal; text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#fffffff; }");
    108           doc.write("h3 { margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica }");
    109           doc.write("</style>");
    110           doc.write("</head><body>");
    111           doc.write("<h3>Properties of " + name + "</h3>");
    112           doc.write("<div align=\"right\"><a href=\"javascript:window.close();\">Close</a></div>");
    113           doc.write("<table class='properties'>");
    114           doc.write("<tr><th>Name</th><th>Value</th></tr>");
    115           for (prop in TestCases[name]) {
    116             doc.write("<tr><th>" + prop + "</th><td>" + TestCases[name][prop] + "</td></tr>");
    117           }
    118           doc.write("</table>");
    119           doc.write("</body></html>");
    120           doc.close();
    121           win.focus();
    122         }
    123       ]]>
    124       </script>
    125         </head>
    126         <body>
    127             <a name="top"></a>
    128             <xsl:call-template name="pageHeader"/>
    129 
    130             <!-- Summary part -->
    131             <xsl:call-template name="summary"/>
    132             <hr size="1" width="95%" align="left"/>
    133 
    134             <!-- Package List part -->
    135             <xsl:call-template name="packagelist"/>
    136             <hr size="1" width="95%" align="left"/>
    137 
    138             <!-- For each package create its part -->
    139             <xsl:call-template name="packages"/>
    140             <hr size="1" width="95%" align="left"/>
    141 
    142             <!-- For each class create the  part -->
    143             <xsl:call-template name="classes"/>
    144 
    145         </body>
    146     </html>
    147 </xsl:template>
    148 
    149 
    150 
    151     <!-- ================================================================== -->
    152     <!-- Write a list of all packages with an hyperlink to the anchor of    -->
    153     <!-- of the package name.                                               -->
    154     <!-- ================================================================== -->
    155     <xsl:template name="packagelist">
    156         <h2>Packages</h2>
    157         Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.
    158         <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
    159             <xsl:call-template name="testsuite.test.header"/>
    160             <!-- list all packages recursively -->
    161             <xsl:for-each select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
    162                 <xsl:sort select="@package"/>
    163                 <xsl:variable name="testsuites-in-package" select="/testsuites/testsuite[./@package = current()/@package]"/>
    164                 <xsl:variable name="testCount" select="sum($testsuites-in-package/@tests)"/>
    165                 <xsl:variable name="errorCount" select="sum($testsuites-in-package/@errors)"/>
    166                 <xsl:variable name="failureCount" select="sum($testsuites-in-package/@failures)"/>
    167                 <xsl:variable name="timeCount" select="sum($testsuites-in-package/@time)"/>
    168 
    169                 <!-- write a summary for the package -->
    170                 <tr valign="top">
    171                     <!-- set a nice color depending if there is an error/failure -->
    172                     <xsl:attribute name="class">
    173                         <xsl:choose>
    174                             <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
    175                             <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
    176                         </xsl:choose>
    177                     </xsl:attribute>
    178                     <td><a href="#{@package}"><xsl:value-of select="@package"/></a></td>
    179                     <td><xsl:value-of select="$testCount"/></td>
    180                     <td><xsl:value-of select="$errorCount"/></td>
    181                     <td><xsl:value-of select="$failureCount"/></td>
    182                     <td>
    183                     <xsl:call-template name="display-time">
    184                         <xsl:with-param name="value" select="$timeCount"/>
    185                     </xsl:call-template>
    186                     </td>
    187                     <td><xsl:value-of select="$testsuites-in-package/@timestamp"/></td>
    188                     <td><xsl:value-of select="$testsuites-in-package/@hostname"/></td>
    189                 </tr>
    190             </xsl:for-each>
    191         </table>
    192     </xsl:template>
    193 
    194 
    195     <!-- ================================================================== -->
    196     <!-- Write a package level report                                       -->
    197     <!-- It creates a table with values from the document:                  -->
    198     <!-- Name | Tests | Errors | Failures | Time                            -->
    199     <!-- ================================================================== -->
    200     <xsl:template name="packages">
    201         <!-- create an anchor to this package name -->
    202         <xsl:for-each select="/testsuites/testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
    203             <xsl:sort select="@package"/>
    204                 <a name="{@package}"></a>
    205                 <h3>Package <xsl:value-of select="@package"/></h3>
    206 
    207                 <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
    208                     <xsl:call-template name="testsuite.test.header"/>
    209 
    210                     <!-- match the testsuites of this package -->
    211                     <xsl:apply-templates select="/testsuites/testsuite[./@package = current()/@package]" mode="print.test"/>
    212                 </table>
    213                 <a href="#top">Back to top</a>
    214                 <p/>
    215                 <p/>
    216         </xsl:for-each>
    217     </xsl:template>
    218 
    219     <xsl:template name="classes">
    220         <xsl:for-each select="testsuite">
    221             <xsl:sort select="@name"/>
    222             <!-- create an anchor to this class name -->
    223             <a name="{@name}"></a>
    224             <h3>TestCase <xsl:value-of select="@name"/></h3>
    225 
    226             <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
    227               <xsl:call-template name="testcase.test.header"/>
    228               <!--
    229               test can even not be started at all (failure to load the class)
    230               so report the error directly
    231               -->
    232                 <xsl:if test="./error">
    233                     <tr class="Error">
    234                         <td colspan="4"><xsl:apply-templates select="./error"/></td>
    235                     </tr>
    236                 </xsl:if>
    237                 <xsl:apply-templates select="./testcase" mode="print.test"/>
    238             </table>
    239             <div class="Properties">
    240                 <a>
    241                     <xsl:attribute name="href">javascript:displayProperties('<xsl:value-of select="@package"/>.<xsl:value-of select="@name"/>');</xsl:attribute>
    242                     Properties &#187;
    243                 </a>
    244             </div>
    245             <p/>
    246 
    247             <a href="#top">Back to top</a>
    248         </xsl:for-each>
    249     </xsl:template>
    250 
    251     <xsl:template name="summary">
    252         <h2>Summary</h2>
    253         <xsl:variable name="testCount" select="sum(testsuite/@tests)"/>
    254         <xsl:variable name="errorCount" select="sum(testsuite/@errors)"/>
    255         <xsl:variable name="failureCount" select="sum(testsuite/@failures)"/>
    256         <xsl:variable name="timeCount" select="sum(testsuite/@time)"/>
    257         <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
    258         <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
    259         <tr valign="top">
    260             <th>Tests</th>
    261             <th>Failures</th>
    262             <th>Errors</th>
    263             <th>Success rate</th>
    264             <th>Time</th>
    265         </tr>
    266         <tr valign="top">
    267             <xsl:attribute name="class">
    268                 <xsl:choose>
    269                     <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
    270                     <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
    271                 </xsl:choose>
    272             </xsl:attribute>
    273             <td><xsl:value-of select="$testCount"/></td>
    274             <td><xsl:value-of select="$failureCount"/></td>
    275             <td><xsl:value-of select="$errorCount"/></td>
    276             <td>
    277                 <xsl:call-template name="display-percent">
    278                     <xsl:with-param name="value" select="$successRate"/>
    279                 </xsl:call-template>
    280             </td>
    281             <td>
    282                 <xsl:call-template name="display-time">
    283                     <xsl:with-param name="value" select="$timeCount"/>
    284                 </xsl:call-template>
    285             </td>
    286 
    287         </tr>
    288         </table>
    289         <table border="0" width="95%">
    290         <tr>
    291         <td style="text-align: justify;">
    292         Note: <i>failures</i> are anticipated and checked for with assertions while <i>errors</i> are unanticipated.
    293         </td>
    294         </tr>
    295         </table>
    296     </xsl:template>
    297 
    298   <!--
    299    Write properties into a JavaScript data structure.
    300    This is based on the original idea by Erik Hatcher (ehatcher (a] apache.org)
    301    -->
    302   <xsl:template match="properties">
    303     cur = TestCases['<xsl:value-of select="../@package"/>.<xsl:value-of select="../@name"/>'] = new Array();
    304     <xsl:for-each select="property">
    305     <xsl:sort select="@name"/>
    306         cur['<xsl:value-of select="@name"/>'] = '<xsl:call-template name="JS-escape"><xsl:with-param name="string" select="@value"/></xsl:call-template>';
    307     </xsl:for-each>
    308   </xsl:template>
    309 
    310 <!-- Page HEADER -->
    311 <xsl:template name="pageHeader">
    312     <h1><xsl:value-of select="$TITLE"/></h1>
    313     <table width="100%">
    314     <tr>
    315         <td align="left"></td>
    316         <td align="right">Designed for use with <a href='http://www.junit.org'>JUnit</a> and <a href='http://ant.apache.org/ant'>Ant</a>.</td>
    317     </tr>
    318     </table>
    319     <hr size="1"/>
    320 </xsl:template>
    321 
    322 <xsl:template match="testsuite" mode="header">
    323     <tr valign="top">
    324         <th width="80%">Name</th>
    325         <th>Tests</th>
    326         <th>Errors</th>
    327         <th>Failures</th>
    328         <th nowrap="nowrap">Time(s)</th>
    329     </tr>
    330 </xsl:template>
    331 
    332 <!-- class header -->
    333 <xsl:template name="testsuite.test.header">
    334     <tr valign="top">
    335         <th width="80%">Name</th>
    336         <th>Tests</th>
    337         <th>Errors</th>
    338         <th>Failures</th>
    339         <th nowrap="nowrap">Time(s)</th>
    340         <th nowrap="nowrap">Time Stamp</th>
    341         <th>Host</th>
    342     </tr>
    343 </xsl:template>
    344 
    345 <!-- method header -->
    346 <xsl:template name="testcase.test.header">
    347     <tr valign="top">
    348         <th>Name</th>
    349         <th>Status</th>
    350         <th width="80%">Type</th>
    351         <th nowrap="nowrap">Time(s)</th>
    352     </tr>
    353 </xsl:template>
    354 
    355 
    356 <!-- class information -->
    357 <xsl:template match="testsuite" mode="print.test">
    358     <tr valign="top">
    359         <!-- set a nice color depending if there is an error/failure -->
    360         <xsl:attribute name="class">
    361             <xsl:choose>
    362                 <xsl:when test="@failures[.&gt; 0]">Failure</xsl:when>
    363                 <xsl:when test="@errors[.&gt; 0]">Error</xsl:when>
    364             </xsl:choose>
    365         </xsl:attribute>
    366 
    367         <!-- print testsuite information -->
    368         <td><a href="#{@name}"><xsl:value-of select="@name"/></a></td>
    369         <td><xsl:value-of select="@tests"/></td>
    370         <td><xsl:value-of select="@errors"/></td>
    371         <td><xsl:value-of select="@failures"/></td>
    372         <td>
    373             <xsl:call-template name="display-time">
    374                 <xsl:with-param name="value" select="@time"/>
    375             </xsl:call-template>
    376         </td>
    377         <td><xsl:apply-templates select="@timestamp"/></td>
    378         <td><xsl:apply-templates select="@hostname"/></td>
    379     </tr>
    380 </xsl:template>
    381 
    382 <xsl:template match="testcase" mode="print.test">
    383     <tr valign="top">
    384         <xsl:attribute name="class">
    385             <xsl:choose>
    386                 <xsl:when test="failure | error">Error</xsl:when>
    387             </xsl:choose>
    388         </xsl:attribute>
    389         <td><xsl:value-of select="@name"/></td>
    390         <xsl:choose>
    391             <xsl:when test="failure">
    392                 <td>Failure</td>
    393                 <td><xsl:apply-templates select="failure"/></td>
    394             </xsl:when>
    395             <xsl:when test="error">
    396                 <td>Error</td>
    397                 <td><xsl:apply-templates select="error"/></td>
    398             </xsl:when>
    399             <xsl:otherwise>
    400                 <td>Success</td>
    401                 <td></td>
    402             </xsl:otherwise>
    403         </xsl:choose>
    404         <td>
    405             <xsl:call-template name="display-time">
    406                 <xsl:with-param name="value" select="@time"/>
    407             </xsl:call-template>
    408         </td>
    409     </tr>
    410 </xsl:template>
    411 
    412 
    413 <xsl:template match="failure">
    414     <xsl:call-template name="display-failures"/>
    415 </xsl:template>
    416 
    417 <xsl:template match="error">
    418     <xsl:call-template name="display-failures"/>
    419 </xsl:template>
    420 
    421 <!-- Style for the error and failure in the tescase template -->
    422 <xsl:template name="display-failures">
    423     <xsl:choose>
    424         <xsl:when test="not(@message)">N/A</xsl:when>
    425         <xsl:otherwise>
    426             <xsl:value-of select="@message"/>
    427         </xsl:otherwise>
    428     </xsl:choose>
    429     <!-- display the stacktrace -->
    430     <code>
    431         <br/><br/>
    432         <xsl:call-template name="br-replace">
    433             <xsl:with-param name="word" select="."/>
    434         </xsl:call-template>
    435     </code>
    436     <!-- the later is better but might be problematic for non-21" monitors... -->
    437     <!--pre><xsl:value-of select="."/></pre-->
    438 </xsl:template>
    439 
    440 <xsl:template name="JS-escape">
    441     <xsl:param name="string"/>
    442     <xsl:param name="tmp1" select="stringutils:replace(string($string),'\','\\')"/>
    443     <xsl:param name="tmp2" select="stringutils:replace(string($tmp1),&quot;'&quot;,&quot;\&apos;&quot;)"/>
    444     <xsl:value-of select="$tmp2"/>
    445 </xsl:template>
    446 
    447 
    448 <!--
    449     template that will convert a carriage return into a br tag
    450     @param word the text from which to convert CR to BR tag
    451 -->
    452 <xsl:template name="br-replace">
    453     <xsl:param name="word"/>
    454     <xsl:value-of disable-output-escaping="yes" select='stringutils:replace(string($word),"&#xA;","&lt;br/>")'/>
    455 </xsl:template>
    456 
    457 <xsl:template name="display-time">
    458     <xsl:param name="value"/>
    459     <xsl:value-of select="format-number($value,'0.000')"/>
    460 </xsl:template>
    461 
    462 <xsl:template name="display-percent">
    463     <xsl:param name="value"/>
    464     <xsl:value-of select="format-number($value,'0.00%')"/>
    465 </xsl:template>
    466 
    467 </xsl:stylesheet>
    468