Permalink
Browse files

Add better formatting for HTML

  • Loading branch information...
1 parent b8e1862 commit cbc39f83a3a7bc3aa8257a90e2444fea9b4e95fe @itay committed Nov 28, 2011
View
@@ -2,4 +2,5 @@
.coverage_data/*
node_modules/*
.coverignore
-npm-debug.log
+npm-debug.log
+cover_html/*
View
@@ -5,7 +5,6 @@
// Licensed under the MIT License
// TODO:
-// - Better HTML
(function() {
var fs = require('fs');
@@ -60,7 +59,7 @@
};
var readIgnoreFile = function(ignorePath) {
- var ignore = {}
+ var ignore = {};
// Get the full path relative to the CWD
var fullIgnorePath = path.resolve(process.cwd(), ignorePath);
@@ -380,45 +379,88 @@
};
/* ====== Reporters ====== */
-
+
var reporterHandlers = {
html: function(coverageData, config) {
var files = _.sortBy(_.keys(coverageData), function(file) { return file; });
+ var allStats = [];
+ var statsByFile = {};
var htmlDirectory = config.html.directory;
var htmls = {};
for(var i = 0; i < files.length; i++) {
var filename = files[i];
htmls[filename] = cover.reporters.html.format(coverageData[filename]);
}
+ // For each file, we compile a list of its summmary stats
+ for(var i = 0; i < files.length; i++) {
+ var filename = files[i];
+ var stats = coverageData[filename].stats();
+
+ statsByFile[filename] = {
+ percentage: Math.floor(stats.percentage * 100) + "%",
+ missingLines: stats.missing,
+ seenLines: stats.seen,
+ partialLines: _.values(stats.coverage).filter(function(lineinfo) { return lineinfo.partial; }).length,
+ totalLines: stats.total,
+ blockPercentage: Math.floor(stats.blocks.percentage * 100) + "%",
+ missingBlocks: stats.blocks.missing,
+ seenBlocks: stats.blocks.seen,
+ totalBlocks: stats.blocks.total,
+ };
+
+ allStats.push([
+ filename,
+ Math.floor(stats.percentage * 100) + "%",
+ stats.missing,
+ stats.total,
+ Math.floor(stats.blocks.percentage * 100) + "%",
+ stats.blocks.missing,
+ stats.blocks.total
+ ]);
+ }
+
+ // Delete the HTML directory if necessary, and then create it
if (path.existsSync(htmlDirectory)) {
rmdirRecursiveSync(htmlDirectory);
}
-
fs.mkdirSync(htmlDirectory, "755");
+ // For each HTML file, use the template to generate an HTML file,
+ // and write it out to disk
_.each(htmls, function(html, filename) {
var outputPath = path.join(htmlDirectory, filename.replace(/\//g, "_") + ".html");
- html = "" +
- "<style>" + "\n" +
- " .covered { background: #C9F76F; }" + "\n" +
- " .uncovered { background: #FDD; }" + "\n" +
- " .partialuncovered { background: #FFA; }" + "\n" +
- "</style>" + "\n" +
- html;
+ var htmlTemplateString = fs.readFileSync("./templates/file.html").toString("utf-8");
+ var htmlTemplate = _.template(htmlTemplateString);
+ var html = htmlTemplate({
+ filename: filename,
+ code: html,
+ stats: statsByFile[filename]
+ });
fs.writeFileSync(outputPath, html);
});
- var indexHtml = "<ul>";
- for(var i = 0; i < files.length; i++) {
- var file = files[i];
- indexHtml += (" <li>" + "<a href='" + file.replace(/\//g, "_") + ".html" + "'>" + file + "</a></li>\n");
- }
- indexHtml += "</ul>";
+ // Compile the index file with the template, and write it out to disk
+ var indexTemplateString = fs.readFileSync("./templates/index.html").toString("utf-8");
+ var indexTemplate = _.template(indexTemplateString);
+ var headers = ["Filename", "% Covered", "Missed Lines", "# Lines", "% Blocks", "Missed Blocks", "# Blocks"];
+ var fileUrls = {};
+ _.each(files, function(file) {
+ fileUrls[file] = file.replace(/\//g, "_") + ".html";
+ });
+ var indexHtml = indexTemplate({ headers: headers, data: allStats, fileUrls: fileUrls });
+
fs.writeFileSync(path.join(htmlDirectory, "index.html"), indexHtml);
+
+ // Copy over the resource files
+ fs.link(path.join("resources", "bootstrap.css"), path.join(htmlDirectory, "bootstrap.css"));
+ fs.link(path.join("resources", "prettify.css"), path.join(htmlDirectory, "prettify.css"));
+ fs.link(path.join("resources", "prettify.js"), path.join(htmlDirectory, "prettify.js"));
+ fs.link(path.join("resources", "jquery.min.js"), path.join(htmlDirectory, "jquery.min.js"));
+ fs.link(path.join("resources", "jquery.tablesorter.min.js"), path.join(htmlDirectory, "jquery.tablesorter.min.js"));
},
cli: function(coverageData, config) {
View
@@ -1,60 +1,64 @@
var fs = require('fs');
+var _ = require('underscore');
-module.exports.name = "html";
-module.exports.format = function(coverageData) {
- var source = coverageData.source.split("\n");
- var stats = coverageData.stats();
- var finalOutput = [];
- var fileOutput = [];
- for(var i = 0 ; i < source.length; i++) {
- var sourceLine = source[i];
- var line = i;
- var lineOutput = [];
- if (!stats.coverage.hasOwnProperty(line + 1)) {
- lineOutput.push("<span class='covered'>");
- lineOutput.push(sourceLine);
- lineOutput.push("</span>");
- }
- else {
- var lineInfo = stats.coverage[line + 1];
- sourceLine = lineInfo.source;
-
- if (!lineInfo.partial) {
- // If it isn't partial, then we can just append the entire line
- lineOutput.push("<span class='uncovered'>");
+module.exports = {
+ name: "html",
+ format: function(coverageData) {
+ var source = coverageData.source.split("\n");
+ var stats = coverageData.stats();
+ var finalOutput = [];
+ var fileOutput = [];
+
+ for(var i = 0 ; i < source.length; i++) {
+ var sourceLine = source[i];
+ var line = i;
+ var lineOutput = [];
+ if (!stats.coverage.hasOwnProperty(line + 1)) {
+ lineOutput.push("<span class='covered'> ");
lineOutput.push(sourceLine);
lineOutput.push("</span>");
}
else {
- lineOutput.push("<span class='partial'>");
+ var lineInfo = stats.coverage[line + 1];
+ sourceLine = lineInfo.source;
- for(var j = 0; j < lineInfo.missing.length; j++) {
- curStart = j == 0 ? 0 : (lineInfo.missing[j-1].endCol + 1);
- curEnd = lineInfo.missing[j].startCol;
+ if (!lineInfo.partial) {
+ // If it isn't partial, then we can just append the entire line
+ lineOutput.push("<span class='uncovered'> ");
+ lineOutput.push(sourceLine.replace(/</g, "&lt;"));
+ lineOutput.push("</span>");
+ }
+ else {
+ lineOutput.push("<span class='partial'> ");
- lineOutput.push(sourceLine.slice(curStart, curEnd));
+ for(var j = 0; j < lineInfo.missing.length; j++) {
+ curStart = j == 0 ? 0 : (lineInfo.missing[j-1].endCol + 1);
+ curEnd = lineInfo.missing[j].startCol;
+
+ lineOutput.push(sourceLine.slice(curStart, curEnd).replace(/</g, "&lt;"));
+
+ lineOutput.push("<span class='partialuncovered'> ");
+ lineOutput.push(sourceLine.slice(lineInfo.missing[j].startCol, lineInfo.missing[j].endCol + 1).replace(/</g, "&lt;"));
+ lineOutput.push("</span>");
+ }
+
+ // Add the straggling part
+ curStart = lineInfo.missing[lineInfo.missing.length - 1].endCol + 1;
+ curEnd = sourceLine.length;
+ lineOutput.push(sourceLine.slice(curStart, curEnd).replace(/</g, "&lt;"));
- lineOutput.push("<span class='partialuncovered'>");
- lineOutput.push(sourceLine.slice(lineInfo.missing[j].startCol, lineInfo.missing[j].endCol + 1));
lineOutput.push("</span>");
}
-
- // Add the straggling part
- curStart = lineInfo.missing[lineInfo.missing.length - 1].endCol + 1;
- curEnd = sourceLine.length;
- lineOutput.push(sourceLine.slice(curStart, curEnd));
-
- lineOutput.push("</span>");
}
+ fileOutput.push(lineOutput.join(""));
}
- fileOutput.push(lineOutput.join(""));
- }
-
- finalOutput.push("<pre>");
- finalOutput.push(fileOutput.join("\n"));
- finalOutput.push("</pre>");
+
+ finalOutput.push("<pre class='prettyprint lang-js linenums'>");
+ finalOutput.push(fileOutput.join("\n"));
+ finalOutput.push("</pre>");
- var outputString = finalOutput.join("\n");
+ var outputString = finalOutput.join("\n");
- return outputString;
+ return outputString;
+ }
}
View
@@ -1,9 +1,11 @@
-
-module.exports.name = "json";
-module.exports.format = function(coverageData) {
- var source = coverageData.source;
- var stats = coverageData.stats();
- var filename = coverageData.filename;
- var result = { filename: filename, stats: stats, source: source };
- return result;
+module.exports = {
+ name: "json",
+ format: function(coverageData) {
+ var source = coverageData.source;
+ var stats = coverageData.stats();
+ var filename = coverageData.filename;
+ var result = { filename: filename, stats: stats, source: source };
+
+ return result;
+ }
}
View
@@ -7,40 +7,42 @@ function pad(text, width) {
return result + text;
}
-module.exports.name = "plain";
-module.exports.format = function(coverageData) {
- var source = coverageData.source.split('\n');
- var stats = coverageData.stats();
- var filename = coverageData.filename;
- var result = 'File: ' + filename + '\n\n';
+module.exports = {
+ name: "plain",
+ format: function(coverageData) {
+ var source = coverageData.source.split('\n');
+ var stats = coverageData.stats();
+ var filename = coverageData.filename;
+ var result = 'File: ' + filename + '\n\n';
- for(var i = 0 ; i < source.length; i++) {
- var sourceLine = source[i];
- var line = i;
- var lineOutput = [];
- if (!stats.coverage.hasOwnProperty(line + 1)) {
- // ignore covered
- }
- else {
- var lineInfo = stats.coverage[line + 1];
- sourceLine = lineInfo.source;
-
- if (!lineInfo.partial) {
- // If it isn't partial, then we can just append the entire line
- result += pad(i + 1, 5) + ' | ' + sourceLine + '\n';
+ for(var i = 0 ; i < source.length; i++) {
+ var sourceLine = source[i];
+ var line = i;
+ var lineOutput = [];
+ if (!stats.coverage.hasOwnProperty(line + 1)) {
+ // ignore covered
}
else {
- var partialLine = '';
- for(var j = 0; j < lineInfo.missing.length; j++) {
- curStart = j == 0 ? 0 : (lineInfo.missing[j-1].endCol + 1);
- curEnd = lineInfo.missing[j].startCol;
- partialLine += pad('', curEnd - curStart);
- partialLine += sourceLine.slice(lineInfo.missing[j].startCol, lineInfo.missing[j].endCol + 1);
+ var lineInfo = stats.coverage[line + 1];
+ sourceLine = lineInfo.source;
+
+ if (!lineInfo.partial) {
+ // If it isn't partial, then we can just append the entire line
+ result += pad(i + 1, 5) + ' | ' + sourceLine + '\n';
}
+ else {
+ var partialLine = '';
+ for(var j = 0; j < lineInfo.missing.length; j++) {
+ curStart = j == 0 ? 0 : (lineInfo.missing[j-1].endCol + 1);
+ curEnd = lineInfo.missing[j].startCol;
+ partialLine += pad('', curEnd - curStart);
+ partialLine += sourceLine.slice(lineInfo.missing[j].startCol, lineInfo.missing[j].endCol + 1);
+ }
- result += pad(i + 1, 5) + ' | ' + partialLine + '\n';
+ result += pad(i + 1, 5) + ' | ' + partialLine + '\n';
+ }
}
}
+ return result + '\n';
}
- return result + '\n';
}
Oops, something went wrong.

0 comments on commit cbc39f8

Please sign in to comment.