You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@maven.apache.org by jv...@apache.org on 2002/12/31 08:19:44 UTC

cvs commit: jakarta-turbine-maven/src/plugins-build/junit-report junit.jsl

jvanzyl     2002/12/30 23:19:44

  Added:       src/plugins-build/changelog changelog.jsl
               src/plugins-build/checkstyle checkstyle.jsl
               src/plugins-build/jbuilder library.jsl
               src/plugins-build/jdepend jdepend.jsl
               src/plugins-build/junit-report junit.jsl
  Log:
  o Adding new jsl files.
  
  Revision  Changes    Path
  1.1                  jakarta-turbine-maven/src/plugins-build/changelog/changelog.jsl
  
  Index: changelog.jsl
  ===================================================================
  <?xml version="1.0"?>
  
  <jsl:stylesheet
    select="$doc"
    xmlns:j="jelly:core"
    xmlns:jsl="jelly:jsl"
    xmlns:x="jelly:xml"
    xmlns="dummy" trim="false">
  
    <jsl:template match="changelog">
      <document>
  
        <properties>
          <title>Changelog Report</title>
        </properties>
        <body>
          <section name="Changelog Report">
            <table>
              <tr>
                <th>Date</th>
                <th>Author</th>
                <th>File/Message</th>
              </tr>
              <x:set var="changes" select="changelog-entry"/>
              <j:forEach var="change" items="${changes}">
                <tr>
                  <td>
                    <x:expr select="$change/date"/>
                    <x:expr select="$change/time"/>
                  </td>
                  <td>
                    <x:expr select="$change/author"/>
                  </td>
                  <td>
                    <j:set var="name"><x:expr select="$change/file/name"/></j:set>
                    <a href="${pom.repository.url}${name}">${name}</a>
                    <j:set var="revision"><x:expr select="$change/file/revision"/></j:set>
                    <a href="${pom.repository.url}${name}?rev=${revision}&amp;content-type=text/vnd.viewcvs-markup">v${revision}</a>
        
                    <p/>
                    
                    
                    <!-- This works -->
                    <x:expr select="$change/msg"/>
                    
                    <!-- But this does not work ?
                    <j:set var="msg"><x:expr select="$change/msg"/></j:set>
                    ${msg}
                    ${escape.getText(msg)}
                    
                    Something to track down. Probably not going to be much
                    html in the changelog entries any way.
                    
                    -->
                    
                  </td>
                </tr>
              </j:forEach>
            </table>
          </section>
        </body>
      </document>
    </jsl:template>
  </jsl:stylesheet>
  
  
  
  1.1                  jakarta-turbine-maven/src/plugins-build/checkstyle/checkstyle.jsl
  
  Index: checkstyle.jsl
  ===================================================================
  <?xml version="1.0"?>
  
  <jsl:stylesheet
    select="$doc"
    xmlns:j="jelly:core"
    xmlns:jsl="jelly:jsl"
    xmlns:x="jelly:xml"
    xmlns="dummy" trim="false">
  
    <!-- This needs to be instantiated here to be available in the template matches -->
    <j:useBean var="mavenTool" class="org.apache.maven.MavenTool"/>
    <j:useBean var="htmlescape" class="org.apache.velocity.anakia.Escape"/>
    <j:useBean var="fileutil" class="org.apache.velocity.texen.util.FileUtil"/>
    <j:useBean var="pathtool" class="org.apache.maven.DVSLPathTool"/>
  
    <jsl:template match="checkstyle">
      <document>
  
        <properties>
          <title>Checkstyle Results</title>
        </properties>
  
        <body>
          <section name="Checkstyle Results">
            <p>
              The following document contains the results of
              <a
                href="http://checkstyle.sourceforge.net/">Checkstyle</a>.
            </p>
          </section>
  
          <section name="Summary">
            <x:set var="fileCount" select="count(file)"/>
            <x:set var="errorCount" select="count(file/error)"/>
            <table>
              <tr>
                <th>Files</th>
                <th>Errors</th>
              </tr>
              <tr>
                <td>${fileCount}</td>
                <td>${errorCount}</td>
              </tr>
            </table>
          </section>
  
          <section name="Files">
            <table>
              <tr>
                <th>Files</th>
                <th>Errors</th>
              </tr>
              <j:set var="fullSrcDir" value="${pom.build.sourceDirectory}"/>
              <j:set var="srcDir" value="${fileutil.file(fullSrcDir).getAbsolutePath()}"/>
              <j:set var="srcDirLength" value="${srcDir.length() + 1}"/>
              <x:set var="files" select="file"/>
              <!-- x:forEach is busted -->
              <j:forEach var="file" items="${files}">
                <!-- Type coercion doesn't work worth a fuck in jexl. -->
                <j:set var="name" value="${file.attribute('name').getValue()}"/>
                <j:set var="name" value="${name.substring(mavenTool.toInteger(srcDirLength.toString()))}"/>
                <!--- +1 is for the trailing slash above -->
                <x:set var="errorCount" select="count($file/error)"/>
                
                <j:if test="${errorCount != 0}">
                  <tr>
                    <td>
                      <a href="#${name}">${name}</a>
                    </td>
                    <td>${errorCount}</td>
                  </tr>
                </j:if>
              </j:forEach>
            </table>
  
            <j:forEach var="file" items="${files}">
              <x:set var="errorCount" select="count($file/error)"/>
              <j:if test="${errorCount != 0}">
                <j:set var="name" value="${file.attribute('name').getValue()}"/>
                <j:set var="name" value="${name.substring(mavenTool.toInteger(srcDirLength.toString()))}"/>
  
                <subsection name="${name}">
                  <table>
                    <tr>
                      <th>Error</th>
                      <th>Line</th>
                    </tr>
                    <x:set var="errors" select="$file/error"/>
                    <j:forEach var="error" items="${errors}">
                      <tr>
                        <td>
                          <j:set var="errorMessage" value="${error.attribute('message').getValue()}"/>
                          ${htmlescape.getText(errorMessage)}
                        </td>
                        <td>
                          <j:set var="line" value="${error.attribute('line').getValue()}"/>
                          <j:set var="lastIndex" value="${name.lastIndexOf('.java')}"/>
                          <j:choose>
                            <j:when test="${lastIndex > 0}">
                              <j:set var="index" value="${mavenTool.toInteger(lastIndex.toString())}"/>
                              <j:set var="nameWithoutJavaExtension" value="${name.substring(0, index)}"/>
                              <a href="xref/${nameWithoutJavaExtension}.html#${line}">${line}</a>
                            </j:when>
                            <j:otherwise>
                              ${line}
                            </j:otherwise>
                          </j:choose>
                        </td>
                      </tr>
                    </j:forEach>
                  </table>
                </subsection>
              </j:if>
            </j:forEach>
          </section>
        </body>
      </document>
    </jsl:template>
  </jsl:stylesheet>
  
  
  
  1.1                  jakarta-turbine-maven/src/plugins-build/jbuilder/library.jsl
  
  Index: library.jsl
  ===================================================================
  #match ("classpath")
    #set( $mavenProject = $context.getAppValue("mavenProject") )
  <?xml version="1.0" encoding="UTF-8"?>
  
  <library>
    <!--JBuilder Library Definition File-->
    <fullname>$mavenProject.id</fullname>
    <class>
  $context.applyTemplates("classpathentry")
    </class>
    <required>$mavenProject.id</required>
  </library>
  #end
  
  #match("classpathentry")
    <path>[$attrib.path]</path>
  #end
  
  
  1.1                  jakarta-turbine-maven/src/plugins-build/jdepend/jdepend.jsl
  
  Index: jdepend.jsl
  ===================================================================
  <?xml version="1.0"?>
  
  <jsl:stylesheet
    select="$doc"
    xmlns:j="jelly:core"
    xmlns:jsl="jelly:jsl"
    xmlns:x="jelly:xml"
    xmlns:define="jelly:define"
    xmlns:util="jelly:util"
    xmlns:doc="doc"
    xmlns:jdepend="jdepend"
    trim="false">
  
    <!-- This needs to be instantiated here to be available in the template matches -->
    <j:useBean var="mavenTool" class="org.apache.maven.MavenTool"/>
    <j:useBean var="htmlescape" class="org.apache.velocity.anakia.Escape"/>
    <j:useBean var="fileutil" class="org.apache.velocity.texen.util.FileUtil"/>
    <j:useBean var="pathtool" class="org.apache.maven.DVSLPathTool"/>
  
    <define:taglib uri="jdepend">
      <define:tag name="nav">
        <p>
          [
          <a href="#Summary">summary</a>]
          [
          <a href="#Packages">packages</a>]
          [
          <a href="#Cycles">cycles</a>]
          [
          <a href="#Explanations">explanations</a>]
        </p>
      </define:tag>
      <!--
       | Used to print the abstract and concrete classes that a package
       | contains.  Also removes the leading package information from
       | the fully qualified class (to conserve screen space).  Also,
       | creates a link to the xref sources so users can quickly navigate
       | the code.
      -->
      <define:tag name="classes">
        <j:choose>
          <j:when test="${currentNode.get(xpath) != null}">
            <i>None</i>
          </j:when>
          <j:otherwise>
            <j:forEach var="class" items="${currentNode.selectNodes(xpath)}">
              <j:set var="index" value="${class.getStringValue().lastIndexOf('.') + 1}"/>
              <util:replace var="dir" oldChar="." newChar="/" value="${class.getStringValue()}"/>
              <a href="xref/${dir}.html">${class.getStringValue().substring(mavenTool.toInteger(index.toString()))}</a>
              <br/>
            </j:forEach>
          </j:otherwise>
        </j:choose>
      </define:tag>
      <!--
       | Used to print the "used" and "used by" packages.  Also, creates a
       | link to the appropriate package in the report.
      -->
      <define:tag name="packages">
        <j:choose>
          <j:when test="${currentNode.get(xpath) != null}">
            <i>None</i>
          </j:when>
          <j:otherwise>
            <j:forEach var="class" items="${currentNode.selectNodes(xpath)}">
              <a href="#${class.getStringValue()}">${class.getStringValue()}</a>
              <br/>
            </j:forEach>
          </j:otherwise>
        </j:choose>
      </define:tag>
    </define:taglib>
  
    <jsl:template match="JDepend">
      <document>
  
        <properties>
          <title>JDepend Source Code Analysis</title>
        </properties>
  
        <body>
          <section name="Metric Results">
            <jdepend:nav/>
            <p>
              The following document contains the results of a
              <a
                href="http://www.clarkware.com/software/JDepend.html">JDepend</a>
              metric analysis.  The various metrics are defined at the bottom
              of this document.
            </p>
          </section>
  
          <section name="Summary">
            <jdepend:nav/>
            <table>
              <tr>
                <th>Package</th>
                <th>
                  <font size="-1">Total 
                  <br/>Classes</font>
                </th>
                <th>
                  <font size="-1">Abstract
                    <br/>Classes
                  </font>
                </th>
                <th>
                  <font size="-1">Concrete
                    <br/>Classes
                  </font>
                </th>
                <th>
                  <font size="-1">Afferent
                    <br/>Couplings
                  </font>
                </th>
                <th>
                  <font size="-1">Efferent
                    <br/>Couplings
                  </font>
                </th>
                <th>
                  <font size="-1">Abstractness</font>
                </th>
                <th>
                  <font size="-1">Instability</font>
                </th>
                <th>
                  <font size="-1">Distance</font>
                </th>
              </tr>
  
              <x:set var="packages" select="Packages/Package"/>
              <j:forEach var="package" items="${packages}">
                <!-- Is this the only way I can tell if an element has a value properly? -->
                <j:set var="error" value="${package.valueOf('error').trim()}"/>
                <j:if test="${error == ''}">
                  <tr>
                    <td>
                      <a href="#${package.attribute('name').getValue()}">${package.attribute('name').getValue()}</a>
                    </td>
                    <td align="right">
                      <x:expr select="$package/Stats/TotalClasses"/>
                    </td>
                    <td><x:expr select="$package/Stats/AbstractClasses"/></td>
                    <td><x:expr select="$package/Stats/ConcreteClasses"/></td>
                    <td><x:expr select="$package/Stats/Ca"/></td>
                    <td><x:expr select="$package/Stats/Ce"/></td>
                    <td>
                      <j:set var="display"><x:expr select="$package/Stats/A"/></j:set>
                      <doc:formatAsNumber string="${display}" pattern="#.##"/>
                    </td>
                    <td>
                      <j:set var="display"><x:expr select="$package/Stats/I"/></j:set>
                      <doc:formatAsNumber string="${display}" pattern="#%"/>
                    </td>
                    <td>
                      <j:set var="display"><x:expr select="$package/Stats/D"/></j:set>
                      <doc:formatAsNumber string="${display}" pattern="0%"/>
                    </td>
                  </tr>
                </j:if>
              </j:forEach>
  
            </table>
          </section>
  
          <section name="Packages">
            <jdepend:nav/>
  
            <j:forEach var="package" items="${packages}">
              <!-- Is this the only way I can tell if an element has a value properly? -->
              <j:set var="error" value="${package.valueOf('error').trim()}"/>
              <j:if test="${error == ''}">
                <subsection name="${package.attribute('name').getValue()}">
                  <table>
                    <tr>
                      <th>Afferent Couplings</th>
                      <th>Efferent Couplings</th>
                      <th>Abstractness</th>
                      <th>Instability</th>
                      <th>Distance</th>
                    </tr>
                    <tr>
                      <td>${package.valueOf("Stats/Ca")}</td>
                      <td>${package.valueOf("Stats/Ce")}</td>
                      <td>
                        <doc:formatAsNumber string="${package.valueOf('Stats/A')}" pattern="0%"/>
                      </td>
                      <td>
                        <doc:formatAsNumber string="${package.valueOf('Stats/I')}" pattern="0%"/>
                      </td>
                      <td>
                        <doc:formatAsNumber string="${package.valueOf('Stats/D')}" pattern="0%"/>
                      </td>
                    </tr>
                  </table>
  
                  <table>
                    <tr>
                      <th>Abstract Classes</th>
                      <th>Concrete Classes</th>
                      <th>Used by Packages</th>
                      <th>Uses Packages</th>
                    </tr>
                    <tr>
                      <td>
                        <jdepend:classes currentNode="${package}" xpath="AbstractClasses/Class"/>
                      </td>
                      <td>
                        <jdepend:classes currentNode="${package}" xpath="ConcreteClasses/Class"/>
                      </td>
                      <td>
                        <jdepend:packages currentNode="${package}" xpath="UsedBy/Package"/>
                      </td>
                      <td>
                        <jdepend:packages currentNode="${package}" xpath="DependsUpon/Package"/>
                      </td>
                    </tr>
                  </table>
                </subsection>
              </j:if>
            </j:forEach>
          </section>
  
          <section name="Cycles">
            <jdepend:nav/>
            <x:set var="packages" select="Cycles/Package"/>
            <j:choose>
              <j:when test="${size(packages) == 0}">
                <p>There are no cyclic dependancies.</p>
              </j:when>
              <j:otherwise>
                <table>
                  <tr>
                    <th>Package</th>
                    <th>Cyclic Dependencies</th>
                  </tr>
                  
                  <j:forEach var="package" items="${packages}">
                    <tr>
                      <td>${package.attribute('Name').getValue()}</td>
                      <td>
                        <x:set var="cycles" select="$package/Package"/> 
                        <j:forEach var="cycle" items="${cycles}">
                          ${cycle.getText()}
                          <br/>
                        </j:forEach>
                      </td>
                    </tr>
                  </j:forEach>
                </table>
              </j:otherwise>
            </j:choose>
          </section>
  
          <section name="Explanations">
            <jdepend:nav/>
  
            <p>
              The following explanations are for quick reference and are
              lifted directly from the original
              <a
                href="http://www.clarkware.com/software/JDepend.html">JDepend
                documentation</a>.
            </p>
  
            <table>
              <tr>
                <th>Term</th>
                <th>Description</th>
              </tr>
              <tr>
                <td>Number of Classes</td>
                <td>
                  The number of concrete and abstract classes (and interfaces)
                  in the package is an indicator of the extensibility of the
                  package.
                </td>
              </tr>
              <tr>
                <td>Afferent Couplings</td>
                <td>
                  The number of other packages that depend upon classes within
                  the package is an indicator of the package's responsibility.
                </td>
              </tr>
              <tr>
                <td>Efferent Couplings</td>
                <td>
                  The number of other packages that the classes in the package
                  depend upon is an indicator of the package's independence.
                </td>
              </tr>
              <tr>
                <td>Abstractness</td>
                <td>
                  The ratio of the number of abstract classes (and interfaces)
                  in the analyzed package to the total number of classes in
                  the analyzed package.  The range for this metric is 0 to 1,
                  with A=0 indicating a completely concrete package and A=1
                  indicating a completely abstract package.
                </td>
              </tr>
              <tr>
                <td>Instability</td>
                <td>
                  The ratio of efferent coupling (Ce) to total coupling (Ce /
                  (Ce + Ca)). This metric is an indicator of the package's
                  resilience to change.  The range for this metric is 0 to 1,
                  with I=0 indicating a completely stable package and I=1
                  indicating a completely instable package.
                </td>
              </tr>
              <tr>
                <td>Distance</td>
                <td>
                  The perpendicular distance of a package from the idealized
                  line A + I = 1. This metric is an indicator of the package's
                  balance between abstractness and stability.  A package
                  squarely on the main sequence is optimally balanced with
                  respect to its abstractness and stability. Ideal packages
                  are either completely abstract and stable (x=0, y=1) or
                  completely concrete and instable (x=1, y=0).  The range for
                  this metric is 0 to 1, with D=0 indicating a package that is
                  coincident with the main sequence and D=1 indicating a
                  package that is as far from the main sequence as possible.
                </td>
              </tr>
              <tr>
                <td>Cycles</td>
                <td>
                  Packages participating in a package dependency cycle are in
                  a deadly embrace with respect to reusability and their
                  release cycle. Package dependency cycles can be easily
                  identified by reviewing the textual reports of dependency
                  cycles. Once these dependency cycles have been identified
                  with JDepend, they can be broken by employing various
                  object-oriented techniques.
                </td>
              </tr>
            </table>
          </section>
  
        </body>
      </document>
  
    </jsl:template>
  </jsl:stylesheet>
  
  
  
  1.1                  jakarta-turbine-maven/src/plugins-build/junit-report/junit.jsl
  
  Index: junit.jsl
  ===================================================================
  <?xml version="1.0"?>
  
  <jsl:stylesheet
    select="$doc"
    xmlns:j="jelly:core"
    xmlns:jsl="jelly:jsl"
    xmlns:x="jelly:xml"
    xmlns:define="jelly:define"
    xmlns:util="jelly:util"
    xmlns:junit="junit"
    xmlns:doc="doc"
    trim="false">
  
    <!-- This needs to be instantiated here to be available in the template matches -->
    <j:useBean var="mavenTool" class="org.apache.maven.MavenTool"/>
    <j:useBean var="numbers" class="java.text.DecimalFormat"/>
    <j:useBean var="htmlescape" class="org.apache.velocity.anakia.Escape"/>
    <j:useBean var="formatter" class="org.apache.maven.DVSLFormatter"/>
    <j:useBean var="fileutil" class="org.apache.velocity.texen.util.FileUtil"/>
    <j:useBean var="pathtool" class="org.apache.maven.DVSLPathTool"/>
  
    <define:taglib uri="junit">
      <define:tag name="nav">
        <p>
          [
          <a href="#Summary">summary</a>]
          [
          <a href="#Package List">package list</a>]
          [
          <a href="#Test Cases">test cases</a>]
        </p>
      </define:tag>
      <define:tag name="testSuiteHeader">
        <tr>
          <th>Name</th>
          <th>Tests</th>
          <th>Errors</th>
          <th>Failures</th>
          <th>Time(s)</th>
        </tr>
      </define:tag>
      <define:tag name="testCaseHeader">
        <tr>
          <th>Name</th>
          <th>Status</th>
          <th>Type</th>
  
          <th>Time(s)</th>
        </tr>
      </define:tag>
      <define:tag name="displayFailure">
        <j:choose>
          <j:when test="${current.attribute('message') != null}">
            ${htmlescape.getTest(current.attributes('message'))}
          </j:when>
          <j:otherwise>
            N/A
          </j:otherwise>
          <p/>
          <code>
            ${htmlescape.getText(current.value())}
          </code>
        </j:choose>
      </define:tag>
    </define:taglib>
  
    <jsl:template match="testsuites">
      <document>
  
        <properties>
          <title>JUnit Test Results</title>
        </properties>
  
        <body>
          <section name="Summary">
            <junit:nav/>
            <x:set var="testCount" select="sum(testsuite/@tests)"/>
            <x:set var="errorCount" select="sum(testsuite/@errors)"/>
            <x:set var="failureCount" select="sum(testsuite/@failures)"/>
            <x:set var="timeCount" select="sum(testsuite/@time)"/>
            <!--
            #set ($successRate  = $node.valueOf("($testCount - ($failureCount + $errorCount)) div $testCount"))
            -->
            <table>
              <tr>
                <th>Tests</th>
                <th>Errors</th>
                <th>Failures</th>
                <th>Success rate</th>
                <th>Time(s)</th>
              </tr>
              <tr>
                <td>
                  <doc:formatAsNumber string="${testCount}" pattern="0"/>
                </td>
                <td>
                  <doc:formatAsNumber string="${errorCount}" pattern="0"/>
                </td>
                <td>
                  <doc:formatAsNumber string="${failureCount}" pattern="0"/>
                </td>
                <td>
                  <doc:formatAsNumber string="${successRate}" pattern="0.00%"/>
                </td>
                <td>
                  <doc:formatAsNumber string="${timeCount}" pattern="0.000"/>
                </td>
              </tr>
            </table>
            <p>
              Note:
              <i>failures</i> are anticipated and checked for with
              assertions while
              <i>errors</i> are unanticipated.
            </p>
          </section>
  
          <section name="Package List">
            <junit:nav/>
            <table>
              <!--
              <junit:testSuiteHeader/>
              -->
              <x:set var="testsuites" select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]"/>
              <j:forEach var="testsuite" items="$testsuites}">
                <j:set var="package" value="${testsuite.attribute('package')}"/>
                <j:set var="quotedPackage" value='"${package}"'/>
                <x:set var="testCount" select="sum(./testsuite[./@package = $quotedPackage]/@tests)"/>
                <x:set var="errorCount" select="sum(./testsuite[./@package = $quotedPackage]/@errors)"/>
                <x:set var="failureCount" select="sum(./testsuite[./@package = $quotedPackage]/@failures)"/>
                <x:set var="timeCount" select="sum(./testsuite[./@package = $quotedPackage]/@time)"/>
                <tr>
                  <td>
                    <a href="#${package}">${package}</a>
                  </td>
                  <td>
                    <doc:formatAsNumber string="${testCount}" pattern="0"/>
                  </td>
                  <td>
                    <doc:formatAsNumber string="${failureCount}" pattern="0"/>
                  </td>
                  <td>
                    <doc:formatAsNumber string="${errorCount}" pattern="0"/>
                  </td>
                  <td>
                    <doc:formatAsNumber string="${timeCount}" pattern="0.000"/>
                  </td>
                </tr>
              </j:forEach>
            </table>
            <p>
              Note: package statistics are not computed recursively, they only
              sum up all of its testsuites numbers.
            </p>
  
            <j:forEach var="testsuite" items="${testsuites}">
              <j:set var="package" value="${testsuite.attribute('package').getValue()}"/>
              <j:set var="quotedPackage" value='"${package}"'/>
  
              <subsection name="${package}">
                <table>
                  <!--
                  <junit:testSuiteHeader/>
                  -->
                  <x:set var="tests" select="/testsuites/testsuite[./@package = $quotedPackage]"/>
                  <j:forEach var="test" items="$tests}">
                    <tr>
                      <td>
                        <a href="#${test.attribute('name').getValue()}">${test.attribute('name').getValue()}</a>
                      </td>
                      <td>
                        <doc:formatAsNumber string="${test.attribute('tests').getValue()}" pattern="0"/>
                      </td>
                      <td>
                        <doc:formatAsNumber string="${test.attribute('errors').getValue()}" pattern="0"/>
                      </td>
                      <td>
                        <doc:formatAsNumber string="${test.attribute('failures').getValue()}" pattern="0"/>
                      </td>
                      <td>
                        <doc:formatAsNumber string="${test.attribute('time').getValue()}" pattern="0.000"/>
                      </td>
                    </tr>
                  </j:forEach>
                </table>
              </subsection>
            </j:forEach>
          </section>
  
          <section name="Test Cases">
            <junit:nav/>
            <x:set var="testsuites" select="./testsuite"/>
            <j:forEach var="testsuite" items="${testsuites}">
              <subsection name="${testsuite.attribute('name').getValue()}">
                <table>
                  <!--
                  <junit:testCaseHeader/>
                  -->
  
                  ## test can even not be started at all (failure to load the class)
                  ## so report the error directly
                  ##
  
                  <x:set var="errors" select="$testsuite/error"/>
                  <j:forEach var="error" items="${errors}">
                    <tr>
                      <td colspan="4">
                        <junit:displayFailure current="${error}"/>
                      </td>
                    </tr>
                  </j:forEach>
  
                  <x:set var="testcases" select="$testsuite/testcase"/>
                  <j:forEach var="error" items="${errors}">
                    <tr>
                      <td>${testcase.attribute("name")}</td>
                      <j:choose>
                        <j:when test="${testcase.get('failure') != null}">
                          <td>Failure</td>
                          <td>
                            <junit:displayFailure current="{$testcase.selectSingleNode('failure')}"/>
                          </td>
                        </j:when>
                        <j:when test="${testcase.get('error') != null}">
                          <td>Error</td>
                          <td>
                            <junit:displayFailure current="{$testcase.selectSingleNode('error')}"/>
                          </td>
                        </j:when>
                        <j:otherwise>
                          <td>Success</td>
                          <td></td>
                        </j:otherwise>
                      </j:choose>
                      <j:choose>
                        <j:when test="${testcase.get('time') != null}">
                          <td>
                            <doc:formatAsNumber string="${testcase.attribute('time')}" pattern="0.000"/>
                          </td>
                        </j:when>
                        <j:otherwise>
                          <td></td>
                        </j:otherwise>
                      </j:choose>
                    </tr>
                  </j:forEach>
                </table>
              </subsection>
            </j:forEach>
          </section>
        </body>
      </document>
    </jsl:template>
  </jsl:stylesheet>