Skip to content

Commit 41e41b0

Browse files
authored
Merge pull request #4 from hansenmc/code-coverage
code coverage
2 parents 883636c + 5a896be commit 41e41b0

File tree

11 files changed

+1016
-65
lines changed

11 files changed

+1016
-65
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* Copyright 2012-2018 MarkLogic Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* The use of the Apache License does not indicate that this project is
17+
* affiliated with the Apache Software Foundation.
18+
*
19+
* Code adapted from xray
20+
* https://github.com/robwhitby/xray/tree/v2.1
21+
*
22+
* Modifications copyright (c) 2018 MarkLogic Corporation
23+
**/
24+
25+
ol.coverage-source li {
26+
font-family: monospace;
27+
margin-left: 30px;
28+
color: #999;
29+
}
30+
ol.coverage-source li pre {
31+
display: inline;
32+
padding: 0 2px;
33+
color: #000;
34+
}
35+
ol.coverage-source li.wanted pre { background-color: #f66; }
36+
ol.coverage-source li.covered pre { background-color: #6f6; }
37+
38+
summary, ul li, ul pre { margin: 0; padding: 5px 10px; font-weight: normal; }
39+
summary {
40+
display: block; /* for non webkit */
41+
border-top-left-radius: 10px;
42+
border-top-right-radius: 10px;
43+
background-color: #ddd;
44+
font-weight: bold;
45+
}
46+
47+
section.coverage details {
48+
margin-bottom: 2em;
49+
}
50+
section.coverage details > table {
51+
border-top-left-radius: 0px;
52+
border-top-right-radius: 0px;
53+
border-bottom-left-radius: 10px;
54+
border-bottom-right-radius: 10px;
55+
}
56+
section.coverage details > table thead th:first-child {
57+
border-top-left-radius: 0px;
58+
}
59+
section.coverage details > table thead th:last-child {
60+
border-top-right-radius: 0px;
61+
}
62+
section.coverage details > table tfoot th {
63+
border-radius: 0px;
64+
}
65+
section.coverage details > table tfoot th:first-child {
66+
border-bottom-left-radius: 10px;
67+
}
68+
section.coverage details > table tfoot th:last-child {
69+
border-bottom-right-radius: 10px;
70+
}
71+
72+
.bar-chart {
73+
width: 100%;
74+
height: 1em;
75+
}
76+
span.bar {
77+
display: inline-block;
78+
height: 50%;
79+
box-sizing: border-box;
80+
float: left;
81+
font-weight: bold;
82+
font-family: arial, sans-serif;
83+
}
84+
85+
.missed {
86+
background: #f66;
87+
}
88+
89+
.covered {
90+
background: #6f6;
91+
}

src/main/ml-modules/root/test/default.xqy

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ limitations under the License.
1515
:)
1616
xquery version "1.0-ml";
1717

18-
import module namespace helper="http://marklogic.com/roxy/test-helper" at "/test/test-helper.xqy", "/test/test-controller.xqy";
18+
import module namespace helper="http://marklogic.com/roxy/test-helper"
19+
at "/test/test-helper.xqy", "/test/test-controller.xqy";
20+
import module namespace coverage="http://marklogic.com/roxy/test-coverage" at "/test/test-coverage.xqy";
1921

2022
declare namespace t="http://marklogic.com/roxy/test";
2123

@@ -27,9 +29,10 @@ declare function local:run() {
2729
let $run-suite-teardown as xs:boolean := xdmp:get-request-field("runsuiteteardown", "") eq "true"
2830
let $run-teardown as xs:boolean := xdmp:get-request-field("runteardown", "") eq "true"
2931
let $format as xs:string := xdmp:get-request-field("format", "xml")
32+
let $calculate-coverage as xs:boolean := xdmp:get-request-field("calculatecoverage", "") eq "true"
3033
return
3134
if ($suite) then
32-
let $result := helper:run-suite($suite, $tests, $run-suite-teardown, $run-teardown)
35+
let $result := helper:run-suite($suite, $tests, $run-suite-teardown, $run-teardown, $calculate-coverage)
3336
return
3437
if ($format eq "junit") then
3538
helper:format-junit($result)
@@ -43,6 +46,32 @@ declare function local:list()
4346
helper:list()
4447
};
4548

49+
(:~
50+
: Generate the code coverage report
51+
:)
52+
declare function local:coverage-report()
53+
{
54+
let $test-results := xdmp:get-request-body("xml")
55+
let $format := xdmp:get-request-field("format", "html")
56+
let $params := map:new(( map:entry("test-dir", xdmp:get-request-field("/test/suites/")) ))
57+
let $coverage-summary := coverage:summary($test-results/*)
58+
return
59+
xdmp:xslt-invoke("/test/xslt/coverage/report/" || $format || ".xsl", $coverage-summary)
60+
};
61+
62+
(:~
63+
: Generate view of module coverage
64+
:)
65+
declare function local:coverage-module()
66+
{
67+
let $module as xs:string := xdmp:get-request-field("module")
68+
let $format as xs:string := xdmp:get-request-field("format", "html")
69+
let $wanted as xs:integer* := for $line in xs:NMTOKENS(xdmp:get-request-field("wanted")) return xs:integer($line)
70+
let $covered as xs:integer* := for $line in xs:NMTOKENS(xdmp:get-request-field("covered")) return xs:integer($line)
71+
return
72+
coverage:module-view($module, $format, $wanted, $covered)
73+
};
74+
4675
(:~
4776
: Provides the UI for the test framework to allow selection and running of tests
4877
:)
@@ -86,7 +115,6 @@ declare function local:main() {
86115
<th>Failed</th>
87116
</tr>
88117
</thead>
89-
90118
<tbody>
91119
{
92120
for $suite at $index in helper:list()/t:suite
@@ -101,7 +129,6 @@ declare function local:main() {
101129
<img class="tests-toggle-minus" src="img/arrow-down.gif"/>
102130
{fn:data($suite/@path)} <span class="spinner"><img src="img/spinner.gif"/><b>Running...</b></span>
103131
</div>
104-
105132
</td>
106133
<td>{fn:count($suite/t:tests/t:test)}</td>
107134
<td class="tests-run">-</td>
@@ -130,11 +157,13 @@ declare function local:main() {
130157
</div>
131158
</td>
132159
</tr>
133-
134160
)
135161
}
136162
</tbody>
137163
</table>
164+
165+
<div id="coverage-report"></div>
166+
138167
<table cellspacing="0" cellpadding="0" >
139168
<thead>
140169
<tr>
@@ -148,6 +177,9 @@ declare function local:main() {
148177
<tr>
149178
<td><label for="runteardown">Run Teardown after each test</label><input id="runteardown" type="checkbox" checked="checked"/></td>
150179
</tr>
180+
<tr>
181+
<td><label for="calculatecoverage">Calculate Coverage</label><input id="calculatecoverage" type="checkbox" /></td>
182+
</tr>
151183
</tbody>
152184
</table>
153185
<input class="runtests button" type="submit" value="Run Tests" title="(ctrl-enter) works too!"/>

src/main/ml-modules/root/test/js/tests.js

Lines changed: 67 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,38 @@
11
/**
2-
* Copyright 2012-2015 MarkLogic Corporation
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
**/
2+
* Copyright 2012-2018 MarkLogic Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* The use of the Apache License does not indicate that this project is
17+
* affiliated with the Apache Software Foundation.
18+
*
19+
* Code adapted from xray
20+
* https://github.com/robwhitby/xray/tree/v2.1
21+
*
22+
* Modifications copyright (c) 2018 MarkLogic Corporation
23+
**/
1624
var queue = [];
25+
var coverage = $.parseXML("<test:tests xmlns:test='http://marklogic.com/roxy/test'/>");
26+
27+
function resetCoverage() {
28+
'use strict';
29+
30+
var tests = coverage.documentElement;
31+
while (tests.firstChild) {
32+
tests.removeChild(tests.firstChild);
33+
}
34+
$('#coverage-report').empty();
35+
}
1736

1837
function disableParent(item, parentClass) {
1938
'use strict';
@@ -25,7 +44,6 @@ function disableParent(item, parentClass) {
2544
else {
2645
li.addClass('disabled');
2746
}
28-
2947
}
3048

3149
function runNextTest() {
@@ -89,9 +107,36 @@ function runNextTest() {
89107
time: ''
90108
});
91109

110+
coverageReport(coverage);
92111
}
93112
}
94113

114+
function coverageReport() {
115+
'use strict';
116+
var $coverageReport = $('#coverage-report');
117+
var calculateCoverage = $('#calculatecoverage').prop('checked');
118+
if (calculateCoverage) {
119+
$.ajax({
120+
url: 'default.xqy?func=coverage-report&format=html',
121+
type: "POST",
122+
cache: false,
123+
data: (new XMLSerializer()).serializeToString(coverage),
124+
contentType: "text/xml",
125+
processData: false,
126+
dataType: 'html',
127+
success: function (data) {
128+
$coverageReport.empty();
129+
$coverageReport.append(data);
130+
},
131+
error: function (data) {
132+
resetCoverage();
133+
}
134+
});
135+
} else {
136+
$coverageReport.empty();
137+
}
138+
}
139+
95140
function renderError(error) {
96141
'use strict';
97142

@@ -229,6 +274,8 @@ function suiteSuccess(parent, xml) {
229274
var spinner = parent.find('span.spinner');
230275
spinner.hide();
231276

277+
coverage.documentElement.appendChild(xml.documentElement);
278+
232279
runNextTest();
233280
}
234281

@@ -256,6 +303,7 @@ function runSuite(suite) {
256303

257304
var suiteTearDown = $('#runsuiteteardown').prop('checked');
258305
var tearDown = $('#runteardown').prop('checked');
306+
var calculateCoverage = $('#calculatecoverage').prop('checked');
259307
var spinner = parent.find('span.spinner');
260308
spinner.show();
261309

@@ -267,7 +315,8 @@ function runSuite(suite) {
267315
suite: suite,
268316
tests: tests.join(','),
269317
runsuiteteardown: suiteTearDown,
270-
runteardown: tearDown
318+
runteardown: tearDown,
319+
calculatecoverage: calculateCoverage
271320
},
272321
dataType: 'xml',
273322
success: function(data) {
@@ -289,13 +338,12 @@ function run() {
289338
$('td.failed').text('-');
290339
$('td.passed').text('-');
291340
$('div.failure').remove();
292-
341+
resetCoverage();
293342
queue = [];
294343
$('input.cb:checked').each(function(){
295344
queue.push(this.value);
296345
});
297346

298-
299347
if (queue.length > 0) {
300348
$('#failed-count').text('Running...');
301349
$('.runtests').hide();
@@ -309,12 +357,12 @@ function cancel() {
309357
'use strict';
310358

311359
queue.length = 0;
360+
resetCoverage();
312361
$('#failed-count').text('Stopping tests...');
313362
$('.canceltests').hide();
314363
}
315364

316365
$(document).ready(function(){
317-
318366
'use strict';
319367

320368
$.extend($.gritter.options, {

0 commit comments

Comments
 (0)