|
35 | 35 | <xsl:param name="inline-css" as="xs:string" select="false() cast as xs:string" /> |
36 | 36 |
|
37 | 37 | <xsl:param name="report-css-uri" as="xs:string?" /> |
| 38 | + <!-- See also report-theme parameter, which is defined in format-utils.xsl --> |
38 | 39 |
|
39 | 40 | <!-- @use-character-maps for inline CSS --> |
40 | 41 | <xsl:output method="xhtml" use-character-maps="fmt:disable-escaping" /> |
|
45 | 46 | <xsl:variable name="xspec-doc" as="document-node(element(x:description))" |
46 | 47 | select="doc($xspec-uri)" /> |
47 | 48 |
|
| 49 | + <!-- Get the *-result.xml file. It contains the date/time the test was run. --> |
| 50 | + <xsl:variable name="result-uri" as="xs:string" |
| 51 | + select="replace(base-uri(), '-coverage\.xml', '-result.xml')" /> |
| 52 | + <xsl:variable name="result-doc" as="document-node(element(x:report))"> |
| 53 | + <xsl:choose> |
| 54 | + <xsl:when test="doc-available($result-uri)"> |
| 55 | + <xsl:sequence select="doc($result-uri)"/> |
| 56 | + </xsl:when> |
| 57 | + <xsl:otherwise> |
| 58 | + <!-- End-to-end coverage tests don't have access to *-result.xml. |
| 59 | + We could make the *-result.xml file available by modifying |
| 60 | + <xsl:variable as="element(reports)" name="reports"> |
| 61 | + in test/end-to-end/ant/base/worker/generate.xsl, but then |
| 62 | + we'd have many *-result.xml files to maintain with little benefit. |
| 63 | + Instead, the end-to-end coverage HTML reports use the date from |
| 64 | + mock-result.xml. --> |
| 65 | + <xsl:variable name="mock-result-uri" as="xs:anyURI" |
| 66 | + select="resolve-uri('../mock-result.xml', $xspec-uri)"/> |
| 67 | + <xsl:sequence select="doc($mock-result-uri)"/> |
| 68 | + </xsl:otherwise> |
| 69 | + </xsl:choose> |
| 70 | + </xsl:variable> |
| 71 | + |
| 72 | + <xsl:accumulator name="computed-status" as="xs:string?" initial-value="()"> |
| 73 | + <xsl:accumulator-rule match="node()" phase="start"> |
| 74 | + <xsl:apply-templates select="." mode="coverage"/> |
| 75 | + </xsl:accumulator-rule> |
| 76 | + </xsl:accumulator> |
| 77 | + |
48 | 78 | <xsl:variable name="stylesheet-uri" as="xs:anyURI" |
49 | 79 | select="$xspec-doc/x:description/resolve-uri(@stylesheet, base-uri())" /> |
50 | 80 |
|
|
69 | 99 | --> |
70 | 100 | <xsl:mode name="coverage-report" on-multiple-match="fail" on-no-match="fail" /> |
71 | 101 |
|
| 102 | + <!-- Collect stats data in this variable for all modules. --> |
| 103 | + <xsl:variable name="coverage-stats" as="element(module)*"> |
| 104 | + <!-- Collect from all stylesheet modules --> |
| 105 | + <xsl:for-each select="$stylesheet-trees/xsl:*"> |
| 106 | + <!-- Produce local variables for stylesheet-lines and number-of-lines --> |
| 107 | + <xsl:variable name="stylesheet-uri" as="xs:anyURI" |
| 108 | + select="base-uri()" /> |
| 109 | + <xsl:variable name="stylesheet-string" as="xs:string" |
| 110 | + select="unparsed-text($stylesheet-uri)" /> |
| 111 | + <xsl:variable name="stylesheet-lines" as="xs:string+" |
| 112 | + select="local:split-lines($stylesheet-string)" /> |
| 113 | + <xsl:variable name="number-of-lines" as="xs:integer" |
| 114 | + select="count($stylesheet-lines)" /> |
| 115 | + <xsl:variable name="module-id" as="xs:integer?" |
| 116 | + select="accumulator-before('module-id-for-node')" /> |
| 117 | + <!-- Create module element with attributes that will be used later --> |
| 118 | + <module uri="{$stylesheet-uri}" number-of-lines="{$number-of-lines}" |
| 119 | + formatted-uri="{fmt:format-uri($stylesheet-uri)}" module-id="{$module-id}" xmlns=""> |
| 120 | + <xsl:if test="not(empty($module-id))"> |
| 121 | + <xsl:for-each select=" |
| 122 | + doc($stylesheet-uri)/( |
| 123 | + descendant::node() except |
| 124 | + descendant::text()[normalize-space() = '' and not(parent::xsl:text)] |
| 125 | + )"> |
| 126 | + <coverage xmlns=""> |
| 127 | + <xsl:sequence select="accumulator-before('computed-status')"/> |
| 128 | + </coverage> |
| 129 | + </xsl:for-each> |
| 130 | + </xsl:if> |
| 131 | + </module> |
| 132 | + </xsl:for-each> |
| 133 | + </xsl:variable> |
| 134 | + |
72 | 135 | <xsl:template match="document-node(element(trace))" as="element(xhtml:html)" |
73 | 136 | mode="coverage-report"> |
74 | 137 | <html> |
|
81 | 144 | <xsl:with-param name="uri" select="$report-css-uri" /> |
82 | 145 | </xsl:call-template> |
83 | 146 | </head> |
84 | | - <body> |
| 147 | + <body id="coverageReport"> |
85 | 148 | <h1>Test Coverage Report</h1> |
86 | 149 | <p> |
87 | 150 | <xsl:text>Stylesheet: </xsl:text> |
88 | 151 | <a href="{$stylesheet-uri}"> |
89 | 152 | <xsl:value-of select="fmt:format-uri($stylesheet-uri)" /> |
90 | 153 | </a> |
| 154 | + <!-- Commented out until XSpec version is available |
| 155 | + <span class="byline">Generated by XSpec v<xsl:value-of select="'x.y.z'" /> using Saxon <xsl:value-of select="system-property('xsl:product-version')" /></span> |
| 156 | + --> |
| 157 | + </p> |
| 158 | + <p> |
| 159 | + <xsl:text>XSpec: </xsl:text> |
| 160 | + <a href="{$xspec-uri}"> |
| 161 | + <xsl:value-of select="fmt:format-uri($xspec-uri)" /> |
| 162 | + </a> |
91 | 163 | </p> |
| 164 | + <p> |
| 165 | + <xsl:text>Tested: </xsl:text> |
| 166 | + <xsl:value-of select="format-dateTime($result-doc/x:report/@date, '[D] [MNn] [Y] at [H01]:[m01]')" /> |
| 167 | + </p> |
| 168 | + <!-- The Contents table --> |
| 169 | + <h2>Contents</h2> |
| 170 | + <xsl:call-template name="contents-table"/> |
92 | 171 | <xsl:apply-templates select="$stylesheet-trees/xsl:*" mode="#current" /> |
93 | 172 | </body> |
94 | 173 | </html> |
95 | 174 | </xsl:template> |
96 | 175 |
|
| 176 | + <!-- Generate Contents table at top of coverage report --> |
| 177 | + <!-- In production, always use the global $coverage-stats variable. |
| 178 | + The template parameter is for unit testing this template. --> |
| 179 | + <xsl:template name="contents-table" as="element(xhtml:table)"> |
| 180 | + <xsl:param name="coverage-stats" select="$coverage-stats" |
| 181 | + as="element(module)*"/> |
| 182 | + <table class="xspec"> |
| 183 | + <colgroup> |
| 184 | + <col style="width:68.75%"/> |
| 185 | + <col style="width:6.25%"/> |
| 186 | + <col style="width:6.25%"/> |
| 187 | + <col style="width:6.25%"/> |
| 188 | + <col style="width:6.25%"/> |
| 189 | + <col style="width:6.25%"/> |
| 190 | + </colgroup> |
| 191 | + <thead> |
| 192 | + <tr> |
| 193 | + <th/> |
| 194 | + <th/> |
| 195 | + <th colspan="3" class="totals nodesHead">nodes</th> |
| 196 | + <th/> |
| 197 | + </tr> |
| 198 | + <tr> |
| 199 | + <th/> |
| 200 | + <th class="totals">used</th> |
| 201 | + <th class="totals"> |
| 202 | + <xsl:text>hit</xsl:text> |
| 203 | + <br/> |
| 204 | + <xsl:value-of select="count($coverage-stats/coverage[. eq 'hit'])"/> |
| 205 | + </th> |
| 206 | + <th class="totals emphasis"> |
| 207 | + <xsl:text>missed</xsl:text> |
| 208 | + <br/> |
| 209 | + <xsl:value-of select="count($coverage-stats/coverage[. eq 'missed'])"/> |
| 210 | + </th> |
| 211 | + <th class="totals"> |
| 212 | + <xsl:text>unknown</xsl:text> |
| 213 | + <br/> |
| 214 | + <xsl:value-of select="count($coverage-stats/coverage[. eq 'unknown'])"/> |
| 215 | + </th> |
| 216 | + <th class="totals"> |
| 217 | + <xsl:text>lines</xsl:text> |
| 218 | + <br/> |
| 219 | + <xsl:value-of select="sum($coverage-stats/@number-of-lines)"/> |
| 220 | + </th> |
| 221 | + </tr> |
| 222 | + </thead> |
| 223 | + <tbody> |
| 224 | + <!-- Use the coverage-stats data --> |
| 225 | + <xsl:for-each select="$coverage-stats"> |
| 226 | + <tr class="{if (@module-id eq '') then 'failed' else 'successful'}"> |
| 227 | + <th> |
| 228 | + <a href="#module{position()}"> |
| 229 | + <xsl:text expand-text="yes">module: {@formatted-uri}</xsl:text> |
| 230 | + </a> |
| 231 | + </th> |
| 232 | + <th class="totals"> |
| 233 | + <xsl:value-of select=" |
| 234 | + if (@module-id eq '') then |
| 235 | + 'no' |
| 236 | + else |
| 237 | + 'yes'"/> |
| 238 | + </th> |
| 239 | + <th class="totals"> |
| 240 | + <xsl:value-of select="count(coverage[. eq 'hit'])"/> |
| 241 | + </th> |
| 242 | + <th class="totals"> |
| 243 | + <xsl:value-of select="count(coverage[. eq 'missed'])"/> |
| 244 | + </th> |
| 245 | + <th class="totals"> |
| 246 | + <xsl:value-of select="count(coverage[. eq 'unknown'])"/> |
| 247 | + </th> |
| 248 | + <th class="totals"> |
| 249 | + <xsl:value-of select="@number-of-lines"/> |
| 250 | + </th> |
| 251 | + </tr> |
| 252 | + </xsl:for-each> |
| 253 | + </tbody> |
| 254 | + </table> |
| 255 | + </xsl:template> |
| 256 | + |
97 | 257 | <xsl:template match="xsl:stylesheet | xsl:transform" as="element()+" mode="coverage-report"> |
98 | 258 | <xsl:variable name="stylesheet-uri" as="xs:anyURI" |
99 | 259 | select="base-uri()" /> |
|
109 | 269 | select="string-join(for $i in 1 to $number-width return '0')" /> |
110 | 270 | <xsl:variable name="module-id" as="xs:integer?" |
111 | 271 | select="accumulator-before('module-id-for-node')"/> |
112 | | - <h2> |
113 | | - <xsl:text expand-text="yes">module: {fmt:format-uri($stylesheet-uri)}; {$number-of-lines} lines</xsl:text> |
| 272 | + <!-- div allows the :target CSS style to cover the heading and stylesheet lines --> |
| 273 | + <div id="module{position()}"> |
| 274 | + <h2 class="{if (empty($module-id)) then 'failed' else 'successful'}"> |
| 275 | + <xsl:text expand-text="yes">module: {fmt:format-uri($stylesheet-uri)}</xsl:text> |
| 276 | + <span class="scenario-totals"> |
| 277 | + <xsl:variable name="main-module-stats" as="element(module)*" |
| 278 | + select="$coverage-stats[@uri eq $stylesheet-uri]"/> |
| 279 | + <xsl:text expand-text="yes">hit: {count($main-module-stats/coverage[. eq 'hit'])} / </xsl:text> |
| 280 | + <xsl:text expand-text="yes">missed: {count($main-module-stats/coverage[. eq 'missed'])} / </xsl:text> |
| 281 | + <xsl:text expand-text="yes">unknown: {count($main-module-stats/coverage[. eq 'unknown'])}</xsl:text> |
| 282 | + </span> |
114 | 283 | </h2> |
115 | 284 | <xsl:choose> |
116 | 285 | <xsl:when test="empty($module-id)"> |
117 | 286 | <p><span class="missed">not used</span></p> |
118 | 287 | </xsl:when> |
119 | 288 | <xsl:otherwise> |
120 | | - <pre> |
| 289 | + <pre class="xspecCoverage"> |
121 | 290 | <xsl:value-of select="format-number(1, $number-format)" /> |
122 | 291 | <xsl:text>: </xsl:text> |
123 | 292 | <xsl:call-template name="output-lines"> |
|
127 | 296 | </pre> |
128 | 297 | </xsl:otherwise> |
129 | 298 | </xsl:choose> |
| 299 | + </div> |
130 | 300 | </xsl:template> |
131 | 301 |
|
132 | 302 | <xsl:variable name="attribute-regex" as="xs:string"> |
|
253 | 423 | <xsl:variable name="coverage" as="xs:string"> |
254 | 424 | <xsl:choose> |
255 | 425 | <xsl:when test="$matches"> |
256 | | - <xsl:apply-templates select="$node" mode="coverage"/> |
| 426 | + <xsl:sequence select="$node/accumulator-before('computed-status')"/> |
257 | 427 | </xsl:when> |
258 | 428 | <xsl:otherwise> |
259 | 429 | <xsl:sequence select="'ignored'"/> |
|
0 commit comments