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