Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added recursive folder totals for html report. #1

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions lib/assets/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ a:hover { text-decoration:underline; }
visibility:hidden;
}
.fl { float: left; }
.fr { float: right; }
@media only screen and (max-width:640px) {
.col3 { width:100%; max-width:100%; }
.hide-mobile { display:none!important; }
Expand Down Expand Up @@ -211,3 +212,23 @@ pre.prettyprint {
.footer, .push {
height: 48px;
}

#depthSlider {
width: 7em;
}

tr.recursive {
display: none;
}
body.normal tr.recursive {
display: none;
}
.recursive .recursive {
display: table-row;
}
body.recursive tr.shallow {
display: none !important;
}
.recursive_cb {
width: 50%;
}
6 changes: 5 additions & 1 deletion lib/assets/sorter.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,8 @@ var addSorting = (function () {
};
})();

window.addEventListener('load', addSorting);
if (window.addEventListener) {
window.addEventListener('load', addSorting);
} else {
window.attachEvent('onload', addSorting);
}
86 changes: 61 additions & 25 deletions lib/report/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ var handlebars = require('handlebars').create(),
'<td class="text"><pre class="prettyprint lang-js">{{#show_code structured}}{{/show_code}}</pre></td>',
'</tr>\n'
].join('')),
summaryTableHeader = [
summaryTableHeader = handlebars.compile([
'<div class="pad1">',
'<table class="coverage-summary">',
'<thead>',
'<tr>',
' <th data-col="file" data-fmt="html" data-html="true" class="file">File</th>',
' <th data-col="file" data-fmt="html" data-html="true" class="file">{{#show_recursive isRoot}}{{/show_recursive}}File</th>',
' <th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>',
' <th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>',
' <th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>',
Expand All @@ -43,9 +43,9 @@ var handlebars = require('handlebars').create(),
'</tr>',
'</thead>',
'<tbody>'
].join('\n'),
].join('\n')),
summaryLineTemplate = handlebars.compile([
'<tr>',
'<tr class="depth-{{depth}} {{recursive}}">',
'<td class="file {{reportClasses.statements}}" data-value="{{file}}"><a href="{{output}}">{{file}}</a></td>',
'<td data-value="{{metrics.statements.pct}}" class="pic {{reportClasses.statements}}"><div class="chart">{{#show_picture}}{{metrics.statements.pct}}{{/show_picture}}</div></td>',
'<td data-value="{{metrics.statements.pct}}" class="pct {{reportClasses.statements}}">{{metrics.statements.pct}}%</td>',
Expand All @@ -69,7 +69,8 @@ var handlebars = require('handlebars').create(),
RE_GT = />/g,
RE_AMP = /&/g,
RE_lt = /\u0001/g,
RE_gt = /\u0002/g;
RE_gt = /\u0002/g,
SEP = path.sep || '/';

handlebars.registerHelper('show_picture', function (opts) {
var num = Number(opts.fn(this)),
Expand Down Expand Up @@ -326,6 +327,30 @@ function isEmptySourceStore(sourceStore) {
return cache && !Object.keys(cache).length;
}

handlebars.registerHelper('show_recursive', function(isRoot){
if (!isRoot) { return '';}
return '<div class="fr recursive_cb" title="show recursive folder totals">' +
'<input type="checkbox" id="recursive" onclick="onRecursiveChange(null, event)" onchange="onRecursiveChange(this.checked, event)" />' +
'<label for="recursive" class="quiet" onclick="onRecursiveChange(null, event)">recursive totals</label>' +
'</div>';
});

handlebars.registerHelper('depth_styles', function () {
var maxDepth = 10,
lazyLoop = Array(maxDepth + 1).join().split(','),
depth = 0,
getStyle = function (ignore, index) {
if (!index) { return ''; }
var val = depth && index > depth ? 'none' : 'table-row;';
return '.depth-' + index + '{display:' + val + '} ';
},
getAtStyle = function (ignore, index) {
depth = index;
return lazyLoop.map(getStyle).join('.at-depth-' + depth + ' ');
};
return '<style type="text/css">' + lazyLoop.map(getAtStyle).join('\n') + '</style>';
});

/**
* a `Report` implementation that produces HTML coverage reports.
*
Expand Down Expand Up @@ -438,46 +463,57 @@ Report.mix(HtmlReport, {
writer.write(footerTemplate(templateData));
},

writeIndexPage: function (writer, node) {
writeIndexPage: function (writer, node, isRoot) {
var linkMapper = this.opts.linkMapper,
templateData = this.opts.templateData,
children = Array.prototype.slice.apply(node.children),
watermarks = this.opts.watermarks;
watermarks = this.opts.watermarks,
maxDepth = 0,
_writeRow = function (child, metrics, recursive) {
var reportClasses = {
statements: getReportClass(metrics.statements, watermarks.statements),
lines: getReportClass(metrics.lines, watermarks.lines),
functions: getReportClass(metrics.functions, watermarks.functions),
branches: getReportClass(metrics.branches, watermarks.branches)
},
data = {
metrics: metrics,
reportClasses: reportClasses,
file: cleanPath(child.displayShortName()),
output: linkMapper.fromParent(child),
depth: isRoot ? child.name.split(SEP).length - 1 : 0,
recursive: recursive ? 'recursive' : 'shallow'
};
if (data.depth > maxDepth) { maxDepth = data.depth; }
writer.write(summaryLineTemplate(data) + '\n');
};

children.sort(function (a, b) {
return a.name < b.name ? -1 : 1;
});
templateData.isRoot = isRoot;

this.fillTemplate(node, templateData);
writer.write(headerTemplate(templateData));
writer.write(summaryTableHeader);
writer.write(summaryTableHeader(templateData));
children.forEach(function (child) {
var metrics = child.metrics,
reportClasses = {
statements: getReportClass(metrics.statements, watermarks.statements),
lines: getReportClass(metrics.lines, watermarks.lines),
functions: getReportClass(metrics.functions, watermarks.functions),
branches: getReportClass(metrics.branches, watermarks.branches)
},
data = {
metrics: metrics,
reportClasses: reportClasses,
file: cleanPath(child.displayShortName()),
output: linkMapper.fromParent(child)
};
writer.write(summaryLineTemplate(data) + '\n');
_writeRow(child, child.metrics, false);
if (isRoot) { // write recursive metrics
_writeRow(child, child.recursiveMetrics, true);
}
});
templateData.maxDepth = maxDepth;
writer.write(summaryTableFooter);
writer.write(footerTemplate(templateData));
},

writeFiles: function (writer, node, dir, collector) {
writeFiles: function (writer, node, dir, collector, isRoot) {
var that = this,
indexFile = path.resolve(dir, 'index.html'),
childFile;
if (this.opts.verbose) { console.error('Writing ' + indexFile); }
writer.writeFile(indexFile, function (contentWriter) {
that.writeIndexPage(contentWriter, node);
that.writeIndexPage(contentWriter, node, isRoot);
});
node.children.forEach(function (child) {
if (child.kind === 'dir') {
Expand Down Expand Up @@ -563,7 +599,7 @@ Report.mix(HtmlReport, {
});
writer.on('done', function () { that.emit('done'); });
//console.log(JSON.stringify(tree.root, undefined, 4));
this.writeFiles(writer, tree.root, dir, collector);
this.writeFiles(writer, tree.root, dir, collector, true);
writer.done();
}
});
Expand Down
10 changes: 7 additions & 3 deletions lib/report/templates/foot.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
{{#if prettify}}
<script src="{{prettify.js}}"></script>
<script>
var maxDepth = {{maxDepth}};
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
if (typeof prettyPrint === 'function') {
prettyPrint();
}

var slider = document.querySelector('#depthSlider');
if (slider) { slider.max = slider.value = maxDepth; }
};
</script>
{{/if}}
Expand Down
37 changes: 36 additions & 1 deletion lib/report/templates/head.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,45 @@
background-image: url({{sorter.image}});
}
</style>
{{#if isRoot}}
<script>
function onDepthChange(value){
document.body.className = document.body.className.replace(/\s*at-depth-\d+/,'') + ' at-depth-' + value;
}
function onRecursiveChange(checked, event){
var ie8 = /MSIE 8/.test(navigator.userAgent);
if (checked === null && !ie8) { // prevent sorter clicks
if(event.stopPropagation) {
event.stopPropagation();
} else {
event.returnValue = false;
}
return false;
}
if (ie8) event.srcElement.blur();
toggleClass(document.body, 'normal');
toggleClass(document.body, 'recursive');
}
function toggleClass(el, name) {
if (el.className.indexOf(name) > -1) {
el.className = el.className.replace(name, '');
} else {
el.className += ' ' + name;
}
}
</script>
{{#depth_styles}}{{/depth_styles}}
{{/if}}
</head>
<body>
<body class="normal">
<div class='wrapper'>
<div class='pad1'>
{{#if isRoot}}
<div class='fr space-right2'>
<label for="depthSlider" class="quiet">show depth</label>
<input type="range" id="depthSlider" min="1" max="10" oninput="onDepthChange(value)" onchange="onDepthChange(value)"/>
</div>
{{/if}}
<h1>
{{{pathHtml}}}
</h1>
Expand Down